1 /** 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.telephony.imsmedia; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.fail; 21 import static org.mockito.Mockito.any; 22 import static org.mockito.Mockito.anyInt; 23 import static org.mockito.Mockito.doAnswer; 24 import static org.mockito.Mockito.doReturn; 25 import static org.mockito.Mockito.eq; 26 import static org.mockito.Mockito.times; 27 import static org.mockito.Mockito.verify; 28 29 import android.content.ComponentName; 30 import android.content.Context; 31 import android.content.Intent; 32 import android.content.ServiceConnection; 33 import android.os.IBinder; 34 import android.os.IInterface; 35 import android.os.Parcel; 36 37 import org.junit.Before; 38 import org.junit.Test; 39 import org.mockito.Mock; 40 import org.mockito.MockitoAnnotations; 41 import org.mockito.invocation.InvocationOnMock; 42 import org.mockito.stubbing.Answer; 43 44 import java.net.DatagramSocket; 45 import java.util.concurrent.Executor; 46 import java.util.concurrent.Executors; 47 48 public class ImsMediaManagerTest { 49 private Executor mExecutor; 50 private final Object mLock = new Object(); 51 52 @Mock 53 Context mMockContext; 54 @Mock 55 DatagramSocket mMockRtpSocket, mMockRtcpSocket; 56 @Mock 57 ImsMediaManager.OnConnectedCallback mMockConnectedCallback; 58 @Mock 59 RtpConfig mMockRtpConfig; 60 @Mock 61 ImsMediaSession mMockImsMediaSession; 62 @Mock 63 ImsMediaManager.SessionCallback mMockSessionCallback; 64 @Mock 65 IMediaStubTest mMockImsMedia; 66 67 @Before setUp()68 public void setUp() throws Exception { 69 mExecutor = Executors.newSingleThreadExecutor(); 70 71 MockitoAnnotations.initMocks(this); 72 doReturn(mMockImsMedia).when(mMockImsMediaSession).getBinder(); 73 doReturn(mMockImsMedia).when(mMockImsMedia).queryLocalInterface(any(String.class)); 74 doReturn(true).when(mMockImsMedia).transact(anyInt(), any(Parcel.class), any(), anyInt()); 75 76 doAnswer(new Answer<Boolean>() { 77 @Override 78 public Boolean answer(InvocationOnMock invocation) throws Throwable { 79 Object[] args = invocation.getArguments(); 80 boolean bServiceConnectionFound = false; 81 boolean bIntentFound = false; 82 for (Object arg : args) { 83 if (arg instanceof ServiceConnection) { 84 synchronized (arg) { 85 bServiceConnectionFound = true; 86 ((ServiceConnection) arg).onServiceConnected(null, 87 (IBinder) mMockImsMedia); 88 arg.notify(); 89 } 90 } else if (arg instanceof Intent) { 91 bIntentFound = true; 92 Intent intent = (Intent) arg; 93 assertEquals(intent.getAction(), IImsMedia.class.getName()); 94 assertEquals(intent.getComponent(), ComponentName.createRelative( 95 ImsMediaManager.MEDIA_SERVICE_PACKAGE, 96 ImsMediaManager.MEDIA_SERVICE_CLASS)); 97 } 98 } 99 100 assertEquals(bServiceConnectionFound, true); 101 assertEquals(bIntentFound, true); 102 return true; 103 } 104 }).when(mMockContext).bindService(any(Intent.class), any(ServiceConnection.class), 105 eq(Context.BIND_AUTO_CREATE)); 106 107 doAnswer(new Answer() { 108 @Override 109 public Object answer(InvocationOnMock invocation) throws Throwable { 110 Object[] args = invocation.getArguments(); 111 for (Object arg : args) { 112 if (arg instanceof ServiceConnection) { 113 synchronized (arg) { 114 ((ServiceConnection) arg).onServiceDisconnected(null); 115 arg.notify(); 116 } 117 } 118 } 119 return null; 120 } 121 }).when(mMockContext).unbindService(any(ServiceConnection.class)); 122 } 123 124 @Test testServiceBindingAndUnbinding()125 public void testServiceBindingAndUnbinding() { 126 ImsMediaManager imsMediaManager = 127 new ImsMediaManager(mMockContext, mExecutor, mMockConnectedCallback); 128 129 synchronized (mLock) { 130 try { 131 //Wait for connection callback 132 Thread.sleep(1000); 133 134 //Unbind from service 135 imsMediaManager.release(); 136 137 //Wait for disconnect callback 138 Thread.sleep(1000); 139 } catch (Exception e) { 140 fail(e.getMessage()); 141 } 142 } 143 144 verify(mMockConnectedCallback).onConnected(); 145 verify(mMockConnectedCallback).onDisconnected(); 146 } 147 148 @Test testOpenAndCloseSession()149 public void testOpenAndCloseSession() { 150 ImsMediaManager imsMediaManager = 151 new ImsMediaManager(mMockContext, mExecutor, mMockConnectedCallback); 152 153 synchronized (mLock) { 154 try { 155 //Wait for connection callback 156 Thread.sleep(1000); 157 158 imsMediaManager.openSession(mMockRtpSocket, mMockRtcpSocket, 159 ImsMediaSession.SESSION_TYPE_AUDIO, mMockRtpConfig, mExecutor, 160 mMockSessionCallback); 161 162 imsMediaManager.closeSession(mMockImsMediaSession); 163 164 //Unbind from service 165 imsMediaManager.release(); 166 167 //Wait for disconnect callback 168 Thread.sleep(1000); 169 170 } catch (Exception e) { 171 fail(e.getMessage()); 172 } 173 } 174 175 try { 176 verify(mMockConnectedCallback).onConnected(); 177 verify(mMockImsMedia, times(2)).transact(anyInt(), any(Parcel.class), any(), anyInt()); 178 verify(mMockConnectedCallback).onDisconnected(); 179 } catch (Exception e) { 180 fail(e.getMessage()); 181 } 182 } 183 184 public abstract static class IMediaStubBase implements IBinder { 185 } 186 187 public abstract static class IMediaStubTest extends IMediaStubBase implements IInterface { transact(int code, Parcel data, Parcel reply, int flags)188 public abstract boolean transact(int code, Parcel data, Parcel reply, int flags); 189 } 190 } 191