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.ims.cts; 18 19 import android.app.Service; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.os.Binder; 23 import android.os.IBinder; 24 import android.telephony.ims.ImsService; 25 import android.telephony.ims.feature.MmTelFeature; 26 import android.telephony.ims.feature.RcsFeature; 27 import android.telephony.ims.stub.ImsConfigImplBase; 28 import android.telephony.ims.stub.ImsFeatureConfiguration; 29 import android.telephony.ims.stub.ImsRegistrationImplBase; 30 import android.util.Log; 31 32 33 import java.util.concurrent.CountDownLatch; 34 import java.util.concurrent.TimeUnit; 35 36 /** 37 * A Test ImsService that will verify ImsService functionality. 38 */ 39 public class TestImsService extends Service { 40 41 private static final String TAG = "GtsImsTestImsService"; 42 43 private static ImsRegistrationImplBase sImsRegistrationImplBase = new ImsRegistrationImplBase(); 44 45 private TestRcsFeature mTestRcsFeature; 46 private TestMmTelFeature mTestMmTelFeature; 47 private TestImsConfig mTestImsConfig; 48 private ImsService mTestImsService; 49 private boolean mIsEnabled = false; 50 private ImsFeatureConfiguration mFeatureConfig; 51 private final Object mLock = new Object(); 52 53 public static final int LATCH_FEATURES_READY = 0; 54 public static final int LATCH_ENABLE_IMS = 1; 55 public static final int LATCH_DISABLE_IMS = 2; 56 public static final int LATCH_CREATE_MMTEL = 3; 57 public static final int LATCH_CREATE_RCS = 4; 58 public static final int LATCH_REMOVE_MMTEL = 5; 59 public static final int LATCH_REMOVE_RCS = 6; 60 public static final int LATCH_MMTEL_READY = 7; 61 public static final int LATCH_RCS_READY = 8; 62 public static final int LATCH_MMTEL_CAP_SET = 9; 63 public static final int LATCH_RCS_CAP_SET = 10; 64 private static final int LATCH_MAX = 11; 65 protected static final CountDownLatch[] sLatches = new CountDownLatch[LATCH_MAX]; 66 static { 67 for (int i = 0; i < LATCH_MAX; i++) { 68 sLatches[i] = new CountDownLatch(1); 69 } 70 } 71 72 interface RemovedListener { onRemoved()73 void onRemoved(); 74 } 75 interface ReadyListener { onReady()76 void onReady(); 77 } 78 interface CapabilitiesSetListener { onSet()79 void onSet(); 80 } 81 82 // This is defined here instead TestImsService extending ImsService directly because the GTS 83 // tests were failing to run on pre-P devices. Not sure why, but TestImsService is loaded 84 // even if it isn't used. 85 private class ImsServiceUT extends ImsService { 86 ImsServiceUT(Context context)87 ImsServiceUT(Context context) { 88 // As explained above, ImsServiceUT is created in order to get around classloader 89 // restrictions. Attach the base context from the wrapper ImsService. 90 if (getBaseContext() == null) { 91 attachBaseContext(context); 92 } 93 mTestImsConfig = new TestImsConfig(); 94 } 95 96 @Override querySupportedImsFeatures()97 public ImsFeatureConfiguration querySupportedImsFeatures() { 98 return getFeatureConfig(); 99 } 100 101 @Override readyForFeatureCreation()102 public void readyForFeatureCreation() { 103 synchronized (mLock) { 104 countDownLatch(LATCH_FEATURES_READY); 105 } 106 } 107 108 @Override enableIms(int slotId)109 public void enableIms(int slotId) { 110 synchronized (mLock) { 111 countDownLatch(LATCH_ENABLE_IMS); 112 setIsEnabled(true); 113 } 114 } 115 116 @Override disableIms(int slotId)117 public void disableIms(int slotId) { 118 synchronized (mLock) { 119 countDownLatch(LATCH_DISABLE_IMS); 120 setIsEnabled(false); 121 } 122 } 123 124 @Override createRcsFeature(int slotId)125 public RcsFeature createRcsFeature(int slotId) { 126 synchronized (mLock) { 127 countDownLatch(LATCH_CREATE_RCS); 128 mTestRcsFeature = new TestRcsFeature( 129 //onReady 130 () -> { 131 synchronized (mLock) { 132 countDownLatch(LATCH_RCS_READY); 133 } 134 }, 135 //onRemoved 136 () -> { 137 synchronized (mLock) { 138 countDownLatch(LATCH_REMOVE_RCS); 139 mTestRcsFeature = null; 140 } 141 }, 142 //onCapabilitiesSet 143 () -> { 144 synchronized (mLock) { 145 countDownLatch(LATCH_RCS_CAP_SET); 146 } 147 } 148 ); 149 return mTestRcsFeature; 150 } 151 } 152 153 @Override getConfig(int slotId)154 public ImsConfigImplBase getConfig(int slotId) { 155 return mTestImsConfig; 156 } 157 158 @Override createMmTelFeature(int slotId)159 public MmTelFeature createMmTelFeature(int slotId) { 160 synchronized (mLock) { 161 countDownLatch(LATCH_CREATE_MMTEL); 162 mTestMmTelFeature = new TestMmTelFeature( 163 //onReady 164 () -> { 165 synchronized (mLock) { 166 countDownLatch(LATCH_MMTEL_READY); 167 } 168 }, 169 //onRemoved 170 () -> { 171 synchronized (mLock) { 172 countDownLatch(LATCH_REMOVE_MMTEL); 173 mTestMmTelFeature = null; 174 } 175 }, 176 //onCapabilitiesSet 177 () -> { 178 synchronized (mLock) { 179 countDownLatch(LATCH_MMTEL_CAP_SET); 180 } 181 } 182 ); 183 return mTestMmTelFeature; 184 } 185 } 186 187 @Override getRegistration(int slotId)188 public ImsRegistrationImplBase getRegistration(int slotId) { 189 return sImsRegistrationImplBase; 190 } 191 } 192 193 private final LocalBinder mBinder = new LocalBinder(); 194 // For local access of this Service. 195 class LocalBinder extends Binder { getService()196 TestImsService getService() { 197 return TestImsService.this; 198 } 199 } 200 getImsService()201 protected ImsService getImsService() { 202 synchronized (mLock) { 203 if (mTestImsService != null) { 204 return mTestImsService; 205 } 206 mTestImsService = new ImsServiceUT(this); 207 return mTestImsService; 208 } 209 } 210 211 @Override onBind(Intent intent)212 public IBinder onBind(Intent intent) { 213 if ("android.telephony.ims.ImsService".equals(intent.getAction())) { 214 if (ImsUtils.VDBG) { 215 Log.d(TAG, "onBind-Remote"); 216 } 217 return getImsService().onBind(intent); 218 } 219 if (ImsUtils.VDBG) { 220 Log.i(TAG, "onBind-Local"); 221 } 222 return mBinder; 223 } 224 resetState()225 public void resetState() { 226 synchronized (mLock) { 227 mTestMmTelFeature = null; 228 mTestRcsFeature = null; 229 mIsEnabled = false; 230 for (int i = 0; i < LATCH_MAX; i++) { 231 sLatches[i] = new CountDownLatch(1); 232 } 233 } 234 } 235 236 // Sets the feature configuration. Make sure to call this before initiating Bind to this 237 // ImsService. setFeatureConfig(ImsFeatureConfiguration f)238 public void setFeatureConfig(ImsFeatureConfiguration f) { 239 synchronized (mLock) { 240 mFeatureConfig = f; 241 } 242 } 243 getFeatureConfig()244 public ImsFeatureConfiguration getFeatureConfig() { 245 synchronized (mLock) { 246 return mFeatureConfig; 247 } 248 } 249 isEnabled()250 public boolean isEnabled() { 251 synchronized (mLock) { 252 return mIsEnabled; 253 } 254 } 255 setIsEnabled(boolean isEnabled)256 public void setIsEnabled(boolean isEnabled) { 257 synchronized (mLock) { 258 mIsEnabled = isEnabled; 259 } 260 } 261 waitForLatchCountdown(int latchIndex)262 public boolean waitForLatchCountdown(int latchIndex) { 263 boolean complete = false; 264 try { 265 CountDownLatch latch; 266 synchronized (mLock) { 267 latch = sLatches[latchIndex]; 268 } 269 complete = latch.await(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); 270 } catch (InterruptedException e) { 271 // complete == false 272 } 273 synchronized (mLock) { 274 sLatches[latchIndex] = new CountDownLatch(1); 275 } 276 return complete; 277 } 278 countDownLatch(int latchIndex)279 public void countDownLatch(int latchIndex) { 280 synchronized (mLock) { 281 sLatches[latchIndex].countDown(); 282 } 283 } 284 getMmTelFeature()285 public TestMmTelFeature getMmTelFeature() { 286 synchronized (mLock) { 287 return mTestMmTelFeature; 288 } 289 } 290 getRcsFeature()291 public TestRcsFeature getRcsFeature() { 292 synchronized (mLock) { 293 return mTestRcsFeature; 294 } 295 } 296 getImsRegistration()297 public ImsRegistrationImplBase getImsRegistration() { 298 synchronized (mLock) { 299 return sImsRegistrationImplBase; 300 } 301 } 302 getConfig()303 public ImsConfigImplBase getConfig() { 304 return mTestImsConfig; 305 } 306 } 307