1 /* 2 * Copyright (C) 2019 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.embms.cts; 18 19 import static androidx.test.InstrumentationRegistry.getContext; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertNotNull; 23 import static org.junit.Assert.assertTrue; 24 import static org.junit.Assert.fail; 25 26 import android.annotation.Nullable; 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.ServiceConnection; 31 import android.os.Handler; 32 import android.os.HandlerThread; 33 import android.os.IBinder; 34 import android.os.RemoteException; 35 import android.telephony.MbmsGroupCallSession; 36 import android.telephony.cts.embmstestapp.CtsGroupCallService; 37 import android.telephony.cts.embmstestapp.ICtsGroupCallMiddlewareControl; 38 import android.telephony.mbms.MbmsGroupCallSessionCallback; 39 40 import java.util.List; 41 import java.util.concurrent.BlockingQueue; 42 import java.util.concurrent.CountDownLatch; 43 import java.util.concurrent.Executor; 44 import java.util.concurrent.LinkedBlockingQueue; 45 import java.util.concurrent.TimeUnit; 46 import java.util.stream.Collectors; 47 import org.junit.After; 48 import org.junit.Before; 49 50 public class MbmsGroupCallTestBase { 51 protected static final int ASYNC_TIMEOUT = 10000; 52 53 protected static class TestCallback implements MbmsGroupCallSessionCallback { 54 private final BlockingQueue<SomeArgs> mErrorCalls = new LinkedBlockingQueue<>(); 55 private final BlockingQueue<SomeArgs> mOnAvailableSaisUpdatedCalls = 56 new LinkedBlockingQueue<>(); 57 private final BlockingQueue<SomeArgs> mOnServiceInterfaceAvailableCalls = 58 new LinkedBlockingQueue<>(); 59 private final BlockingQueue<SomeArgs> mMiddlewareReadyCalls = new LinkedBlockingQueue<>(); 60 private int mNumErrorCalls = 0; 61 62 @Override 63 public void onError(int errorCode, @Nullable String message) { 64 MbmsGroupCallSessionCallback.super.onError(errorCode, message); 65 mNumErrorCalls += 1; 66 SomeArgs args = SomeArgs.obtain(); 67 args.arg1 = errorCode; 68 args.arg2 = message; 69 mErrorCalls.add(args); 70 } 71 72 @Override 73 public void onMiddlewareReady() { 74 MbmsGroupCallSessionCallback.super.onMiddlewareReady(); 75 mMiddlewareReadyCalls.add(SomeArgs.obtain()); 76 } 77 78 @Override 79 public void onAvailableSaisUpdated(List<Integer> currentSais, 80 List<List<Integer>> availableSais) { 81 MbmsGroupCallSessionCallback.super.onAvailableSaisUpdated(currentSais, availableSais); 82 SomeArgs args = SomeArgs.obtain(); 83 args.arg1 = currentSais; 84 args.arg2 = availableSais; 85 mOnAvailableSaisUpdatedCalls.add(args); 86 } 87 88 @Override 89 public void onServiceInterfaceAvailable(String interfaceName, int index) { 90 MbmsGroupCallSessionCallback.super.onServiceInterfaceAvailable(interfaceName, index); 91 SomeArgs args = SomeArgs.obtain(); 92 args.arg1 = interfaceName; 93 args.arg2 = index; 94 mOnServiceInterfaceAvailableCalls.add(args); 95 } 96 97 public SomeArgs waitOnError() { 98 try { 99 return mErrorCalls.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 100 } catch (InterruptedException e) { 101 return null; 102 } 103 } 104 105 public SomeArgs waitOnAvailableSaisUpdatedCalls() { 106 try { 107 return mOnAvailableSaisUpdatedCalls.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 108 } catch (InterruptedException e) { 109 return null; 110 } 111 } 112 113 public SomeArgs waitOnServiceInterfaceAvailableCalls() { 114 try { 115 return mOnServiceInterfaceAvailableCalls.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 116 } catch (InterruptedException e) { 117 return null; 118 } 119 } 120 121 public boolean waitOnMiddlewareReady() { 122 try { 123 return mMiddlewareReadyCalls.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS) != null; 124 } catch (InterruptedException e) { 125 return false; 126 } 127 } 128 129 public int getNumErrorCalls() { 130 return mNumErrorCalls; 131 } 132 } 133 134 Context mContext; 135 HandlerThread mHandlerThread; 136 Executor mCallbackExecutor; 137 ICtsGroupCallMiddlewareControl mMiddlewareControl; 138 MbmsGroupCallSession mGroupCallSession; 139 TestCallback mCallback = new TestCallback(); 140 141 @Before 142 public void setUp() throws Exception { 143 mContext = getContext(); 144 mHandlerThread = new HandlerThread("EmbmsCtsTestWorker"); 145 mHandlerThread.start(); 146 mCallbackExecutor = (new Handler(mHandlerThread.getLooper()))::post; 147 mCallback = new TestCallback(); 148 getControlBinder(); 149 setupGroupCallSession(); 150 } 151 152 @After 153 public void tearDown() throws Exception { 154 mHandlerThread.quit(); 155 mGroupCallSession.close(); 156 mMiddlewareControl.reset(); 157 } 158 159 private void setupGroupCallSession() throws Exception { 160 mGroupCallSession = MbmsGroupCallSession.create( 161 mContext, mCallbackExecutor, mCallback); 162 assertNotNull(mGroupCallSession); 163 assertTrue(mCallback.waitOnMiddlewareReady()); 164 assertEquals(0, mCallback.getNumErrorCalls()); 165 List initializeCall = (List) mMiddlewareControl.getGroupCallSessionCalls().get(0); 166 assertEquals(CtsGroupCallService.METHOD_INITIALIZE, initializeCall.get(0)); 167 } 168 169 private void getControlBinder() throws InterruptedException { 170 Intent bindIntent = new Intent(CtsGroupCallService.CONTROL_INTERFACE_ACTION); 171 bindIntent.setComponent(CtsGroupCallService.CONTROL_INTERFACE_COMPONENT); 172 final CountDownLatch bindLatch = new CountDownLatch(1); 173 174 boolean success = mContext.bindService(bindIntent, new ServiceConnection() { 175 @Override 176 public void onServiceConnected(ComponentName name, IBinder service) { 177 mMiddlewareControl = ICtsGroupCallMiddlewareControl.Stub.asInterface(service); 178 bindLatch.countDown(); 179 } 180 181 @Override 182 public void onServiceDisconnected(ComponentName name) { 183 mMiddlewareControl = null; 184 } 185 }, Context.BIND_AUTO_CREATE); 186 if (!success) { 187 fail("Failed to get control interface -- bind error"); 188 } 189 bindLatch.await(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS); 190 } 191 192 protected List<List<Object>> getMiddlewareCalls(String methodName) throws RemoteException { 193 return ((List<List<Object>>) mMiddlewareControl.getGroupCallSessionCalls()).stream() 194 .filter((elem) -> elem.get(0).equals(methodName)) 195 .collect(Collectors.toList()); 196 } 197 }