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