• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 org.mockito.Mockito.mock;
20 import static org.mockito.Mockito.when;
21 
22 import android.annotation.Nullable;
23 import android.app.usage.UsageStatsManager;
24 import android.content.ComponentName;
25 import android.content.ContentResolver;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.content.pm.PackageManager;
29 import android.content.pm.ResolveInfo;
30 import android.content.res.Resources;
31 import android.database.Cursor;
32 import android.graphics.Bitmap;
33 import android.net.Uri;
34 import android.os.UserHandle;
35 import android.util.Size;
36 
37 import com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter;
38 import com.android.internal.app.chooser.DisplayResolveInfo;
39 import com.android.internal.app.chooser.TargetInfo;
40 import com.android.internal.logging.MetricsLogger;
41 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
42 
43 import java.util.List;
44 import java.util.function.Function;
45 
46 public class ChooserWrapperActivity extends ChooserActivity {
47     /*
48      * Simple wrapper around chooser activity to be able to initiate it under test
49      */
50     static final OverrideData sOverrides = new OverrideData();
51     private UsageStatsManager mUsm;
52 
53     @Override
createMultiProfilePagerAdapter( Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed)54     protected AbstractMultiProfilePagerAdapter createMultiProfilePagerAdapter(
55             Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) {
56         AbstractMultiProfilePagerAdapter multiProfilePagerAdapter =
57                 super.createMultiProfilePagerAdapter(initialIntents, rList, filterLastUsed);
58         multiProfilePagerAdapter.setInjector(sOverrides.multiPagerAdapterInjector);
59         return multiProfilePagerAdapter;
60     }
61 
62     @Override
createChooserListAdapter(Context context, List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed, ResolverListController resolverListController)63     public ChooserListAdapter createChooserListAdapter(Context context, List<Intent> payloadIntents,
64             Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed,
65             ResolverListController resolverListController) {
66         PackageManager packageManager =
67                 sOverrides.packageManager == null ? context.getPackageManager()
68                         : sOverrides.packageManager;
69         return new ChooserListAdapter(context, payloadIntents, initialIntents, rList,
70                 filterLastUsed, resolverListController,
71                 this, this, packageManager,
72                 getChooserActivityLogger());
73     }
74 
getAdapter()75     ChooserListAdapter getAdapter() {
76         return mChooserMultiProfilePagerAdapter.getActiveListAdapter();
77     }
78 
getPersonalListAdapter()79     ChooserListAdapter getPersonalListAdapter() {
80         return ((ChooserGridAdapter) mMultiProfilePagerAdapter.getAdapterForIndex(0))
81                 .getListAdapter();
82     }
83 
getWorkListAdapter()84     ChooserListAdapter getWorkListAdapter() {
85         if (mMultiProfilePagerAdapter.getInactiveListAdapter() == null) {
86             return null;
87         }
88         return ((ChooserGridAdapter) mMultiProfilePagerAdapter.getAdapterForIndex(1))
89                 .getListAdapter();
90     }
91 
getIsSelected()92     boolean getIsSelected() { return mIsSuccessfullySelected; }
93 
94     @Override
getNearbySharingComponent()95     protected ComponentName getNearbySharingComponent() {
96         // an arbitrary pre-installed activity that handles this type of intent
97         return ComponentName.unflattenFromString("com.google.android.apps.messaging/"
98                 + "com.google.android.apps.messaging.ui.conversationlist.ShareIntentActivity");
99     }
100 
101     @Override
getNearbySharingTarget(Intent originalIntent)102     protected TargetInfo getNearbySharingTarget(Intent originalIntent) {
103         return new ChooserWrapperActivity.EmptyTargetInfo();
104     }
105 
getUsageStatsManager()106     UsageStatsManager getUsageStatsManager() {
107         if (mUsm == null) {
108             mUsm = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
109         }
110         return mUsm;
111     }
112 
113     @Override
isVoiceInteraction()114     public boolean isVoiceInteraction() {
115         if (sOverrides.isVoiceInteraction != null) {
116             return sOverrides.isVoiceInteraction;
117         }
118         return super.isVoiceInteraction();
119     }
120 
121     @Override
safelyStartActivity(com.android.internal.app.chooser.TargetInfo cti)122     public void safelyStartActivity(com.android.internal.app.chooser.TargetInfo cti) {
123         if (sOverrides.onSafelyStartCallback != null &&
124                 sOverrides.onSafelyStartCallback.apply(cti)) {
125             return;
126         }
127         super.safelyStartActivity(cti);
128     }
129 
130     @Override
createListController(UserHandle userHandle)131     protected ResolverListController createListController(UserHandle userHandle) {
132         if (userHandle == UserHandle.SYSTEM) {
133             when(sOverrides.resolverListController.getUserHandle()).thenReturn(UserHandle.SYSTEM);
134             return sOverrides.resolverListController;
135         }
136         when(sOverrides.workResolverListController.getUserHandle()).thenReturn(userHandle);
137         return sOverrides.workResolverListController;
138     }
139 
140     @Override
getPackageManager()141     public PackageManager getPackageManager() {
142         if (sOverrides.createPackageManager != null) {
143             return sOverrides.createPackageManager.apply(super.getPackageManager());
144         }
145         return super.getPackageManager();
146     }
147 
148     @Override
getResources()149     public Resources getResources() {
150         if (sOverrides.resources != null) {
151             return sOverrides.resources;
152         }
153         return super.getResources();
154     }
155 
156     @Override
loadThumbnail(Uri uri, Size size)157     protected Bitmap loadThumbnail(Uri uri, Size size) {
158         if (sOverrides.previewThumbnail != null) {
159             return sOverrides.previewThumbnail;
160         }
161         return super.loadThumbnail(uri, size);
162     }
163 
164     @Override
isImageType(String mimeType)165     protected boolean isImageType(String mimeType) {
166         return sOverrides.isImageType;
167     }
168 
169     @Override
getMetricsLogger()170     protected MetricsLogger getMetricsLogger() {
171         return sOverrides.metricsLogger;
172     }
173 
174     @Override
getChooserActivityLogger()175     protected ChooserActivityLogger getChooserActivityLogger() {
176         return sOverrides.chooserActivityLogger;
177     }
178 
179     @Override
queryResolver(ContentResolver resolver, Uri uri)180     public Cursor queryResolver(ContentResolver resolver, Uri uri) {
181         if (sOverrides.resolverCursor != null) {
182             return sOverrides.resolverCursor;
183         }
184 
185         if (sOverrides.resolverForceException) {
186             throw new SecurityException("Test exception handling");
187         }
188 
189         return super.queryResolver(resolver, uri);
190     }
191 
192     @Override
isWorkProfile()193     protected boolean isWorkProfile() {
194         if (sOverrides.alternateProfileSetting != 0) {
195             return sOverrides.alternateProfileSetting == MetricsEvent.MANAGED_PROFILE;
196         }
197         return super.isWorkProfile();
198     }
199 
createTestDisplayResolveInfo(Intent originalIntent, ResolveInfo pri, CharSequence pLabel, CharSequence pInfo, Intent replacementIntent, @Nullable ResolveInfoPresentationGetter resolveInfoPresentationGetter)200     public DisplayResolveInfo createTestDisplayResolveInfo(Intent originalIntent, ResolveInfo pri,
201             CharSequence pLabel, CharSequence pInfo, Intent replacementIntent,
202             @Nullable ResolveInfoPresentationGetter resolveInfoPresentationGetter) {
203         return new DisplayResolveInfo(originalIntent, pri, pLabel, pInfo, replacementIntent,
204                 resolveInfoPresentationGetter);
205     }
206 
207     @Override
getWorkProfileUserHandle()208     protected UserHandle getWorkProfileUserHandle() {
209         return sOverrides.workProfileUserHandle;
210     }
211 
getCurrentUserHandle()212     protected UserHandle getCurrentUserHandle() {
213         return mMultiProfilePagerAdapter.getCurrentUserHandle();
214     }
215 
216     @Override
createContextAsUser(UserHandle user, int flags)217     public Context createContextAsUser(UserHandle user, int flags) {
218         // return the current context as a work profile doesn't really exist in these tests
219         return getApplicationContext();
220     }
221 
222     @Override
queryDirectShareTargets(ChooserListAdapter adapter, boolean skipAppPredictionService)223     protected void queryDirectShareTargets(ChooserListAdapter adapter,
224             boolean skipAppPredictionService) {
225         if (sOverrides.onQueryDirectShareTargets != null) {
226             sOverrides.onQueryDirectShareTargets.apply(adapter);
227         }
228         super.queryDirectShareTargets(adapter, skipAppPredictionService);
229     }
230 
231     @Override
queryTargetServices(ChooserListAdapter adapter)232     protected void queryTargetServices(ChooserListAdapter adapter) {
233         if (sOverrides.onQueryTargetServices != null) {
234             sOverrides.onQueryTargetServices.apply(adapter);
235         }
236         super.queryTargetServices(adapter);
237     }
238 
239     @Override
isQuietModeEnabled(UserHandle userHandle)240     protected boolean isQuietModeEnabled(UserHandle userHandle) {
241         return sOverrides.isQuietModeEnabled;
242     }
243 
244     @Override
isUserRunning(UserHandle userHandle)245     protected boolean isUserRunning(UserHandle userHandle) {
246         if (userHandle.equals(UserHandle.SYSTEM)) {
247             return super.isUserRunning(userHandle);
248         }
249         return sOverrides.isWorkProfileUserRunning;
250     }
251 
252     @Override
isUserUnlocked(UserHandle userHandle)253     protected boolean isUserUnlocked(UserHandle userHandle) {
254         if (userHandle.equals(UserHandle.SYSTEM)) {
255             return super.isUserUnlocked(userHandle);
256         }
257         return sOverrides.isWorkProfileUserUnlocked;
258     }
259 
260     /**
261      * We cannot directly mock the activity created since instrumentation creates it.
262      * <p>
263      * Instead, we use static instances of this object to modify behavior.
264      */
265     static class OverrideData {
266         @SuppressWarnings("Since15")
267         public Function<PackageManager, PackageManager> createPackageManager;
268         public Function<TargetInfo, Boolean> onSafelyStartCallback;
269         public Function<ChooserListAdapter, Void> onQueryDirectShareTargets;
270         public Function<ChooserListAdapter, Void> onQueryTargetServices;
271         public ResolverListController resolverListController;
272         public ResolverListController workResolverListController;
273         public Boolean isVoiceInteraction;
274         public boolean isImageType;
275         public Cursor resolverCursor;
276         public boolean resolverForceException;
277         public Bitmap previewThumbnail;
278         public MetricsLogger metricsLogger;
279         public ChooserActivityLogger chooserActivityLogger;
280         public int alternateProfileSetting;
281         public Resources resources;
282         public UserHandle workProfileUserHandle;
283         public boolean hasCrossProfileIntents;
284         public boolean isQuietModeEnabled;
285         public boolean isWorkProfileUserRunning;
286         public boolean isWorkProfileUserUnlocked;
287         public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector;
288         public PackageManager packageManager;
289 
reset()290         public void reset() {
291             onSafelyStartCallback = null;
292             onQueryDirectShareTargets = null;
293             onQueryTargetServices = null;
294             isVoiceInteraction = null;
295             createPackageManager = null;
296             previewThumbnail = null;
297             isImageType = false;
298             resolverCursor = null;
299             resolverForceException = false;
300             resolverListController = mock(ResolverListController.class);
301             workResolverListController = mock(ResolverListController.class);
302             metricsLogger = mock(MetricsLogger.class);
303             chooserActivityLogger = new ChooserActivityLoggerFake();
304             alternateProfileSetting = 0;
305             resources = null;
306             workProfileUserHandle = null;
307             hasCrossProfileIntents = true;
308             isQuietModeEnabled = false;
309             isWorkProfileUserRunning = true;
310             isWorkProfileUserUnlocked = true;
311             packageManager = null;
312             multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() {
313                 @Override
314                 public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId,
315                         int targetUserId) {
316                     return hasCrossProfileIntents;
317                 }
318 
319                 @Override
320                 public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) {
321                     return isQuietModeEnabled;
322                 }
323 
324                 @Override
325                 public void requestQuietModeEnabled(boolean enabled,
326                         UserHandle workProfileUserHandle) {
327                     isQuietModeEnabled = enabled;
328                 }
329             };
330         }
331     }
332 }
333