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.intentresolver; 18 19 import android.annotation.Nullable; 20 import android.app.prediction.AppPredictor; 21 import android.app.usage.UsageStatsManager; 22 import android.content.ComponentName; 23 import android.content.ContentResolver; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.content.IntentFilter; 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.net.Uri; 32 import android.os.Bundle; 33 import android.os.UserHandle; 34 35 import androidx.lifecycle.ViewModelProvider; 36 37 import com.android.intentresolver.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; 38 import com.android.intentresolver.chooser.DisplayResolveInfo; 39 import com.android.intentresolver.chooser.TargetInfo; 40 import com.android.intentresolver.flags.FeatureFlagRepository; 41 import com.android.intentresolver.grid.ChooserGridAdapter; 42 import com.android.intentresolver.icons.TargetDataLoader; 43 import com.android.intentresolver.logging.EventLog; 44 import com.android.intentresolver.shortcuts.ShortcutLoader; 45 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 46 47 import java.util.List; 48 import java.util.function.Consumer; 49 50 /** 51 * Simple wrapper around chooser activity to be able to initiate it under test. For more 52 * information, see {@code com.android.internal.app.ChooserWrapperActivity}. 53 */ 54 public class ChooserWrapperActivity 55 extends com.android.intentresolver.ChooserActivity implements IChooserWrapper { 56 static final ChooserActivityOverrideData sOverrides = ChooserActivityOverrideData.getInstance(); 57 private UsageStatsManager mUsm; 58 59 // ResolverActivity (the base class of ChooserActivity) inspects the launched-from UID at 60 // onCreate and needs to see some non-negative value in the test. 61 @Override getLaunchedFromUid()62 public int getLaunchedFromUid() { 63 return 1234; 64 } 65 66 @Override createChooserListAdapter( Context context, List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed, ResolverListController resolverListController, UserHandle userHandle, Intent targetIntent, ChooserRequestParameters chooserRequest, int maxTargetsPerRow, TargetDataLoader targetDataLoader)67 public ChooserListAdapter createChooserListAdapter( 68 Context context, 69 List<Intent> payloadIntents, 70 Intent[] initialIntents, 71 List<ResolveInfo> rList, 72 boolean filterLastUsed, 73 ResolverListController resolverListController, 74 UserHandle userHandle, 75 Intent targetIntent, 76 ChooserRequestParameters chooserRequest, 77 int maxTargetsPerRow, 78 TargetDataLoader targetDataLoader) { 79 PackageManager packageManager = 80 sOverrides.packageManager == null ? context.getPackageManager() 81 : sOverrides.packageManager; 82 return new ChooserListAdapter( 83 context, 84 payloadIntents, 85 initialIntents, 86 rList, 87 filterLastUsed, 88 createListController(userHandle), 89 userHandle, 90 targetIntent, 91 this, 92 packageManager, 93 getEventLog(), 94 chooserRequest, 95 maxTargetsPerRow, 96 userHandle, 97 targetDataLoader); 98 } 99 100 @Override getAdapter()101 public ChooserListAdapter getAdapter() { 102 return mChooserMultiProfilePagerAdapter.getActiveListAdapter(); 103 } 104 105 @Override getPersonalListAdapter()106 public ChooserListAdapter getPersonalListAdapter() { 107 return ((ChooserGridAdapter) mMultiProfilePagerAdapter.getAdapterForIndex(0)) 108 .getListAdapter(); 109 } 110 111 @Override getWorkListAdapter()112 public ChooserListAdapter getWorkListAdapter() { 113 if (mMultiProfilePagerAdapter.getInactiveListAdapter() == null) { 114 return null; 115 } 116 return ((ChooserGridAdapter) mMultiProfilePagerAdapter.getAdapterForIndex(1)) 117 .getListAdapter(); 118 } 119 120 @Override getIsSelected()121 public boolean getIsSelected() { 122 return mIsSuccessfullySelected; 123 } 124 125 @Override getIntegratedDeviceComponents()126 protected ChooserIntegratedDeviceComponents getIntegratedDeviceComponents() { 127 return new ChooserIntegratedDeviceComponents( 128 /* editSharingComponent=*/ null, 129 // An arbitrary pre-installed activity that handles this type of intent: 130 /* nearbySharingComponent=*/ new ComponentName( 131 "com.google.android.apps.messaging", 132 ".ui.conversationlist.ShareIntentActivity")); 133 } 134 135 @Override getUsageStatsManager()136 public UsageStatsManager getUsageStatsManager() { 137 if (mUsm == null) { 138 mUsm = getSystemService(UsageStatsManager.class); 139 } 140 return mUsm; 141 } 142 143 @Override isVoiceInteraction()144 public boolean isVoiceInteraction() { 145 if (sOverrides.isVoiceInteraction != null) { 146 return sOverrides.isVoiceInteraction; 147 } 148 return super.isVoiceInteraction(); 149 } 150 151 @Override createCrossProfileIntentsChecker()152 protected CrossProfileIntentsChecker createCrossProfileIntentsChecker() { 153 if (sOverrides.mCrossProfileIntentsChecker != null) { 154 return sOverrides.mCrossProfileIntentsChecker; 155 } 156 return super.createCrossProfileIntentsChecker(); 157 } 158 159 @Override createWorkProfileAvailabilityManager()160 protected WorkProfileAvailabilityManager createWorkProfileAvailabilityManager() { 161 if (sOverrides.mWorkProfileAvailability != null) { 162 return sOverrides.mWorkProfileAvailability; 163 } 164 return super.createWorkProfileAvailabilityManager(); 165 } 166 167 @Override safelyStartActivityInternal(TargetInfo cti, UserHandle user, @Nullable Bundle options)168 public void safelyStartActivityInternal(TargetInfo cti, UserHandle user, 169 @Nullable Bundle options) { 170 if (sOverrides.onSafelyStartInternalCallback != null 171 && sOverrides.onSafelyStartInternalCallback.apply(cti)) { 172 return; 173 } 174 super.safelyStartActivityInternal(cti, user, options); 175 } 176 177 @Override createListController(UserHandle userHandle)178 protected ChooserListController createListController(UserHandle userHandle) { 179 if (userHandle == UserHandle.SYSTEM) { 180 return sOverrides.resolverListController; 181 } 182 return sOverrides.workResolverListController; 183 } 184 185 @Override getPackageManager()186 public PackageManager getPackageManager() { 187 if (sOverrides.createPackageManager != null) { 188 return sOverrides.createPackageManager.apply(super.getPackageManager()); 189 } 190 return super.getPackageManager(); 191 } 192 193 @Override getResources()194 public Resources getResources() { 195 if (sOverrides.resources != null) { 196 return sOverrides.resources; 197 } 198 return super.getResources(); 199 } 200 201 @Override createPreviewViewModelFactory()202 protected ViewModelProvider.Factory createPreviewViewModelFactory() { 203 return TestContentPreviewViewModel.Companion.wrap( 204 super.createPreviewViewModelFactory(), 205 sOverrides.imageLoader); 206 } 207 208 @Override getEventLog()209 public EventLog getEventLog() { 210 return sOverrides.mEventLog; 211 } 212 213 @Override queryResolver(ContentResolver resolver, Uri uri)214 public Cursor queryResolver(ContentResolver resolver, Uri uri) { 215 if (sOverrides.resolverCursor != null) { 216 return sOverrides.resolverCursor; 217 } 218 219 if (sOverrides.resolverForceException) { 220 throw new SecurityException("Test exception handling"); 221 } 222 223 return super.queryResolver(resolver, uri); 224 } 225 226 @Override isWorkProfile()227 protected boolean isWorkProfile() { 228 if (sOverrides.alternateProfileSetting != 0) { 229 return sOverrides.alternateProfileSetting == MetricsEvent.MANAGED_PROFILE; 230 } 231 return super.isWorkProfile(); 232 } 233 234 @Override createTestDisplayResolveInfo(Intent originalIntent, ResolveInfo pri, CharSequence pLabel, CharSequence pInfo, Intent replacementIntent, @Nullable TargetPresentationGetter resolveInfoPresentationGetter)235 public DisplayResolveInfo createTestDisplayResolveInfo(Intent originalIntent, ResolveInfo pri, 236 CharSequence pLabel, CharSequence pInfo, Intent replacementIntent, 237 @Nullable TargetPresentationGetter resolveInfoPresentationGetter) { 238 return DisplayResolveInfo.newDisplayResolveInfo( 239 originalIntent, 240 pri, 241 pLabel, 242 pInfo, 243 replacementIntent, 244 resolveInfoPresentationGetter); 245 } 246 247 @Override getWorkProfileUserHandle()248 protected UserHandle getWorkProfileUserHandle() { 249 return sOverrides.workProfileUserHandle; 250 } 251 252 @Override getCurrentUserHandle()253 public UserHandle getCurrentUserHandle() { 254 return mMultiProfilePagerAdapter.getCurrentUserHandle(); 255 } 256 257 @Override getTabOwnerUserHandleForLaunch()258 protected UserHandle getTabOwnerUserHandleForLaunch() { 259 if (sOverrides.tabOwnerUserHandleForLaunch == null) { 260 return super.getTabOwnerUserHandleForLaunch(); 261 } 262 return sOverrides.tabOwnerUserHandleForLaunch; 263 } 264 265 @Override createContextAsUser(UserHandle user, int flags)266 public Context createContextAsUser(UserHandle user, int flags) { 267 // return the current context as a work profile doesn't really exist in these tests 268 return getApplicationContext(); 269 } 270 271 @Override createShortcutLoader( Context context, AppPredictor appPredictor, UserHandle userHandle, IntentFilter targetIntentFilter, Consumer<ShortcutLoader.Result> callback)272 protected ShortcutLoader createShortcutLoader( 273 Context context, 274 AppPredictor appPredictor, 275 UserHandle userHandle, 276 IntentFilter targetIntentFilter, 277 Consumer<ShortcutLoader.Result> callback) { 278 ShortcutLoader shortcutLoader = 279 sOverrides.shortcutLoaderFactory.invoke(userHandle, callback); 280 if (shortcutLoader != null) { 281 return shortcutLoader; 282 } 283 return super.createShortcutLoader( 284 context, appPredictor, userHandle, targetIntentFilter, callback); 285 } 286 287 @Override createFeatureFlagRepository()288 protected FeatureFlagRepository createFeatureFlagRepository() { 289 if (sOverrides.featureFlagRepository != null) { 290 return sOverrides.featureFlagRepository; 291 } 292 return super.createFeatureFlagRepository(); 293 } 294 } 295