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