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 static org.mockito.ArgumentMatchers.any; 20 import static org.mockito.ArgumentMatchers.anyInt; 21 import static org.mockito.Mockito.mock; 22 import static org.mockito.Mockito.when; 23 24 import android.annotation.Nullable; 25 import android.app.usage.UsageStatsManager; 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.os.Bundle; 31 import android.os.UserHandle; 32 import android.util.Pair; 33 34 import com.android.internal.app.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker; 35 import com.android.internal.app.AbstractMultiProfilePagerAdapter.QuietModeManager; 36 import com.android.internal.app.chooser.TargetInfo; 37 38 import java.util.List; 39 import java.util.function.Function; 40 41 /* 42 * Simple wrapper around chooser activity to be able to initiate it under test 43 */ 44 public class ResolverWrapperActivity extends ResolverActivity { 45 static final OverrideData sOverrides = new OverrideData(); 46 private UsageStatsManager mUsm; 47 ResolverWrapperActivity()48 public ResolverWrapperActivity() { 49 super(/* isIntentPicker= */ true); 50 } 51 52 @Override createResolverListAdapter(Context context, List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed, UserHandle userHandle)53 public ResolverListAdapter createResolverListAdapter(Context context, 54 List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, 55 boolean filterLastUsed, UserHandle userHandle) { 56 return new ResolverWrapperAdapter(context, payloadIntents, initialIntents, rList, 57 filterLastUsed, createListController(userHandle), this, userHandle); 58 } 59 60 @Override createCrossProfileIntentsChecker()61 protected CrossProfileIntentsChecker createCrossProfileIntentsChecker() { 62 if (sOverrides.mCrossProfileIntentsChecker != null) { 63 return sOverrides.mCrossProfileIntentsChecker; 64 } 65 return super.createCrossProfileIntentsChecker(); 66 } 67 68 @Override createQuietModeManager()69 protected QuietModeManager createQuietModeManager() { 70 if (sOverrides.mQuietModeManager != null) { 71 return sOverrides.mQuietModeManager; 72 } 73 return super.createQuietModeManager(); 74 } 75 getAdapter()76 ResolverWrapperAdapter getAdapter() { 77 return (ResolverWrapperAdapter) mMultiProfilePagerAdapter.getActiveListAdapter(); 78 } 79 getPersonalListAdapter()80 ResolverListAdapter getPersonalListAdapter() { 81 return ((ResolverListAdapter) mMultiProfilePagerAdapter.getAdapterForIndex(0)); 82 } 83 getWorkListAdapter()84 ResolverListAdapter getWorkListAdapter() { 85 if (mMultiProfilePagerAdapter.getInactiveListAdapter() == null) { 86 return null; 87 } 88 return ((ResolverListAdapter) mMultiProfilePagerAdapter.getAdapterForIndex(1)); 89 } 90 getMultiProfilePagerAdapterCount()91 int getMultiProfilePagerAdapterCount(){ 92 return mMultiProfilePagerAdapter.getCount(); 93 } 94 95 @Override isVoiceInteraction()96 public boolean isVoiceInteraction() { 97 if (sOverrides.isVoiceInteraction != null) { 98 return sOverrides.isVoiceInteraction; 99 } 100 return super.isVoiceInteraction(); 101 } 102 103 @Override safelyStartActivityInternal(TargetInfo cti, UserHandle user, @Nullable Bundle options)104 public void safelyStartActivityInternal(TargetInfo cti, UserHandle user, 105 @Nullable Bundle options) { 106 if (sOverrides.onSafelyStartInternalCallback != null 107 && sOverrides.onSafelyStartInternalCallback.apply(new Pair<>(cti, user))) { 108 return; 109 } 110 super.safelyStartActivityInternal(cti, user, options); 111 } 112 113 @Override createListController(UserHandle userHandle)114 protected ResolverListController createListController(UserHandle userHandle) { 115 if (userHandle == UserHandle.SYSTEM) { 116 when(sOverrides.resolverListController.getUserHandle()).thenReturn(UserHandle.SYSTEM); 117 return sOverrides.resolverListController; 118 } 119 if (isLaunchedInSingleUserMode()) { 120 when(sOverrides.resolverListController.getUserHandle()).thenReturn(userHandle); 121 return sOverrides.resolverListController; 122 } 123 when(sOverrides.workResolverListController.getUserHandle()).thenReturn(userHandle); 124 return sOverrides.workResolverListController; 125 } 126 127 @Override getPackageManager()128 public PackageManager getPackageManager() { 129 if (sOverrides.createPackageManager != null) { 130 return sOverrides.createPackageManager.apply(super.getPackageManager()); 131 } 132 return super.getPackageManager(); 133 } 134 getCurrentUserHandle()135 protected UserHandle getCurrentUserHandle() { 136 return mMultiProfilePagerAdapter.getCurrentUserHandle(); 137 } 138 139 @Override getPersonalProfileUserHandle()140 protected UserHandle getPersonalProfileUserHandle() { 141 return super.getPersonalProfileUserHandle(); 142 } 143 144 @Override getWorkProfileUserHandle()145 protected UserHandle getWorkProfileUserHandle() { 146 return sOverrides.workProfileUserHandle; 147 } 148 149 @Override getCloneProfileUserHandle()150 protected UserHandle getCloneProfileUserHandle() { 151 return sOverrides.cloneProfileUserHandle; 152 } 153 154 @Override getPrivateProfileUserHandle()155 protected UserHandle getPrivateProfileUserHandle() { 156 return sOverrides.privateProfileUserHandle; 157 } 158 159 @Override getTabOwnerUserHandleForLaunch()160 protected UserHandle getTabOwnerUserHandleForLaunch() { 161 if (sOverrides.tabOwnerUserHandleForLaunch == null) { 162 return super.getTabOwnerUserHandleForLaunch(); 163 } 164 return sOverrides.tabOwnerUserHandleForLaunch; 165 } 166 167 @Override startActivityAsUser(Intent intent, Bundle options, UserHandle user)168 public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) { 169 super.startActivityAsUser(intent, options, user); 170 } 171 172 @Override getResolverRankerServiceUserHandleListInternal(UserHandle userHandle)173 protected List<UserHandle> getResolverRankerServiceUserHandleListInternal(UserHandle 174 userHandle) { 175 return super.getResolverRankerServiceUserHandleListInternal(userHandle); 176 } 177 178 /** 179 * We cannot directly mock the activity created since instrumentation creates it. 180 * <p> 181 * Instead, we use static instances of this object to modify behavior. 182 */ 183 static class OverrideData { 184 @SuppressWarnings("Since15") 185 public Function<PackageManager, PackageManager> createPackageManager; 186 public Function<Pair<TargetInfo, UserHandle>, Boolean> onSafelyStartInternalCallback; 187 public ResolverListController resolverListController; 188 public ResolverListController workResolverListController; 189 public Boolean isVoiceInteraction; 190 public UserHandle workProfileUserHandle; 191 public UserHandle cloneProfileUserHandle; 192 public UserHandle privateProfileUserHandle; 193 public UserHandle tabOwnerUserHandleForLaunch; 194 public Integer myUserId; 195 public boolean hasCrossProfileIntents; 196 public boolean isQuietModeEnabled; 197 public QuietModeManager mQuietModeManager; 198 public CrossProfileIntentsChecker mCrossProfileIntentsChecker; 199 reset()200 public void reset() { 201 onSafelyStartInternalCallback = null; 202 isVoiceInteraction = null; 203 createPackageManager = null; 204 resolverListController = mock(ResolverListController.class); 205 workResolverListController = mock(ResolverListController.class); 206 workProfileUserHandle = null; 207 cloneProfileUserHandle = null; 208 privateProfileUserHandle = null; 209 tabOwnerUserHandleForLaunch = null; 210 myUserId = null; 211 hasCrossProfileIntents = true; 212 isQuietModeEnabled = false; 213 214 mQuietModeManager = new QuietModeManager() { 215 @Override 216 public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { 217 return isQuietModeEnabled; 218 } 219 220 @Override 221 public void requestQuietModeEnabled(boolean enabled, 222 UserHandle workProfileUserHandle) { 223 isQuietModeEnabled = enabled; 224 } 225 226 @Override 227 public void markWorkProfileEnabledBroadcastReceived() { 228 } 229 230 @Override 231 public boolean isWaitingToEnableWorkProfile() { 232 return false; 233 } 234 }; 235 236 mCrossProfileIntentsChecker = mock(CrossProfileIntentsChecker.class); 237 when(mCrossProfileIntentsChecker.hasCrossProfileIntents(any(), anyInt(), anyInt())) 238 .thenAnswer(invocation -> hasCrossProfileIntents); 239 } 240 } 241 } 242