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 android.annotation.Nullable;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.IPackageManager;
24 import android.content.pm.PackageManager;
25 import android.content.pm.UserInfo;
26 import android.os.Bundle;
27 import android.os.UserHandle;
28 import android.os.UserManager;
29 import android.support.test.InstrumentationRegistry;
30 import android.support.test.rule.ActivityTestRule;
31 import android.support.test.runner.AndroidJUnit4;
32 import android.util.Log;
33 
34 import org.junit.Before;
35 import org.junit.Rule;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 import org.mockito.ArgumentCaptor;
39 import org.mockito.Mock;
40 import org.mockito.Mockito;
41 import org.mockito.MockitoAnnotations;
42 
43 import java.util.ArrayList;
44 import java.util.List;
45 
46 import static junit.framework.Assert.assertEquals;
47 import static junit.framework.Assert.assertNotNull;
48 import static junit.framework.Assert.assertNull;
49 import static org.mockito.ArgumentMatchers.any;
50 import static org.mockito.ArgumentMatchers.anyInt;
51 import static org.mockito.ArgumentMatchers.anyString;
52 import static org.mockito.ArgumentMatchers.eq;
53 import static org.mockito.ArgumentMatchers.nullable;
54 import static org.mockito.Mockito.verify;
55 import static org.mockito.Mockito.when;
56 
57 @RunWith(AndroidJUnit4.class)
58 public class IntentForwarderActivityTest {
59     private static final ComponentName FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME =
60             new ComponentName(
61                     "android",
62                     IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE
63             );
64     private static final String TYPE_PLAIN_TEXT = "text/plain";
65 
66     private static UserInfo MANAGED_PROFILE_INFO = new UserInfo();
67     static {
68         MANAGED_PROFILE_INFO.id = 10;
69         MANAGED_PROFILE_INFO.flags = UserInfo.FLAG_MANAGED_PROFILE;
70     }
71 
72     private static UserInfo CURRENT_USER_INFO = new UserInfo();
73     static {
74         CURRENT_USER_INFO.id = UserHandle.myUserId();
75         CURRENT_USER_INFO.flags = 0;
76     }
77 
78     private static IntentForwarderActivity.Injector sInjector;
79     private static ComponentName sComponentName;
80 
81     @Mock private IPackageManager mIPm;
82     @Mock private PackageManager mPm;
83     @Mock private UserManager mUserManager;
84 
85     @Rule
86     public ActivityTestRule<IntentForwarderWrapperActivity> mActivityRule =
87             new ActivityTestRule<>(IntentForwarderWrapperActivity.class, true, false);
88 
89     private Context mContext;
90 
91     @Before
setup()92     public void setup() {
93         MockitoAnnotations.initMocks(this);
94         mContext = InstrumentationRegistry.getTargetContext();
95         sInjector = new TestInjector();
96     }
97 
98     @Test
forwardToManagedProfile_canForward_sendIntent()99     public void forwardToManagedProfile_canForward_sendIntent() throws Exception {
100         sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
101 
102         // Intent can be forwarded.
103         when(mIPm.canForwardTo(
104                 any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
105 
106         // Managed profile exists.
107         List<UserInfo> profiles = new ArrayList<>();
108         profiles.add(CURRENT_USER_INFO);
109         profiles.add(MANAGED_PROFILE_INFO);
110         when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
111 
112         Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
113         intent.setAction(Intent.ACTION_SEND);
114         intent.setType(TYPE_PLAIN_TEXT);
115         IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
116 
117         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
118         verify(mIPm).canForwardTo(intentCaptor.capture(), eq(TYPE_PLAIN_TEXT), anyInt(), anyInt());
119         assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction());
120 
121         assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction());
122         assertNotNull(activity.mStartActivityIntent);
123         assertEquals(Intent.ACTION_SEND, activity.mStartActivityIntent.getAction());
124         assertNull(activity.mStartActivityIntent.getPackage());
125         assertNull(activity.mStartActivityIntent.getComponent());
126         assertEquals(CURRENT_USER_INFO.id, activity.mStartActivityIntent.getContentUserHint());
127 
128         assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn);
129     }
130 
131     @Test
forwardToManagedProfile_cannotForward_sendIntent()132     public void forwardToManagedProfile_cannotForward_sendIntent() throws Exception {
133         sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
134 
135         // Intent cannot be forwarded.
136         when(mIPm.canForwardTo(
137                 any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(false);
138 
139         // Managed profile exists.
140         List<UserInfo> profiles = new ArrayList<>();
141         profiles.add(CURRENT_USER_INFO);
142         profiles.add(MANAGED_PROFILE_INFO);
143         when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
144 
145         // Create ACTION_SEND intent.
146         Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
147         intent.setAction(Intent.ACTION_SEND);
148         IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
149 
150         assertNull(activity.mStartActivityIntent);
151     }
152 
153     @Test
forwardToManagedProfile_noManagedProfile_sendIntent()154     public void forwardToManagedProfile_noManagedProfile_sendIntent() throws Exception {
155         sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
156 
157         // Intent can be forwarded.
158         when(mIPm.canForwardTo(
159                 any(Intent.class), anyString(), anyInt(), anyInt())).thenReturn(true);
160 
161         // Managed profile does not exist.
162         List<UserInfo> profiles = new ArrayList<>();
163         profiles.add(CURRENT_USER_INFO);
164         when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
165 
166         // Create ACTION_SEND intent.
167         Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
168         intent.setAction(Intent.ACTION_SEND);
169         IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
170 
171         assertNull(activity.mStartActivityIntent);
172     }
173 
174     @Test
forwardToManagedProfile_canForward_chooserIntent()175     public void forwardToManagedProfile_canForward_chooserIntent() throws Exception {
176         sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
177 
178         // Intent can be forwarded.
179         when(mIPm.canForwardTo(
180                 any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
181 
182         // Manage 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 chooser Intent
189         Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
190         intent.setAction(Intent.ACTION_CHOOSER);
191         Intent sendIntent = new Intent(Intent.ACTION_SEND);
192         sendIntent.setComponent(new ComponentName("xx", "yyy"));
193         sendIntent.setType(TYPE_PLAIN_TEXT);
194         intent.putExtra(Intent.EXTRA_INTENT, sendIntent);
195         IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
196 
197         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
198         verify(mIPm).canForwardTo(intentCaptor.capture(), eq(TYPE_PLAIN_TEXT), anyInt(), anyInt());
199         assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction());
200 
201         assertNotNull(activity.mStartActivityIntent);
202         assertEquals(Intent.ACTION_CHOOSER, activity.mStartActivityIntent.getAction());
203         assertNull(activity.mStartActivityIntent.getPackage());
204         assertNull(activity.mStartActivityIntent.getComponent());
205 
206         Intent innerIntent = activity.mStartActivityIntent.getParcelableExtra(Intent.EXTRA_INTENT);
207         assertNotNull(innerIntent);
208         assertEquals(Intent.ACTION_SEND, innerIntent.getAction());
209         assertNull(innerIntent.getComponent());
210         assertNull(innerIntent.getPackage());
211         assertEquals(CURRENT_USER_INFO.id, innerIntent.getContentUserHint());
212 
213         assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn);
214     }
215 
216     @Test
forwardToManagedProfile_canForward_selectorIntent()217     public void forwardToManagedProfile_canForward_selectorIntent() throws Exception {
218         sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
219 
220         // Intent can be forwarded.
221         when(mIPm.canForwardTo(
222                 any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
223 
224         // Manage profile exists.
225         List<UserInfo> profiles = new ArrayList<>();
226         profiles.add(CURRENT_USER_INFO);
227         profiles.add(MANAGED_PROFILE_INFO);
228         when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
229 
230         // Create selector intent.
231         Intent intent = Intent.makeMainSelectorActivity(
232                 Intent.ACTION_VIEW, Intent.CATEGORY_BROWSABLE);
233         IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
234 
235         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
236         verify(mIPm).canForwardTo(
237                 intentCaptor.capture(), nullable(String.class), anyInt(), anyInt());
238         assertEquals(Intent.ACTION_VIEW, intentCaptor.getValue().getAction());
239 
240         assertNotNull(activity.mStartActivityIntent);
241         assertEquals(Intent.ACTION_MAIN, activity.mStartActivityIntent.getAction());
242         assertNull(activity.mStartActivityIntent.getPackage());
243         assertNull(activity.mStartActivityIntent.getComponent());
244         assertEquals(CURRENT_USER_INFO.id, activity.mStartActivityIntent.getContentUserHint());
245 
246         Intent innerIntent = activity.mStartActivityIntent.getSelector();
247         assertNotNull(innerIntent);
248         assertEquals(Intent.ACTION_VIEW, innerIntent.getAction());
249         assertNull(innerIntent.getComponent());
250         assertNull(innerIntent.getPackage());
251 
252         assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn);
253     }
254 
255 
256     public static class IntentForwarderWrapperActivity extends IntentForwarderActivity {
257         private Intent mStartActivityIntent;
258         private int mUserIdActivityLaunchedIn;
259 
260         @Override
onCreate(@ullable Bundle savedInstanceState)261         public void onCreate(@Nullable Bundle savedInstanceState) {
262             getIntent().setComponent(sComponentName);
263             super.onCreate(savedInstanceState);
264         }
265 
266         @Override
createInjector()267         protected Injector createInjector() {
268             return sInjector;
269         }
270 
271         @Override
startActivityAsCaller(Intent intent, @Nullable Bundle options, boolean ignoreTargetSecurity, int userId)272         public void startActivityAsCaller(Intent intent, @Nullable Bundle options, boolean
273                 ignoreTargetSecurity, int userId) {
274             mStartActivityIntent = intent;
275             mUserIdActivityLaunchedIn = userId;
276         }
277     }
278 
279     class TestInjector implements IntentForwarderActivity.Injector {
280 
281         @Override
getIPackageManager()282         public IPackageManager getIPackageManager() {
283             return mIPm;
284         }
285 
286         @Override
getUserManager()287         public UserManager getUserManager() {
288             return mUserManager;
289         }
290 
291         @Override
getPackageManager()292         public PackageManager getPackageManager() {
293             return mPm;
294         }
295     }
296 }