1 /* 2 * Copyright (C) 2017 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.internal.app; 18 19 import static junit.framework.Assert.assertEquals; 20 import static junit.framework.Assert.assertNotNull; 21 import static junit.framework.Assert.assertNull; 22 23 import static org.mockito.ArgumentMatchers.any; 24 import static org.mockito.ArgumentMatchers.anyInt; 25 import static org.mockito.ArgumentMatchers.anyString; 26 import static org.mockito.ArgumentMatchers.eq; 27 import static org.mockito.ArgumentMatchers.nullable; 28 import static org.mockito.Mockito.mock; 29 import static org.mockito.Mockito.never; 30 import static org.mockito.Mockito.spy; 31 import static org.mockito.Mockito.verify; 32 import static org.mockito.Mockito.when; 33 34 import android.annotation.Nullable; 35 import android.content.ComponentName; 36 import android.content.Context; 37 import android.content.Intent; 38 import android.content.pm.ActivityInfo; 39 import android.content.pm.ApplicationInfo; 40 import android.content.pm.IPackageManager; 41 import android.content.pm.PackageManager; 42 import android.content.pm.ResolveInfo; 43 import android.content.pm.UserInfo; 44 import android.metrics.LogMaker; 45 import android.net.Uri; 46 import android.os.Bundle; 47 import android.os.IBinder; 48 import android.os.RemoteException; 49 import android.os.UserHandle; 50 import android.os.UserManager; 51 import android.provider.Settings; 52 53 import androidx.test.InstrumentationRegistry; 54 import androidx.test.rule.ActivityTestRule; 55 import androidx.test.runner.AndroidJUnit4; 56 57 import com.android.internal.logging.MetricsLogger; 58 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 59 60 import org.junit.After; 61 import org.junit.Before; 62 import org.junit.Rule; 63 import org.junit.Test; 64 import org.junit.runner.RunWith; 65 import org.mockito.ArgumentCaptor; 66 import org.mockito.Mock; 67 import org.mockito.MockitoAnnotations; 68 69 import java.util.ArrayList; 70 import java.util.List; 71 import java.util.concurrent.CompletableFuture; 72 import java.util.concurrent.TimeUnit; 73 74 @RunWith(AndroidJUnit4.class) 75 public class IntentForwarderActivityTest { 76 77 private static final ComponentName FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME = 78 new ComponentName( 79 "android", 80 IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE 81 ); 82 private static final ComponentName FORWARD_TO_PARENT_COMPONENT_NAME = 83 new ComponentName( 84 "android", 85 IntentForwarderActivity.FORWARD_INTENT_TO_PARENT 86 ); 87 private static final String TYPE_PLAIN_TEXT = "text/plain"; 88 89 private static UserInfo MANAGED_PROFILE_INFO = new UserInfo(); 90 91 static { 92 MANAGED_PROFILE_INFO.id = 10; 93 MANAGED_PROFILE_INFO.flags = UserInfo.FLAG_MANAGED_PROFILE; 94 MANAGED_PROFILE_INFO.userType = UserManager.USER_TYPE_PROFILE_MANAGED; 95 } 96 97 private static UserInfo CURRENT_USER_INFO = new UserInfo(); 98 99 static { 100 CURRENT_USER_INFO.id = UserHandle.myUserId(); 101 CURRENT_USER_INFO.flags = 0; 102 } 103 104 private static IntentForwarderActivity.Injector sInjector; 105 private static ComponentName sComponentName; 106 private static String sActivityName; 107 private static String sPackageName; 108 109 @Mock 110 private IPackageManager mIPm; 111 @Mock 112 private PackageManager mPm; 113 @Mock 114 private UserManager mUserManager; 115 @Mock 116 private ApplicationInfo mApplicationInfo; 117 118 @Rule 119 public ActivityTestRule<IntentForwarderWrapperActivity> mActivityRule = 120 new ActivityTestRule<>(IntentForwarderWrapperActivity.class, true, false); 121 122 private Context mContext; 123 public static final String PHONE_NUMBER = "123-456-789"; 124 private int mDeviceProvisionedInitialValue; 125 126 @Before setup()127 public void setup() { 128 MockitoAnnotations.initMocks(this); 129 mContext = InstrumentationRegistry.getTargetContext(); 130 sInjector = spy(new TestInjector()); 131 mDeviceProvisionedInitialValue = Settings.Global.getInt(mContext.getContentResolver(), 132 Settings.Global.DEVICE_PROVISIONED, /* def= */ 0); 133 } 134 135 @After tearDown()136 public void tearDown() { 137 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 138 mDeviceProvisionedInitialValue); 139 } 140 141 @Test forwardToManagedProfile_canForward_sendIntent()142 public void forwardToManagedProfile_canForward_sendIntent() throws Exception { 143 sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME; 144 145 // Intent can be forwarded. 146 when(mIPm.canForwardTo( 147 any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true); 148 149 // Managed profile exists. 150 List<UserInfo> profiles = new ArrayList<>(); 151 profiles.add(CURRENT_USER_INFO); 152 profiles.add(MANAGED_PROFILE_INFO); 153 when(mUserManager.getProfiles(anyInt())).thenReturn(profiles); 154 155 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class); 156 intent.setAction(Intent.ACTION_SEND); 157 intent.setType(TYPE_PLAIN_TEXT); 158 IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent); 159 160 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 161 verify(mIPm).canForwardTo(intentCaptor.capture(), eq(TYPE_PLAIN_TEXT), anyInt(), anyInt()); 162 assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction()); 163 164 assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction()); 165 assertNotNull(activity.mStartActivityIntent); 166 assertEquals(Intent.ACTION_SEND, activity.mStartActivityIntent.getAction()); 167 assertNull(activity.mStartActivityIntent.getPackage()); 168 assertNull(activity.mStartActivityIntent.getComponent()); 169 assertEquals(CURRENT_USER_INFO.id, activity.mStartActivityIntent.getContentUserHint()); 170 171 assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn); 172 } 173 174 @Test forwardToManagedProfile_cannotForward_sendIntent()175 public void forwardToManagedProfile_cannotForward_sendIntent() throws Exception { 176 sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME; 177 178 // Intent cannot be forwarded. 179 when(mIPm.canForwardTo( 180 any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(false); 181 182 // Managed profile exists. 183 List<UserInfo> profiles = new ArrayList<>(); 184 profiles.add(CURRENT_USER_INFO); 185 profiles.add(MANAGED_PROFILE_INFO); 186 when(mUserManager.getProfiles(anyInt())).thenReturn(profiles); 187 188 // Create ACTION_SEND intent. 189 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class); 190 intent.setAction(Intent.ACTION_SEND); 191 IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent); 192 193 assertNull(activity.mStartActivityIntent); 194 } 195 196 @Test forwardToManagedProfile_noManagedProfile_sendIntent()197 public void forwardToManagedProfile_noManagedProfile_sendIntent() throws Exception { 198 sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME; 199 200 // Intent can be forwarded. 201 when(mIPm.canForwardTo( 202 any(Intent.class), anyString(), anyInt(), anyInt())).thenReturn(true); 203 204 // Managed profile does not exist. 205 List<UserInfo> profiles = new ArrayList<>(); 206 profiles.add(CURRENT_USER_INFO); 207 when(mUserManager.getProfiles(anyInt())).thenReturn(profiles); 208 209 // Create ACTION_SEND intent. 210 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class); 211 intent.setAction(Intent.ACTION_SEND); 212 IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent); 213 214 assertNull(activity.mStartActivityIntent); 215 } 216 217 @Test launchInSameProfile_chooserIntent()218 public void launchInSameProfile_chooserIntent() { 219 sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME; 220 221 // Manage profile exists. 222 List<UserInfo> profiles = new ArrayList<>(); 223 profiles.add(CURRENT_USER_INFO); 224 profiles.add(MANAGED_PROFILE_INFO); 225 when(mUserManager.getProfiles(anyInt())).thenReturn(profiles); 226 227 // Create chooser Intent 228 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class); 229 intent.setAction(Intent.ACTION_CHOOSER); 230 Intent sendIntent = new Intent(Intent.ACTION_SEND); 231 sendIntent.setComponent(new ComponentName("xx", "yyy")); 232 sendIntent.setType(TYPE_PLAIN_TEXT); 233 intent.putExtra(Intent.EXTRA_INTENT, sendIntent); 234 IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent); 235 236 assertNotNull(activity.mStartActivityIntent); 237 assertEquals(Intent.ACTION_CHOOSER, activity.mStartActivityIntent.getAction()); 238 assertNull(activity.mStartActivityIntent.getPackage()); 239 assertNull(activity.mStartActivityIntent.getComponent()); 240 241 Intent innerIntent = activity.mStartActivityIntent.getParcelableExtra(Intent.EXTRA_INTENT); 242 assertNotNull(innerIntent); 243 assertEquals(Intent.ACTION_SEND, innerIntent.getAction()); 244 assertNull(innerIntent.getComponent()); 245 assertNull(innerIntent.getPackage()); 246 assertEquals(UserHandle.USER_CURRENT, innerIntent.getContentUserHint()); 247 248 assertEquals(CURRENT_USER_INFO.id, activity.mUserIdActivityLaunchedIn); 249 } 250 251 @Test forwardToManagedProfile_canForward_selectorIntent()252 public void forwardToManagedProfile_canForward_selectorIntent() throws Exception { 253 sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME; 254 255 // Intent can be forwarded. 256 when(mIPm.canForwardTo( 257 any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true); 258 259 // Manage profile exists. 260 List<UserInfo> profiles = new ArrayList<>(); 261 profiles.add(CURRENT_USER_INFO); 262 profiles.add(MANAGED_PROFILE_INFO); 263 when(mUserManager.getProfiles(anyInt())).thenReturn(profiles); 264 265 // Create selector intent. 266 Intent intent = Intent.makeMainSelectorActivity( 267 Intent.ACTION_VIEW, Intent.CATEGORY_BROWSABLE); 268 IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent); 269 270 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 271 verify(mIPm).canForwardTo( 272 intentCaptor.capture(), nullable(String.class), anyInt(), anyInt()); 273 assertEquals(Intent.ACTION_VIEW, intentCaptor.getValue().getAction()); 274 275 assertNotNull(activity.mStartActivityIntent); 276 assertEquals(Intent.ACTION_MAIN, activity.mStartActivityIntent.getAction()); 277 assertNull(activity.mStartActivityIntent.getPackage()); 278 assertNull(activity.mStartActivityIntent.getComponent()); 279 assertEquals(CURRENT_USER_INFO.id, activity.mStartActivityIntent.getContentUserHint()); 280 281 Intent innerIntent = activity.mStartActivityIntent.getSelector(); 282 assertNotNull(innerIntent); 283 assertEquals(Intent.ACTION_VIEW, innerIntent.getAction()); 284 assertNull(innerIntent.getComponent()); 285 assertNull(innerIntent.getPackage()); 286 287 assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn); 288 } 289 290 @Test shouldSkipDisclosure_notWhitelisted()291 public void shouldSkipDisclosure_notWhitelisted() throws RemoteException { 292 setupShouldSkipDisclosureTest(); 293 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 294 .setAction(Intent.ACTION_SEND) 295 .setType(TYPE_PLAIN_TEXT); 296 297 mActivityRule.launchActivity(intent); 298 299 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 300 verify(sInjector).showToast(anyInt(), anyInt()); 301 } 302 303 @Test shouldSkipDisclosure_withResolverActivity()304 public void shouldSkipDisclosure_withResolverActivity() throws RemoteException { 305 setupShouldSkipDisclosureTest(); 306 sActivityName = ResolverActivity.class.getName(); 307 sPackageName = "android"; 308 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 309 .setAction(Intent.ACTION_SEND) 310 .setType(TYPE_PLAIN_TEXT); 311 312 mActivityRule.launchActivity(intent); 313 314 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 315 verify(sInjector, never()).showToast(anyInt(), anyInt()); 316 } 317 318 @Test shouldSkipDisclosure_callIntent_call()319 public void shouldSkipDisclosure_callIntent_call() throws RemoteException { 320 setupShouldSkipDisclosureTest(); 321 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 322 .setAction(Intent.ACTION_CALL); 323 324 mActivityRule.launchActivity(intent); 325 326 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 327 verify(sInjector, never()).showToast(anyInt(), anyInt()); 328 } 329 330 @Test shouldSkipDisclosure_callIntent_callPrivileged()331 public void shouldSkipDisclosure_callIntent_callPrivileged() throws RemoteException { 332 setupShouldSkipDisclosureTest(); 333 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 334 .setAction(Intent.ACTION_CALL_PRIVILEGED); 335 336 mActivityRule.launchActivity(intent); 337 338 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 339 verify(sInjector, never()).showToast(anyInt(), anyInt()); 340 } 341 342 @Test shouldSkipDisclosure_callIntent_callEmergency()343 public void shouldSkipDisclosure_callIntent_callEmergency() throws RemoteException { 344 setupShouldSkipDisclosureTest(); 345 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 346 .setAction(Intent.ACTION_CALL_EMERGENCY); 347 348 mActivityRule.launchActivity(intent); 349 350 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 351 verify(sInjector, never()).showToast(anyInt(), anyInt()); 352 } 353 354 @Test shouldSkipDisclosure_callIntent_dial()355 public void shouldSkipDisclosure_callIntent_dial() throws RemoteException { 356 setupShouldSkipDisclosureTest(); 357 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 358 .setAction(Intent.ACTION_DIAL); 359 360 mActivityRule.launchActivity(intent); 361 362 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 363 verify(sInjector, never()).showToast(anyInt(), anyInt()); 364 } 365 366 @Test shouldSkipDisclosure_callIntent_notCallOrDial()367 public void shouldSkipDisclosure_callIntent_notCallOrDial() throws RemoteException { 368 setupShouldSkipDisclosureTest(); 369 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 370 .setAction(Intent.ACTION_ALARM_CHANGED); 371 372 mActivityRule.launchActivity(intent); 373 374 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 375 verify(sInjector).showToast(anyInt(), anyInt()); 376 } 377 378 @Test shouldSkipDisclosure_callIntent_actionViewTel()379 public void shouldSkipDisclosure_callIntent_actionViewTel() throws RemoteException { 380 setupShouldSkipDisclosureTest(); 381 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 382 .setAction(Intent.ACTION_VIEW) 383 .addCategory(Intent.CATEGORY_BROWSABLE) 384 .setData(Uri.fromParts("tel", PHONE_NUMBER, null)); 385 386 mActivityRule.launchActivity(intent); 387 388 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 389 verify(sInjector, never()).showToast(anyInt(), anyInt()); 390 } 391 392 @Test shouldSkipDisclosure_textMessageIntent_sms()393 public void shouldSkipDisclosure_textMessageIntent_sms() throws RemoteException { 394 setupShouldSkipDisclosureTest(); 395 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 396 .setAction(Intent.ACTION_SENDTO) 397 .setData(Uri.fromParts("sms", PHONE_NUMBER, null)); 398 399 mActivityRule.launchActivity(intent); 400 401 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 402 verify(sInjector, never()).showToast(anyInt(), anyInt()); 403 } 404 405 @Test shouldSkipDisclosure_textMessageIntent_smsto()406 public void shouldSkipDisclosure_textMessageIntent_smsto() throws RemoteException { 407 setupShouldSkipDisclosureTest(); 408 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 409 .setAction(Intent.ACTION_SENDTO) 410 .setData(Uri.fromParts("smsto", PHONE_NUMBER, null)); 411 412 mActivityRule.launchActivity(intent); 413 414 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 415 verify(sInjector, never()).showToast(anyInt(), anyInt()); 416 } 417 418 @Test shouldSkipDisclosure_textMessageIntent_mms()419 public void shouldSkipDisclosure_textMessageIntent_mms() throws RemoteException { 420 setupShouldSkipDisclosureTest(); 421 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 422 .setAction(Intent.ACTION_SENDTO) 423 .setData(Uri.fromParts("mms", PHONE_NUMBER, null)); 424 425 mActivityRule.launchActivity(intent); 426 427 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 428 verify(sInjector, never()).showToast(anyInt(), anyInt()); 429 } 430 431 @Test shouldSkipDisclosure_textMessageIntent_mmsto()432 public void shouldSkipDisclosure_textMessageIntent_mmsto() throws RemoteException { 433 setupShouldSkipDisclosureTest(); 434 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 435 .setAction(Intent.ACTION_SENDTO) 436 .setData(Uri.fromParts("mmsto", PHONE_NUMBER, null)); 437 438 mActivityRule.launchActivity(intent); 439 440 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 441 verify(sInjector, never()).showToast(anyInt(), anyInt()); 442 } 443 444 @Test shouldSkipDisclosure_textMessageIntent_actionViewSms()445 public void shouldSkipDisclosure_textMessageIntent_actionViewSms() throws RemoteException { 446 setupShouldSkipDisclosureTest(); 447 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 448 .setAction(Intent.ACTION_VIEW) 449 .addCategory(Intent.CATEGORY_BROWSABLE) 450 .setData(Uri.fromParts("sms", PHONE_NUMBER, null)); 451 452 mActivityRule.launchActivity(intent); 453 454 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 455 verify(sInjector, never()).showToast(anyInt(), anyInt()); 456 } 457 458 @Test shouldSkipDisclosure_textMessageIntent_actionViewSmsto()459 public void shouldSkipDisclosure_textMessageIntent_actionViewSmsto() throws RemoteException { 460 setupShouldSkipDisclosureTest(); 461 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 462 .setAction(Intent.ACTION_VIEW) 463 .addCategory(Intent.CATEGORY_BROWSABLE) 464 .setData(Uri.fromParts("smsto", PHONE_NUMBER, null)); 465 466 mActivityRule.launchActivity(intent); 467 468 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 469 verify(sInjector, never()).showToast(anyInt(), anyInt()); 470 } 471 472 @Test shouldSkipDisclosure_textMessageIntent_actionViewMms()473 public void shouldSkipDisclosure_textMessageIntent_actionViewMms() throws RemoteException { 474 setupShouldSkipDisclosureTest(); 475 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 476 .setAction(Intent.ACTION_VIEW) 477 .addCategory(Intent.CATEGORY_BROWSABLE) 478 .setData(Uri.fromParts("mms", PHONE_NUMBER, null)); 479 480 mActivityRule.launchActivity(intent); 481 482 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 483 verify(sInjector, never()).showToast(anyInt(), anyInt()); 484 } 485 486 @Test shouldSkipDisclosure_textMessageIntent_actionViewMmsto()487 public void shouldSkipDisclosure_textMessageIntent_actionViewMmsto() throws RemoteException { 488 setupShouldSkipDisclosureTest(); 489 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 490 .setAction(Intent.ACTION_VIEW) 491 .addCategory(Intent.CATEGORY_BROWSABLE) 492 .setData(Uri.fromParts("mmsto", PHONE_NUMBER, null)); 493 494 mActivityRule.launchActivity(intent); 495 496 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 497 verify(sInjector, never()).showToast(anyInt(), anyInt()); 498 } 499 500 @Test shouldSkipDisclosure_textMessageIntent_invalidUri()501 public void shouldSkipDisclosure_textMessageIntent_invalidUri() throws RemoteException { 502 setupShouldSkipDisclosureTest(); 503 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 504 .setAction(Intent.ACTION_SENDTO) 505 .setData(Uri.fromParts("invalid", PHONE_NUMBER, null)); 506 507 mActivityRule.launchActivity(intent); 508 509 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 510 verify(sInjector).showToast(anyInt(), anyInt()); 511 } 512 513 @Test shouldSkipDisclosure_viewBrowsableIntent_invalidUri()514 public void shouldSkipDisclosure_viewBrowsableIntent_invalidUri() throws RemoteException { 515 setupShouldSkipDisclosureTest(); 516 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 517 .setAction(Intent.ACTION_VIEW) 518 .addCategory(Intent.CATEGORY_BROWSABLE) 519 .setData(Uri.fromParts("invalid", PHONE_NUMBER, null)); 520 521 mActivityRule.launchActivity(intent); 522 523 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 524 verify(sInjector).showToast(anyInt(), anyInt()); 525 } 526 527 @Test shouldSkipDisclosure_viewBrowsableIntent_normalUrl()528 public void shouldSkipDisclosure_viewBrowsableIntent_normalUrl() throws RemoteException { 529 setupShouldSkipDisclosureTest(); 530 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 531 .setAction(Intent.ACTION_VIEW) 532 .addCategory(Intent.CATEGORY_BROWSABLE) 533 .setData(Uri.fromParts("http", "apache.org", null)); 534 535 mActivityRule.launchActivity(intent); 536 537 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 538 verify(sInjector).showToast(anyInt(), anyInt()); 539 } 540 541 @Test shouldSkipDisclosure_duringDeviceSetup()542 public void shouldSkipDisclosure_duringDeviceSetup() throws RemoteException { 543 setupShouldSkipDisclosureTest(); 544 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 545 /* value= */ 0); 546 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) 547 .setAction(Intent.ACTION_VIEW) 548 .addCategory(Intent.CATEGORY_BROWSABLE) 549 .setData(Uri.fromParts("http", "apache.org", null)); 550 551 mActivityRule.launchActivity(intent); 552 553 verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); 554 verify(sInjector, never()).showToast(anyInt(), anyInt()); 555 } 556 557 @Test forwardToManagedProfile_LoggingTest()558 public void forwardToManagedProfile_LoggingTest() throws Exception { 559 sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME; 560 561 // Intent can be forwarded. 562 when(mIPm.canForwardTo( 563 any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true); 564 565 // Managed profile exists. 566 List<UserInfo> profiles = new ArrayList<>(); 567 profiles.add(CURRENT_USER_INFO); 568 profiles.add(MANAGED_PROFILE_INFO); 569 when(mUserManager.getProfiles(anyInt())).thenReturn(profiles); 570 571 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class); 572 intent.setAction(Intent.ACTION_SEND); 573 intent.setType(TYPE_PLAIN_TEXT); 574 IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent); 575 576 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); 577 verify(activity.getMetricsLogger()).write(logMakerCaptor.capture()); 578 assertEquals(MetricsEvent.ACTION_SWITCH_SHARE_PROFILE, 579 logMakerCaptor.getValue().getCategory()); 580 assertEquals(MetricsEvent.MANAGED_PROFILE, 581 logMakerCaptor.getValue().getSubtype()); 582 } 583 584 @Test forwardToParent_LoggingTest()585 public void forwardToParent_LoggingTest() throws Exception { 586 sComponentName = FORWARD_TO_PARENT_COMPONENT_NAME; 587 588 // Intent can be forwarded. 589 when(mIPm.canForwardTo( 590 any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true); 591 592 // Managed profile exists. 593 List<UserInfo> profiles = new ArrayList<>(); 594 profiles.add(CURRENT_USER_INFO); 595 profiles.add(MANAGED_PROFILE_INFO); 596 when(mUserManager.getProfiles(anyInt())).thenReturn(profiles); 597 598 Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class); 599 intent.setAction(Intent.ACTION_SEND); 600 intent.setType(TYPE_PLAIN_TEXT); 601 IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent); 602 603 ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); 604 verify(activity.getMetricsLogger()).write(logMakerCaptor.capture()); 605 assertEquals(MetricsEvent.ACTION_SWITCH_SHARE_PROFILE, 606 logMakerCaptor.getValue().getCategory()); 607 assertEquals(MetricsEvent.PARENT_PROFILE, 608 logMakerCaptor.getValue().getSubtype()); 609 } 610 setupShouldSkipDisclosureTest()611 private void setupShouldSkipDisclosureTest() throws RemoteException { 612 sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME; 613 sActivityName = "MyTestActivity"; 614 sPackageName = "test.package.name"; 615 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 616 /* value= */ 1); 617 when(mApplicationInfo.isSystemApp()).thenReturn(true); 618 // Managed profile exists. 619 List<UserInfo> profiles = new ArrayList<>(); 620 profiles.add(CURRENT_USER_INFO); 621 profiles.add(MANAGED_PROFILE_INFO); 622 when(mUserManager.getProfiles(anyInt())).thenReturn(profiles); 623 // Intent can be forwarded. 624 when(mIPm.canForwardTo( 625 any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true); 626 } 627 628 public static class IntentForwarderWrapperActivity extends IntentForwarderActivity { 629 630 private Intent mStartActivityIntent; 631 private int mUserIdActivityLaunchedIn; 632 private MetricsLogger mMetricsLogger = mock(MetricsLogger.class); 633 634 @Override onCreate(@ullable Bundle savedInstanceState)635 public void onCreate(@Nullable Bundle savedInstanceState) { 636 getIntent().setComponent(sComponentName); 637 super.onCreate(savedInstanceState); 638 try { 639 mExecutorService.awaitTermination(/* timeout= */ 30, TimeUnit.SECONDS); 640 } catch (InterruptedException e) { 641 e.printStackTrace(); 642 } 643 } 644 645 @Override createInjector()646 protected Injector createInjector() { 647 return sInjector; 648 } 649 650 @Override startActivityAsCaller(Intent intent, @Nullable Bundle options, IBinder permissionToken, boolean ignoreTargetSecurity, int userId)651 public void startActivityAsCaller(Intent intent, @Nullable Bundle options, 652 IBinder permissionToken, boolean ignoreTargetSecurity, int userId) { 653 mStartActivityIntent = intent; 654 mUserIdActivityLaunchedIn = userId; 655 } 656 657 @Override getMetricsLogger()658 protected MetricsLogger getMetricsLogger() { 659 return mMetricsLogger; 660 } 661 } 662 663 public class TestInjector implements IntentForwarderActivity.Injector { 664 665 @Override getIPackageManager()666 public IPackageManager getIPackageManager() { 667 return mIPm; 668 } 669 670 @Override getUserManager()671 public UserManager getUserManager() { 672 return mUserManager; 673 } 674 675 @Override getPackageManager()676 public PackageManager getPackageManager() { 677 return mPm; 678 } 679 680 @Override resolveActivityAsUser( Intent intent, int flags, int userId)681 public CompletableFuture<ResolveInfo> resolveActivityAsUser( 682 Intent intent, int flags, int userId) { 683 ActivityInfo activityInfo = new ActivityInfo(); 684 activityInfo.packageName = sPackageName; 685 activityInfo.name = sActivityName; 686 activityInfo.applicationInfo = mApplicationInfo; 687 688 ResolveInfo resolveInfo = new ResolveInfo(); 689 resolveInfo.activityInfo = activityInfo; 690 691 return CompletableFuture.completedFuture(resolveInfo); 692 } 693 694 @Override showToast(int messageId, int duration)695 public void showToast(int messageId, int duration) {} 696 } 697 } 698