1 /* 2 * Copyright (C) 2016 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 com.android.cellbroadcastreceiver.unit; 18 19 import static org.mockito.ArgumentMatchers.any; 20 import static org.mockito.ArgumentMatchers.anyBoolean; 21 import static org.mockito.ArgumentMatchers.anyInt; 22 import static org.mockito.ArgumentMatchers.eq; 23 import static org.mockito.ArgumentMatchers.nullable; 24 import static org.mockito.Mockito.atLeastOnce; 25 import static org.mockito.Mockito.doAnswer; 26 import static org.mockito.Mockito.doReturn; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.times; 29 import static org.mockito.Mockito.verify; 30 31 import android.app.ActivityManager; 32 import android.app.ActivityOptions; 33 import android.app.ContentProviderHolder; 34 import android.app.IActivityManager; 35 import android.app.Notification; 36 import android.app.NotificationManager; 37 import android.app.PendingIntent; 38 import android.content.IContentProvider; 39 import android.content.Intent; 40 import android.content.SharedPreferences; 41 import android.content.pm.ApplicationInfo; 42 import android.content.pm.ProviderInfo; 43 import android.content.res.Configuration; 44 import android.content.res.Resources; 45 import android.os.Bundle; 46 import android.os.IBinder; 47 import android.os.IPowerManager; 48 import android.os.IThermalService; 49 import android.os.Looper; 50 import android.os.Message; 51 import android.os.PowerManager; 52 import android.os.RemoteException; 53 import android.telephony.SmsCbMessage; 54 import android.telephony.SubscriptionInfo; 55 import android.telephony.SubscriptionManager; 56 import android.text.TextUtils; 57 import android.util.Singleton; 58 import android.view.IWindowManager; 59 import android.view.KeyEvent; 60 import android.view.View; 61 import android.view.ViewGroup; 62 import android.view.WindowManager; 63 import android.view.WindowManagerGlobal; 64 import android.widget.ImageView; 65 import android.widget.LinearLayout; 66 import android.widget.TextView; 67 68 import com.android.cellbroadcastreceiver.CellBroadcastAlertDialog; 69 import com.android.cellbroadcastreceiver.CellBroadcastAlertService; 70 import com.android.cellbroadcastreceiver.CellBroadcastChannelManager; 71 import com.android.cellbroadcastreceiver.CellBroadcastReceiverApp; 72 import com.android.cellbroadcastreceiver.CellBroadcastSettings; 73 import com.android.cellbroadcastreceiver.R; 74 import com.android.internal.telephony.gsm.SmsCbConstants; 75 import com.android.modules.utils.build.SdkLevel; 76 77 import org.junit.After; 78 import org.junit.Before; 79 import org.mockito.ArgumentCaptor; 80 import org.mockito.Captor; 81 import org.mockito.Mock; 82 import org.mockito.MockitoAnnotations; 83 import org.mockito.invocation.InvocationOnMock; 84 import org.mockito.stubbing.Answer; 85 86 import java.lang.reflect.Field; 87 import java.lang.reflect.Method; 88 import java.util.ArrayList; 89 90 public class CellBroadcastAlertDialogTest extends 91 CellBroadcastActivityTestCase<CellBroadcastAlertDialog> { 92 93 @Mock 94 private NotificationManager mMockedNotificationManager; 95 96 @Mock 97 private IPowerManager.Stub mMockedPowerManagerService; 98 99 @Mock 100 private IThermalService.Stub mMockedThermalService; 101 102 @Mock 103 private IActivityManager.Stub mMockedActivityManager; 104 105 @Mock 106 IWindowManager.Stub mWindowManagerService; 107 108 @Mock 109 LinearLayout mMockLinearLayout; 110 111 @Captor 112 private ArgumentCaptor<Integer> mFlags; 113 114 @Captor 115 private ArgumentCaptor<Integer> mInt; 116 117 @Captor 118 private ArgumentCaptor<Notification> mNotification; 119 120 private PowerManager mPowerManager; 121 private int mSubId = 0; 122 CellBroadcastAlertDialogTest()123 public CellBroadcastAlertDialogTest() { 124 super(CellBroadcastAlertDialog.class); 125 } 126 127 private int mServiceCategory = SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL; 128 private int mCmasMessageClass = 0; 129 130 private ArrayList<SmsCbMessage> mMessageList; 131 132 MockedServiceManager mMockedActivityManagerHelper; 133 134 @Override createActivityIntent()135 protected Intent createActivityIntent() { 136 mMessageList = new ArrayList<>(1); 137 mMessageList.add(CellBroadcastAlertServiceTest.createMessageForCmasMessageClass(12412, 138 mServiceCategory, 139 mCmasMessageClass)); 140 141 Intent intent = new Intent(getInstrumentation().getTargetContext(), 142 CellBroadcastAlertDialog.class); 143 intent.putParcelableArrayListExtra(CellBroadcastAlertService.SMS_CB_MESSAGE_EXTRA, 144 mMessageList); 145 return intent; 146 } 147 148 @Before setUp()149 public void setUp() throws Exception { 150 super.setUp(); 151 MockitoAnnotations.initMocks(this); 152 injectSystemService(NotificationManager.class, mMockedNotificationManager); 153 // PowerManager is a final class so we can't use Mockito to mock it, but we can mock 154 // its underlying service. 155 doReturn(true).when(mMockedPowerManagerService).isInteractive(); 156 if (SdkLevel.isAtLeastU()) { 157 doReturn(true).when( 158 mMockedPowerManagerService).isDisplayInteractive(anyInt()); 159 } 160 mPowerManager = new PowerManager(mContext, mMockedPowerManagerService, 161 mMockedThermalService, null); 162 injectSystemService(PowerManager.class, mPowerManager); 163 164 SubscriptionManager mockSubManager = mock(SubscriptionManager.class); 165 injectSystemService(SubscriptionManager.class, mockSubManager); 166 SubscriptionInfo mockSubInfo = mock(SubscriptionInfo.class); 167 doReturn(mockSubInfo).when(mockSubManager).getActiveSubscriptionInfo(anyInt()); 168 169 CellBroadcastSettings.resetResourcesCache(); 170 CellBroadcastChannelManager.clearAllCellBroadcastChannelRanges(); 171 String[] values = new String[]{"0x1112-0x1112:rat=gsm, always_on=true"}; 172 doReturn(values).when(mContext.getResources()).getStringArray( 173 eq(com.android.cellbroadcastreceiver.R.array 174 .cmas_presidential_alerts_channels_range_strings)); 175 } 176 177 @After tearDown()178 public void tearDown() throws Exception { 179 CellBroadcastSettings.resetResourcesCache(); 180 CellBroadcastChannelManager.clearAllCellBroadcastChannelRanges(); 181 super.tearDown(); 182 } 183 testTitleAndMessageText()184 public void testTitleAndMessageText() throws Throwable { 185 doReturn(true).when(mContext.getResources()).getBoolean(R.bool.show_alert_title); 186 187 startActivity(); 188 waitForMs(100); 189 190 CharSequence alertString = 191 getActivity().getResources().getText(com.android.cellbroadcastreceiver.R.string 192 .cmas_presidential_level_alert); 193 assertTrue(getActivity().getTitle().toString().startsWith(alertString.toString())); 194 assertTrue(((TextView) getActivity().findViewById( 195 com.android.cellbroadcastreceiver.R.id.alertTitle)).getText().toString() 196 .startsWith(alertString.toString())); 197 198 waitUntilAssertPasses(()-> { 199 String body = CellBroadcastAlertServiceTest.createMessage(34596).getMessageBody(); 200 assertEquals(body, ((TextView) getActivity().findViewById( 201 com.android.cellbroadcastreceiver.R.id.message)).getText().toString()); 202 }, 1000); 203 204 stopActivity(); 205 } testNoTitle()206 public void testNoTitle() throws Throwable { 207 doReturn(false).when(mContext.getResources()).getBoolean(R.bool.show_alert_title); 208 startActivity(); 209 waitForMs(100); 210 assertTrue(TextUtils.isEmpty(((TextView) getActivity().findViewById( 211 com.android.cellbroadcastreceiver.R.id.alertTitle)).getText())); 212 stopActivity(); 213 } 214 waitUntilAssertPasses(Runnable r, long maxWaitMs)215 public void waitUntilAssertPasses(Runnable r, long maxWaitMs) { 216 long waitTime = 0; 217 while (waitTime < maxWaitMs) { 218 try { 219 r.run(); 220 // if the assert succeeds, return 221 return; 222 } catch (Exception e) { 223 waitTime += 100; 224 waitForMs(100); 225 } 226 } 227 // if timed out, run one last time without catching exception 228 r.run(); 229 } 230 testAddToNotification()231 public void testAddToNotification() throws Throwable { 232 setUpMockActivityManager(); 233 234 doReturn(true).when(mContext.getResources()).getBoolean(R.bool.show_alert_title); 235 doReturn(false).when(mContext.getResources()).getBoolean( 236 R.bool.disable_capture_alert_dialog); 237 238 startActivity(); 239 waitForMs(100); 240 leaveActivity(); 241 waitForMs(100); 242 verify(mMockedNotificationManager, times(1)).notify(mInt.capture(), 243 mNotification.capture()); 244 Bundle b = mNotification.getValue().extras; 245 246 assertEquals(Notification.VISIBILITY_PUBLIC, mNotification.getValue().visibility); 247 248 assertEquals(1, (int) mInt.getValue()); 249 250 assertTrue(getActivity().getTitle().toString().startsWith( 251 b.getCharSequence(Notification.EXTRA_TITLE).toString())); 252 assertEquals(CellBroadcastAlertServiceTest.createMessage(98235).getMessageBody(), 253 b.getCharSequence(Notification.EXTRA_TEXT)); 254 255 ArgumentCaptor<Bundle> bundleArgs = ArgumentCaptor.forClass(Bundle.class); 256 verify(mMockedActivityManager, times(2)) 257 .getIntentSenderWithFeature(anyInt(), any(), any(), any(), any(), anyInt(), 258 any(), any(), mFlags.capture(), bundleArgs.capture(), anyInt()); 259 260 assertTrue((PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE) 261 == mFlags.getAllValues().get(0)); 262 assertTrue((PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE) 263 == mFlags.getAllValues().get(1)); 264 265 if (SdkLevel.isAtLeastU()) { 266 ActivityOptions activityOptions = new ActivityOptions(bundleArgs.getAllValues().get(0)); 267 int startMode = activityOptions.getPendingIntentCreatorBackgroundActivityStartMode(); 268 assertEquals(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED, startMode); 269 activityOptions = new ActivityOptions(bundleArgs.getAllValues().get(1)); 270 startMode = activityOptions.getPendingIntentCreatorBackgroundActivityStartMode(); 271 assertEquals(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED, startMode); 272 } 273 274 Field field = ((Class) WindowManagerGlobal.class).getDeclaredField("sWindowManagerService"); 275 field.setAccessible(true); 276 field.set(null, null); 277 278 mMockedActivityManagerHelper.restoreAllServices(); 279 } 280 setUpMockActivityManager()281 private void setUpMockActivityManager() throws Exception { 282 ProviderInfo providerInfo = new ProviderInfo(); 283 providerInfo.authority = "test"; 284 providerInfo.applicationInfo = new ApplicationInfo(); 285 providerInfo.applicationInfo.uid = 999; 286 ContentProviderHolder holder = new ContentProviderHolder(providerInfo); 287 doReturn(holder).when(mMockedActivityManager) 288 .getContentProvider(any(), any(), any(), anyInt(), anyBoolean()); 289 holder.provider = mock(IContentProvider.class); 290 291 Singleton<IActivityManager> activityManagerSingleton = new Singleton<IActivityManager>() { 292 @Override 293 protected IActivityManager create() { 294 return mMockedActivityManager; 295 } 296 }; 297 mMockedActivityManagerHelper = new MockedServiceManager(); 298 mMockedActivityManagerHelper.replaceService("window", mWindowManagerService); 299 Field fieldHandler = ActivityManager.class.getDeclaredField("IActivityManagerSingleton"); 300 fieldHandler.setAccessible(true); 301 Singleton<IActivityManager> activityManager = 302 (Singleton<IActivityManager>) fieldHandler.get(null); 303 IActivityManager realInstance = activityManager.get(); 304 doAnswer(new Answer() { 305 public Void answer(InvocationOnMock invocation) throws RemoteException { 306 if (realInstance != null) { 307 realInstance.finishReceiver(invocation.getArgument(0), 308 invocation.getArgument(1), invocation.getArgument(2), 309 invocation.getArgument(3), invocation.getArgument(4), 310 invocation.getArgument(5)); 311 } 312 return null; 313 } 314 }).when(mMockedActivityManager).finishReceiver(nullable(IBinder.class), anyInt(), 315 nullable(String.class), nullable(Bundle.class), anyBoolean(), anyInt()); 316 mMockedActivityManagerHelper.replaceInstance(ActivityManager.class, 317 "IActivityManagerSingleton", null, activityManagerSingleton); 318 } 319 testAddToNotificationWithDifferentConfiguration()320 public void testAddToNotificationWithDifferentConfiguration() throws Throwable { 321 doReturn(false).when(mContext.getResources()).getBoolean(R.bool.show_alert_title); 322 doReturn(true).when(mContext.getResources()).getBoolean( 323 R.bool.disable_capture_alert_dialog); 324 325 startActivity(); 326 waitForMs(100); 327 leaveActivity(); 328 waitForMs(100); 329 verify(mMockedNotificationManager, times(1)).notify(mInt.capture(), 330 mNotification.capture()); 331 Bundle b = mNotification.getValue().extras; 332 333 assertEquals(Notification.VISIBILITY_PUBLIC, mNotification.getValue().visibility); 334 assertEquals(1, (int) mInt.getValue()); 335 assertTrue(TextUtils.isEmpty(b.getCharSequence(Notification.EXTRA_TITLE))); 336 verify(mContext.getResources(), times(1)).getString(mInt.capture(), anyInt()); 337 assertEquals(R.string.notification_multiple, (int) mInt.getValue()); 338 } 339 testDoNotAddToNotificationOnStop()340 public void testDoNotAddToNotificationOnStop() throws Throwable { 341 startActivity(); 342 waitForMs(100); 343 stopActivity(); 344 waitForMs(100); 345 verify(mMockedNotificationManager, times(0)).notify(mInt.capture(), 346 mNotification.capture()); 347 } 348 testDismissByDeleteIntent()349 public void testDismissByDeleteIntent() throws Throwable { 350 final Intent intent = createActivityIntent(); 351 intent.putExtra(CellBroadcastAlertService.DISMISS_DIALOG, true); 352 intent.putExtra(CellBroadcastAlertDialog.DISMISS_NOTIFICATION_EXTRA, true); 353 Looper.prepare(); 354 CellBroadcastAlertDialog activity = 355 startActivity(intent, null, null); 356 getInstrumentation().callActivityOnUserLeaving(activity); 357 verify(mMockedNotificationManager, atLeastOnce()).cancel( 358 eq(CellBroadcastAlertService.NOTIFICATION_ID)); 359 } 360 testGetNewMessageListIfNeeded()361 public void testGetNewMessageListIfNeeded() throws Throwable { 362 CellBroadcastAlertDialog activity = startActivity(); 363 Resources spyRes = mContext.getResources(); 364 doReturn(false).when(spyRes).getBoolean( 365 R.bool.show_cmas_messages_in_priority_order); 366 367 SmsCbMessage testMessage1 = CellBroadcastAlertServiceTest 368 .createMessageForCmasMessageClass(12412, 369 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL, 370 mCmasMessageClass); 371 waitForMs(10); 372 SmsCbMessage testMessage2 = CellBroadcastAlertServiceTest 373 .createMessageForCmasMessageClass(12412, 374 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY, 375 mCmasMessageClass); 376 ArrayList<SmsCbMessage> inputList1 = new ArrayList<>(); 377 ArrayList<SmsCbMessage> inputList2 = new ArrayList<>(); 378 379 inputList1.add(testMessage1); 380 ArrayList<SmsCbMessage> messageList = activity.getNewMessageListIfNeeded( 381 inputList1, inputList2); 382 assertTrue(messageList.size() == 1); 383 assertEquals(testMessage1.getReceivedTime(), messageList.get(0).getReceivedTime()); 384 385 inputList2.add(testMessage1); 386 messageList = activity.getNewMessageListIfNeeded(inputList1, inputList2); 387 assertTrue(messageList.size() == 1); 388 assertEquals(testMessage1.getReceivedTime(), messageList.get(0).getReceivedTime()); 389 390 inputList2.add(testMessage2); 391 messageList = activity.getNewMessageListIfNeeded(inputList1, inputList2); 392 assertTrue(messageList.size() == 2); 393 assertEquals(testMessage2.getReceivedTime(), messageList.get(1).getReceivedTime()); 394 395 doReturn(true).when(spyRes).getBoolean( 396 R.bool.show_cmas_messages_in_priority_order); 397 398 messageList = activity.getNewMessageListIfNeeded(inputList1, inputList2); 399 assertTrue(messageList.size() == 2); 400 assertEquals(testMessage1.getReceivedTime(), messageList.get(1).getReceivedTime()); 401 } 402 403 @InstrumentationTest 404 // This test has a module dependency (it uses the CellBroadcastContentProvider), so it is 405 // disabled for OEM testing because it is not a true unit test testDismiss()406 public void testDismiss() throws Throwable { 407 CellBroadcastAlertDialog activity = startActivity(); 408 waitForMs(100); 409 activity.dismiss(); 410 411 verify(mMockedNotificationManager, times(1)).cancel( 412 eq(CellBroadcastAlertService.NOTIFICATION_ID)); 413 } 414 testOnNewIntent()415 public void testOnNewIntent() throws Throwable { 416 Intent intent = createActivityIntent(); 417 intent.putExtra(CellBroadcastAlertDialog.DISMISS_NOTIFICATION_EXTRA, true); 418 419 Looper.prepare(); 420 CellBroadcastAlertDialog activity = startActivity(intent, null, null); 421 waitForMs(100); 422 423 ImageView image = activity.findViewById(R.id.pictogramImage); 424 image.setVisibility(View.VISIBLE); 425 assertEquals(View.VISIBLE, image.getVisibility()); 426 427 // add more messages to list 428 mMessageList.add(CellBroadcastAlertServiceTest.createMessageForCmasMessageClass(12413, 429 SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_WARNING, 430 SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_WARNING)); 431 intent.putParcelableArrayListExtra(CellBroadcastAlertService.SMS_CB_MESSAGE_EXTRA, 432 new ArrayList<>(mMessageList)); 433 activity.onNewIntent(intent); 434 435 verify(mMockedNotificationManager, atLeastOnce()).cancel( 436 eq(CellBroadcastAlertService.NOTIFICATION_ID)); 437 assertNotNull(image.getLayoutParams()); 438 } 439 testAnimationHandler()440 public void testAnimationHandler() throws Throwable { 441 CellBroadcastAlertDialog activity = startActivity(); 442 443 activity.mAnimationHandler.startIconAnimation(mSubId); 444 445 assertTrue(activity.mAnimationHandler.mWarningIconVisible); 446 447 Message m = Message.obtain(); 448 m.what = activity.mAnimationHandler.mCount.get(); 449 activity.mAnimationHandler.handleMessage(m); 450 451 // assert that message count has gone up 452 assertEquals(m.what + 1, activity.mAnimationHandler.mCount.get()); 453 } 454 testOnResume()455 public void testOnResume() throws Throwable { 456 Intent intent = createActivityIntent(); 457 intent.putExtra(CellBroadcastAlertDialog.DISMISS_NOTIFICATION_EXTRA, true); 458 459 Looper.prepare(); 460 CellBroadcastAlertDialog activity = startActivity(intent, null, null); 461 462 CellBroadcastAlertDialog.AnimationHandler mockAnimationHandler = mock( 463 CellBroadcastAlertDialog.AnimationHandler.class); 464 activity.mAnimationHandler = mockAnimationHandler; 465 466 activity.onResume(); 467 verify(mockAnimationHandler).startIconAnimation(anyInt()); 468 } 469 testOnPause()470 public void testOnPause() throws Throwable { 471 Intent intent = createActivityIntent(); 472 intent.putExtra(CellBroadcastAlertDialog.DISMISS_NOTIFICATION_EXTRA, true); 473 474 Looper.prepare(); 475 CellBroadcastAlertDialog activity = startActivity(intent, null, null); 476 477 CellBroadcastAlertDialog.AnimationHandler mockAnimationHandler = mock( 478 CellBroadcastAlertDialog.AnimationHandler.class); 479 activity.mAnimationHandler = mockAnimationHandler; 480 481 activity.onPause(); 482 verify(mockAnimationHandler).stopIconAnimation(); 483 } 484 testOnKeyDown()485 public void testOnKeyDown() throws Throwable { 486 Intent intent = createActivityIntent(); 487 intent.putExtra(CellBroadcastAlertDialog.DISMISS_NOTIFICATION_EXTRA, true); 488 489 Looper.prepare(); 490 CellBroadcastAlertDialog activity = startActivity(intent, null, null); 491 492 assertTrue(activity.onKeyDown(0, 493 new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_FOCUS))); 494 } 495 testOnConfigurationChanged()496 public void testOnConfigurationChanged() throws Throwable { 497 CellBroadcastAlertDialog activity = startActivity(); 498 Configuration newConfig = new Configuration(); 499 500 ImageView image = activity.findViewById(R.id.pictogramImage); 501 image.setVisibility(View.VISIBLE); 502 assertEquals(View.VISIBLE, image.getVisibility()); 503 504 newConfig.orientation = Configuration.ORIENTATION_LANDSCAPE; 505 activity.onConfigurationChanged(newConfig); 506 assertNotNull(image.getLayoutParams()); 507 508 newConfig.orientation = Configuration.ORIENTATION_PORTRAIT; 509 activity.onConfigurationChanged(newConfig); 510 assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, image.getLayoutParams().height); 511 assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, image.getLayoutParams().width); 512 } 513 testOnWindowFocusChanged()514 public void testOnWindowFocusChanged() throws Throwable { 515 CellBroadcastAlertDialog activity = startActivity(); 516 517 ImageView image = activity.findViewById(R.id.pictogramImage); 518 image.setVisibility(View.VISIBLE); 519 assertEquals(View.VISIBLE, image.getVisibility()); 520 521 activity.onWindowFocusChanged(true); 522 assertNotNull(image.getLayoutParams()); 523 } 524 testOnKeyDownWithEmptyMessageList()525 public void testOnKeyDownWithEmptyMessageList() throws Throwable { 526 mMessageList = new ArrayList<>(1); 527 528 Intent intent = new Intent(getInstrumentation().getTargetContext(), 529 CellBroadcastAlertDialog.class); 530 intent.putParcelableArrayListExtra(CellBroadcastAlertService.SMS_CB_MESSAGE_EXTRA, 531 mMessageList); 532 intent.putExtra(CellBroadcastAlertDialog.DISMISS_NOTIFICATION_EXTRA, true); 533 Looper.prepare(); 534 CellBroadcastAlertDialog activity = startActivity(intent, null, null); 535 536 assertTrue(activity.onKeyDown(0, 537 new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_FOCUS))); 538 } 539 testPulsationHandlerStart()540 public void testPulsationHandlerStart() throws Throwable { 541 int[] pattern = new int[] {0xFFFF0000, 100000, 500, 1000}; 542 doReturn(pattern).when(mContext.getResources()).getIntArray( 543 eq(com.android.cellbroadcastreceiver.R.array.default_pulsation_pattern)); 544 545 CellBroadcastChannelManager.clearAllCellBroadcastChannelRanges(); 546 CellBroadcastAlertDialog activity = startActivity(); 547 waitForMs(100); 548 activity.mPulsationHandler.mLayout = mMockLinearLayout; 549 550 assertEquals(0xFFFF0000, activity.mPulsationHandler.mHighlightColor); 551 assertEquals(100000, activity.mPulsationHandler.mDuration); 552 assertEquals(500, activity.mPulsationHandler.mOnInterval); 553 assertEquals(1000, activity.mPulsationHandler.mOffInterval); 554 555 waitForMs(2000); 556 557 verify(mMockLinearLayout, atLeastOnce()).setBackgroundColor(eq(0xFFFF0000)); 558 } 559 testPulsationRestartOnNewIntent()560 public void testPulsationRestartOnNewIntent() throws Throwable { 561 int[] pattern = new int[] {0xFFFF0000, 100000, 500, 1000}; 562 doReturn(pattern).when(mContext.getResources()).getIntArray( 563 eq(com.android.cellbroadcastreceiver.R.array.default_pulsation_pattern)); 564 565 CellBroadcastAlertDialog activity = startActivity(); 566 waitForMs(100); 567 activity.mPulsationHandler.mLayout = mMockLinearLayout; 568 569 assertEquals(0xFFFF0000, activity.mPulsationHandler.mHighlightColor); 570 assertEquals(100000, activity.mPulsationHandler.mDuration); 571 assertEquals(500, activity.mPulsationHandler.mOnInterval); 572 assertEquals(1000, activity.mPulsationHandler.mOffInterval); 573 574 pattern = new int[] {0xFFFFFFFF, 200000, 1000, 500}; 575 doReturn(pattern).when(mContext.getResources()).getIntArray( 576 eq(com.android.cellbroadcastreceiver.R.array.default_pulsation_pattern)); 577 mMessageList.add(CellBroadcastAlertServiceTest.createMessageForCmasMessageClass(12413, 578 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY, 579 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY)); 580 Intent intent = createActivityIntent(); 581 intent.putParcelableArrayListExtra(CellBroadcastAlertService.SMS_CB_MESSAGE_EXTRA, 582 new ArrayList<>(mMessageList)); 583 CellBroadcastSettings.resetResourcesCache(); 584 CellBroadcastChannelManager.clearAllCellBroadcastChannelRanges(); 585 activity.onNewIntent(intent); 586 waitForMs(100); 587 588 // Verify existing pulsation has been stopped 589 verify(mMockLinearLayout, times(1)).setBackgroundColor( 590 eq(activity.mPulsationHandler.mBackgroundColor)); 591 592 activity.mPulsationHandler.mLayout = mMockLinearLayout; 593 594 // Verify new parameters have been applied 595 assertEquals(0xFFFFFFFF, activity.mPulsationHandler.mHighlightColor); 596 assertEquals(200000, activity.mPulsationHandler.mDuration); 597 assertEquals(1000, activity.mPulsationHandler.mOnInterval); 598 assertEquals(500, activity.mPulsationHandler.mOffInterval); 599 600 waitForMs(2000); 601 602 // Verify new pulsation takes effect 603 verify(mMockLinearLayout, atLeastOnce()).setBackgroundColor(eq(0xFFFFFFFF)); 604 } 605 testPulsationHandlerHandleMessageAndStop()606 public void testPulsationHandlerHandleMessageAndStop() throws Throwable { 607 CellBroadcastAlertDialog activity = startActivity(); 608 waitForMs(100); 609 610 int backgroundColor = activity.mPulsationHandler.mBackgroundColor; 611 activity.mPulsationHandler.mHighlightColor = 0xFFFF0000; 612 activity.mPulsationHandler.mLayout = mMockLinearLayout; 613 activity.mPulsationHandler.mOnInterval = 60000; 614 activity.mPulsationHandler.mOffInterval = 60000; 615 activity.mPulsationHandler.mDuration = 300000; 616 617 Message m = Message.obtain(); 618 m.what = activity.mPulsationHandler.mCount.get(); 619 activity.mPulsationHandler.handleMessage(m); 620 621 // assert that message count has gone up, and the background color is highlighted 622 assertEquals(m.what + 1, activity.mPulsationHandler.mCount.get()); 623 assertTrue(activity.mPulsationHandler.mIsPulsationOn); 624 verify(mMockLinearLayout, times(1)).setBackgroundColor(eq(0xFFFF0000)); 625 626 m = Message.obtain(); 627 m.what = activity.mPulsationHandler.mCount.get(); 628 activity.mPulsationHandler.handleMessage(m); 629 630 // assert that message count has gone up, and the background color is restored 631 assertEquals(m.what + 1, activity.mPulsationHandler.mCount.get()); 632 assertFalse(activity.mPulsationHandler.mIsPulsationOn); 633 verify(mMockLinearLayout, times(1)).setBackgroundColor(eq(backgroundColor)); 634 635 m = Message.obtain(); 636 m.what = activity.mPulsationHandler.mCount.get(); 637 activity.mPulsationHandler.handleMessage(m); 638 639 // assert that the background color is highlighted again 640 assertEquals(m.what + 1, activity.mPulsationHandler.mCount.get()); 641 assertTrue(activity.mPulsationHandler.mIsPulsationOn); 642 verify(mMockLinearLayout, times(2)).setBackgroundColor(eq(0xFFFF0000)); 643 644 activity.mPulsationHandler.stop(); 645 waitForMs(100); 646 647 // assert that the background color is restored 648 assertEquals(m.what + 2, activity.mPulsationHandler.mCount.get()); 649 assertFalse(activity.mPulsationHandler.mIsPulsationOn); 650 verify(mMockLinearLayout, times(2)).setBackgroundColor(eq(backgroundColor)); 651 } 652 getNewMessageList()653 private ArrayList<SmsCbMessage> getNewMessageList() throws Exception { 654 Method method = CellBroadcastReceiverApp.class.getDeclaredMethod("getNewMessageList"); 655 method.setAccessible(true); 656 return (ArrayList<SmsCbMessage>) method.invoke(null); 657 } 658 addNewMessageToList(SmsCbMessage message)659 private ArrayList<SmsCbMessage> addNewMessageToList(SmsCbMessage message) { 660 Class[] args = new Class[1]; 661 args[0] = SmsCbMessage.class; 662 try { 663 Method method = CellBroadcastReceiverApp.class.getDeclaredMethod( 664 "addNewMessageToList", args); 665 method.setAccessible(true); 666 return (ArrayList<SmsCbMessage>) method.invoke(null, message); 667 } catch (Exception e) { 668 return null; 669 } 670 } 671 testNewMessageListCount()672 public void testNewMessageListCount() throws Throwable { 673 SmsCbMessage testMessage1 = CellBroadcastAlertServiceTest 674 .createMessageForCmasMessageClass(75103, 675 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL, 676 mCmasMessageClass); 677 SmsCbMessage testMessage2 = CellBroadcastAlertServiceTest 678 .createMessageForCmasMessageClass(51030, 679 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY, 680 mCmasMessageClass); 681 SmsCbMessage testMessage3 = CellBroadcastAlertServiceTest 682 .createMessageForCmasMessageClass(10307, 683 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY, 684 mCmasMessageClass); 685 686 // touch a notification for on-going message 687 Intent intent1 = createActivityIntent(); 688 intent1.putExtra(CellBroadcastAlertService.DISMISS_DIALOG, false); 689 intent1.putExtra(CellBroadcastAlertDialog.DISMISS_NOTIFICATION_EXTRA, false); 690 addNewMessageToList(testMessage1); 691 Looper.prepare(); 692 CellBroadcastAlertDialog activity = startActivity(intent1, null, null); 693 waitForMs(100); 694 695 assertEquals(1, getNewMessageList().size()); 696 697 // touch a notification for pending message 698 Intent intent2 = createActivityIntent(); 699 intent2.putExtra(CellBroadcastAlertService.DISMISS_DIALOG, false); 700 intent2.putExtra(CellBroadcastAlertDialog.DISMISS_NOTIFICATION_EXTRA, true); 701 addNewMessageToList(testMessage2); 702 activity.onNewIntent(intent2); 703 704 assertEquals(2, getNewMessageList().size()); 705 706 // swipe a notification for pending message 707 Intent intent3 = createActivityIntent(); 708 intent3.putExtra(CellBroadcastAlertService.DISMISS_DIALOG, true); 709 intent3.putExtra(CellBroadcastAlertDialog.DISMISS_NOTIFICATION_EXTRA, true); 710 addNewMessageToList(testMessage3); 711 activity.onNewIntent(intent3); 712 713 assertEquals(getNewMessageList().size(), 0); 714 715 // swipe a notification for on-going message 716 Intent intent4 = createActivityIntent(); 717 intent4.putExtra(CellBroadcastAlertService.DISMISS_DIALOG, true); 718 intent4.putExtra(CellBroadcastAlertDialog.DISMISS_NOTIFICATION_EXTRA, false); 719 addNewMessageToList(testMessage1); 720 activity.onNewIntent(intent4); 721 722 assertEquals(getNewMessageList().size(), 1); 723 } 724 setWatchUiMode()725 private void setWatchUiMode() { 726 Configuration configuration = new Configuration( 727 mContext.getResources().getConfiguration()); 728 configuration.uiMode = 729 (configuration.uiMode & ~Configuration.UI_MODE_TYPE_MASK) 730 | Configuration.UI_MODE_TYPE_WATCH; 731 mContext.enableOverrideConfiguration(true); 732 mContext = (TestContext) mContext.createConfigurationContext(configuration); 733 setActivityContext(mContext); 734 } 735 testOnConfigurationChangedForWatch()736 public void testOnConfigurationChangedForWatch() throws Throwable { 737 setWatchUiMode(); 738 CellBroadcastAlertDialog activity = startActivity(); 739 740 Configuration newConfig = new Configuration(); 741 newConfig.orientation = Configuration.ORIENTATION_LANDSCAPE; 742 activity.onConfigurationChanged(newConfig); 743 744 newConfig.orientation = Configuration.ORIENTATION_PORTRAIT; 745 activity.onConfigurationChanged(newConfig); 746 747 assertNull(activity.findViewById(R.id.pictogramImage)); 748 } 749 testOnCreate()750 public void testOnCreate() throws Throwable { 751 doReturn(false).when(mContext.getResources()).getBoolean( 752 R.bool.disable_capture_alert_dialog); 753 CellBroadcastAlertDialog activity = startActivity(); 754 int flags = activity.getWindow().getAttributes().flags; 755 assertEquals((flags & WindowManager.LayoutParams.FLAG_SECURE), 0); 756 stopActivity(); 757 } 758 testOnCreateWithCaptureRestriction()759 public void testOnCreateWithCaptureRestriction() throws Throwable { 760 doReturn(true).when(mContext.getResources()).getBoolean( 761 R.bool.disable_capture_alert_dialog); 762 CellBroadcastAlertDialog activity = startActivity(); 763 int flags = activity.getWindow().getAttributes().flags; 764 assertEquals((flags & WindowManager.LayoutParams.FLAG_SECURE), 765 WindowManager.LayoutParams.FLAG_SECURE); 766 stopActivity(); 767 } 768 testTitleOnNonDefaultSubId()769 public void testTitleOnNonDefaultSubId() throws Throwable { 770 Intent intent = createActivityIntent(); 771 Looper.prepare(); 772 CellBroadcastAlertDialog activity = startActivity(intent, null, null); 773 waitForMs(100); 774 775 assertFalse(TextUtils.isEmpty(((TextView) getActivity().findViewById( 776 com.android.cellbroadcastreceiver.R.id.alertTitle)).getText())); 777 778 SharedPreferences mockSharedPreferences = mock(SharedPreferences.class); 779 doReturn("334090").when(mockSharedPreferences).getString(any(), any()); 780 mContext.injectSharedPreferences(mockSharedPreferences); 781 Resources mockResources2 = mock(Resources.class); 782 doReturn(false).when(mockResources2).getBoolean(R.bool.show_alert_title); 783 doReturn("none").when(mockResources2).getString(R.string.link_method); 784 785 CellBroadcastSettings.sResourcesCacheByOperator.put("334090", mockResources2); 786 787 mMessageList.add(CellBroadcastAlertServiceTest.createMessageForCmasMessageClass(12413, 788 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY, 789 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY)); 790 intent.putParcelableArrayListExtra(CellBroadcastAlertService.SMS_CB_MESSAGE_EXTRA, 791 new ArrayList<>(mMessageList)); 792 activity.onNewIntent(intent); 793 794 assertTrue(TextUtils.isEmpty(((TextView) getActivity().findViewById( 795 com.android.cellbroadcastreceiver.R.id.alertTitle)).getText())); 796 } 797 } 798