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.ArgumentMatchers.any; 20 import static org.mockito.ArgumentMatchers.anyInt; 21 import static org.mockito.Mockito.doAnswer; 22 import static org.mockito.Mockito.spy; 23 import static org.mockito.Mockito.when; 24 25 import android.annotation.Nullable; 26 import android.app.usage.UsageStatsManager; 27 import android.content.ComponentName; 28 import android.content.ContentResolver; 29 import android.content.Context; 30 import android.content.Intent; 31 import android.content.pm.PackageManager; 32 import android.content.pm.ResolveInfo; 33 import android.content.res.Resources; 34 import android.database.Cursor; 35 import android.graphics.Bitmap; 36 import android.net.Uri; 37 import android.os.UserHandle; 38 import android.util.Pair; 39 import android.util.Size; 40 41 import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; 42 import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider; 43 import com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter; 44 import com.android.internal.app.chooser.DisplayResolveInfo; 45 import com.android.internal.app.chooser.TargetInfo; 46 import com.android.internal.logging.MetricsLogger; 47 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 48 49 import java.util.List; 50 51 /** 52 * Simple wrapper around chooser activity to be able to initiate it under test with overrides 53 * specified in the {@code ChooserActivityOverrideData} singleton. This should be copy-and-pasted 54 * verbatim to test other {@code ChooserActivity} subclasses (updating only the `extends` to match 55 * the concrete activity under test). 56 */ 57 public class ChooserWrapperActivity extends ChooserActivity implements IChooserWrapper { 58 static final ChooserActivityOverrideData sOverrides = ChooserActivityOverrideData.getInstance(); 59 private UsageStatsManager mUsm; 60 61 // ResolverActivity (the base class of ChooserActivity) inspects the launched-from UID at 62 // onCreate and needs to see some non-negative value in the test. 63 @Override getLaunchedFromUid()64 public int getLaunchedFromUid() { 65 return 1234; 66 } 67 68 @Override createChooserListAdapter(Context context, List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed, ResolverListController resolverListController)69 public ChooserListAdapter createChooserListAdapter(Context context, List<Intent> payloadIntents, 70 Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed, 71 ResolverListController resolverListController) { 72 PackageManager packageManager = 73 sOverrides.packageManager == null ? context.getPackageManager() 74 : sOverrides.packageManager; 75 return new ChooserListAdapter(context, payloadIntents, initialIntents, rList, 76 filterLastUsed, resolverListController, 77 this, this, packageManager, 78 getChooserActivityLogger()); 79 } 80 81 @Override getAdapter()82 public ChooserListAdapter getAdapter() { 83 return mChooserMultiProfilePagerAdapter.getActiveListAdapter(); 84 } 85 86 @Override getPersonalListAdapter()87 public ChooserListAdapter getPersonalListAdapter() { 88 return ((ChooserGridAdapter) mMultiProfilePagerAdapter.getAdapterForIndex(0)) 89 .getListAdapter(); 90 } 91 92 @Override getWorkListAdapter()93 public ChooserListAdapter getWorkListAdapter() { 94 if (mMultiProfilePagerAdapter.getInactiveListAdapter() == null) { 95 return null; 96 } 97 return ((ChooserGridAdapter) mMultiProfilePagerAdapter.getAdapterForIndex(1)) 98 .getListAdapter(); 99 } 100 101 @Override getIsSelected()102 public boolean getIsSelected() { 103 return mIsSuccessfullySelected; 104 } 105 106 @Override getNearbySharingComponent()107 protected ComponentName getNearbySharingComponent() { 108 // an arbitrary pre-installed activity that handles this type of intent 109 return ComponentName.unflattenFromString("com.google.android.apps.messaging/" 110 + "com.google.android.apps.messaging.ui.conversationlist.ShareIntentActivity"); 111 } 112 113 @Override getNearbySharingTarget(Intent originalIntent)114 protected TargetInfo getNearbySharingTarget(Intent originalIntent) { 115 return new ChooserWrapperActivity.EmptyTargetInfo(); 116 } 117 118 @Override getUsageStatsManager()119 public UsageStatsManager getUsageStatsManager() { 120 if (mUsm == null) { 121 mUsm = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); 122 } 123 return mUsm; 124 } 125 126 @Override isVoiceInteraction()127 public boolean isVoiceInteraction() { 128 if (sOverrides.isVoiceInteraction != null) { 129 return sOverrides.isVoiceInteraction; 130 } 131 return super.isVoiceInteraction(); 132 } 133 134 @Override createMyUserIdProvider()135 protected MyUserIdProvider createMyUserIdProvider() { 136 if (sOverrides.mMyUserIdProvider != null) { 137 return sOverrides.mMyUserIdProvider; 138 } 139 return super.createMyUserIdProvider(); 140 } 141 142 @Override createCrossProfileIntentsChecker()143 protected CrossProfileIntentsChecker createCrossProfileIntentsChecker() { 144 if (sOverrides.mCrossProfileIntentsChecker != null) { 145 return sOverrides.mCrossProfileIntentsChecker; 146 } 147 return super.createCrossProfileIntentsChecker(); 148 } 149 150 @Override createQuietModeManager()151 protected AbstractMultiProfilePagerAdapter.QuietModeManager createQuietModeManager() { 152 if (sOverrides.mQuietModeManager != null) { 153 return sOverrides.mQuietModeManager; 154 } 155 return super.createQuietModeManager(); 156 } 157 158 @Override safelyStartActivity(com.android.internal.app.chooser.TargetInfo cti)159 public void safelyStartActivity(com.android.internal.app.chooser.TargetInfo cti) { 160 if (sOverrides.onSafelyStartCallback != null && 161 sOverrides.onSafelyStartCallback.apply(cti)) { 162 return; 163 } 164 super.safelyStartActivity(cti); 165 } 166 167 @Override createListController(UserHandle userHandle)168 protected ResolverListController createListController(UserHandle userHandle) { 169 if (userHandle == UserHandle.SYSTEM) { 170 when(sOverrides.resolverListController.getUserHandle()).thenReturn(UserHandle.SYSTEM); 171 return sOverrides.resolverListController; 172 } 173 when(sOverrides.workResolverListController.getUserHandle()).thenReturn(userHandle); 174 return sOverrides.workResolverListController; 175 } 176 177 @Override getPackageManager()178 public PackageManager getPackageManager() { 179 if (sOverrides.createPackageManager != null) { 180 return sOverrides.createPackageManager.apply(super.getPackageManager()); 181 } 182 return super.getPackageManager(); 183 } 184 185 @Override getResources()186 public Resources getResources() { 187 if (sOverrides.resources != null) { 188 return sOverrides.resources; 189 } 190 return super.getResources(); 191 } 192 193 @Override loadThumbnail(Uri uri, Size size)194 protected Bitmap loadThumbnail(Uri uri, Size size) { 195 if (sOverrides.previewThumbnail != null) { 196 return sOverrides.previewThumbnail; 197 } 198 return super.loadThumbnail(uri, size); 199 } 200 201 @Override isImageType(String mimeType)202 protected boolean isImageType(String mimeType) { 203 return sOverrides.isImageType; 204 } 205 206 @Override getMetricsLogger()207 protected MetricsLogger getMetricsLogger() { 208 return sOverrides.metricsLogger; 209 } 210 211 @Override getChooserActivityLogger()212 public ChooserActivityLogger getChooserActivityLogger() { 213 return sOverrides.chooserActivityLogger; 214 } 215 216 @Override queryResolver(ContentResolver resolver, Uri uri)217 public Cursor queryResolver(ContentResolver resolver, Uri uri) { 218 if (sOverrides.resolverCursor != null) { 219 return sOverrides.resolverCursor; 220 } 221 222 if (sOverrides.resolverForceException) { 223 throw new SecurityException("Test exception handling"); 224 } 225 226 return super.queryResolver(resolver, uri); 227 } 228 229 @Override isWorkProfile()230 protected boolean isWorkProfile() { 231 if (sOverrides.alternateProfileSetting != 0) { 232 return sOverrides.alternateProfileSetting == MetricsEvent.MANAGED_PROFILE; 233 } 234 return super.isWorkProfile(); 235 } 236 237 @Override createTestDisplayResolveInfo(Intent originalIntent, ResolveInfo pri, CharSequence pLabel, CharSequence pInfo, Intent replacementIntent, @Nullable ResolveInfoPresentationGetter resolveInfoPresentationGetter)238 public DisplayResolveInfo createTestDisplayResolveInfo(Intent originalIntent, ResolveInfo pri, 239 CharSequence pLabel, CharSequence pInfo, Intent replacementIntent, 240 @Nullable ResolveInfoPresentationGetter resolveInfoPresentationGetter) { 241 return new DisplayResolveInfo(originalIntent, pri, pLabel, pInfo, replacementIntent, 242 resolveInfoPresentationGetter); 243 } 244 245 @Override getWorkProfileUserHandle()246 protected UserHandle getWorkProfileUserHandle() { 247 return sOverrides.workProfileUserHandle; 248 } 249 250 @Override getCurrentUserHandle()251 public UserHandle getCurrentUserHandle() { 252 return mMultiProfilePagerAdapter.getCurrentUserHandle(); 253 } 254 255 @Override createContextAsUser(UserHandle user, int flags)256 public Context createContextAsUser(UserHandle user, int flags) { 257 // return the current context as a work profile doesn't really exist in these tests 258 return getApplicationContext(); 259 } 260 261 @Override queryDirectShareTargets(ChooserListAdapter adapter, boolean skipAppPredictionService)262 protected void queryDirectShareTargets(ChooserListAdapter adapter, 263 boolean skipAppPredictionService) { 264 if (sOverrides.directShareTargets != null) { 265 Pair<Integer, ServiceResultInfo[]> result = 266 sOverrides.directShareTargets.apply(this, adapter); 267 sendShortcutManagerShareTargetResults(result.first, result.second); 268 return; 269 } 270 if (sOverrides.onQueryDirectShareTargets != null) { 271 sOverrides.onQueryDirectShareTargets.apply(adapter); 272 } 273 super.queryDirectShareTargets(adapter, skipAppPredictionService); 274 } 275 276 @Override isQuietModeEnabled(UserHandle userHandle)277 protected boolean isQuietModeEnabled(UserHandle userHandle) { 278 return sOverrides.isQuietModeEnabled; 279 } 280 281 @Override isUserRunning(UserHandle userHandle)282 protected boolean isUserRunning(UserHandle userHandle) { 283 if (userHandle.equals(UserHandle.SYSTEM)) { 284 return super.isUserRunning(userHandle); 285 } 286 return sOverrides.isWorkProfileUserRunning; 287 } 288 289 @Override isUserUnlocked(UserHandle userHandle)290 protected boolean isUserUnlocked(UserHandle userHandle) { 291 if (userHandle.equals(UserHandle.SYSTEM)) { 292 return super.isUserUnlocked(userHandle); 293 } 294 return sOverrides.isWorkProfileUserUnlocked; 295 } 296 } 297