diff options
8 files changed, 77 insertions, 53 deletions
diff --git a/java/src/com/android/intentresolver/ChooserActivity.java b/java/src/com/android/intentresolver/ChooserActivity.java index b1c7d6fb..82e46a57 100644 --- a/java/src/com/android/intentresolver/ChooserActivity.java +++ b/java/src/com/android/intentresolver/ChooserActivity.java @@ -259,7 +259,8 @@ public class ChooserActivity extends Hilt_ChooserActivity implements new AppPredictorFactory( this, mChooserRequest.getSharedText(), - mChooserRequest.getTargetIntentFilter()), + mChooserRequest.getTargetIntentFilter(), + getPackageManager().getAppPredictionServicePackageName() != null), mChooserRequest.getTargetIntentFilter()); diff --git a/java/src/com/android/intentresolver/shortcuts/AppPredictorFactory.kt b/java/src/com/android/intentresolver/shortcuts/AppPredictorFactory.kt index 82f40b91..e544e064 100644 --- a/java/src/com/android/intentresolver/shortcuts/AppPredictorFactory.kt +++ b/java/src/com/android/intentresolver/shortcuts/AppPredictorFactory.kt @@ -41,16 +41,14 @@ private const val SHARED_TEXT_KEY = "shared_text" class AppPredictorFactory( private val context: Context, private val sharedText: String?, - private val targetIntentFilter: IntentFilter? + private val targetIntentFilter: IntentFilter?, + private val appPredictionAvailable: Boolean, ) { - private val mIsComponentAvailable = - context.packageManager.appPredictionServicePackageName != null - /** * Creates an AppPredictor instance for a profile or `null` if app predictor is not available. */ fun create(userHandle: UserHandle): AppPredictor? { - if (!mIsComponentAvailable) return null + if (!appPredictionAvailable) return null val contextAsUser = context.createContextAsUser(userHandle, 0 /* flags */) val extras = Bundle().apply { putParcelable(APP_PREDICTION_INTENT_FILTER_KEY, targetIntentFilter) diff --git a/java/src/com/android/intentresolver/v2/ChooserActivity.java b/java/src/com/android/intentresolver/v2/ChooserActivity.java index e281613d..54d8b4cb 100644 --- a/java/src/com/android/intentresolver/v2/ChooserActivity.java +++ b/java/src/com/android/intentresolver/v2/ChooserActivity.java @@ -145,6 +145,7 @@ import com.android.intentresolver.v2.emptystate.NoAppsAvailableEmptyStateProvide import com.android.intentresolver.v2.emptystate.NoCrossProfileEmptyStateProvider; import com.android.intentresolver.v2.emptystate.NoCrossProfileEmptyStateProvider.DevicePolicyBlockerEmptyState; import com.android.intentresolver.v2.emptystate.WorkProfilePausedEmptyStateProvider; +import com.android.intentresolver.v2.platform.AppPredictionAvailable; import com.android.intentresolver.v2.platform.ImageEditor; import com.android.intentresolver.v2.platform.NearbyShare; import com.android.intentresolver.v2.ui.ActionTitle; @@ -221,7 +222,6 @@ public class ChooserActivity extends Hilt_ChooserActivity implements protected static final int PROFILE_PERSONAL = MultiProfilePagerAdapter.PROFILE_PERSONAL; protected static final int PROFILE_WORK = MultiProfilePagerAdapter.PROFILE_WORK; private boolean mRegistered; - protected PackageManager mPm; private PackageMonitor mPersonalPackageMonitor; private PackageMonitor mWorkPackageMonitor; protected View mProfileView; @@ -262,11 +262,12 @@ public class ChooserActivity extends Hilt_ChooserActivity implements @Inject public FeatureFlags mFeatureFlags; @Inject public EventLog mEventLog; + @Inject @AppPredictionAvailable public boolean mAppPredictionAvailable; @Inject @ImageEditor public Optional<ComponentName> mImageEditor; @Inject @NearbyShare public Optional<ComponentName> mNearbyShare; @Inject public TargetDataLoader mTargetDataLoader; - @Inject public DevicePolicyResources mDevicePolicyResources; + private ChooserRefinementManager mRefinementManager; private ChooserContentPreviewUi mChooserContentPreviewUi; @@ -356,7 +357,8 @@ public class ChooserActivity extends Hilt_ChooserActivity implements new AppPredictorFactory( this, chooserRequest.getSharedText(), - chooserRequest.getTargetIntentFilter() + chooserRequest.getTargetIntentFilter(), + mAppPredictionAvailable ), chooserRequest.getTargetIntentFilter() ); @@ -371,7 +373,6 @@ public class ChooserActivity extends Hilt_ChooserActivity implements return; } - mPm = getPackageManager(); mChooserMultiProfilePagerAdapter = createMultiProfilePagerAdapter( requireNonNullElse(initialIntents, emptyList()).toArray(new Intent[0]), /* resolutionList = */ null, @@ -2180,7 +2181,7 @@ public class ChooserActivity extends Hilt_ChooserActivity implements return new ChooserListController( this, - mPm, + getPackageManager(), mLogic.getTargetIntent(), mLogic.getReferrerPackageName(), requireAnnotatedUserHandles().userIdOfCallingApp, diff --git a/java/src/com/android/intentresolver/v2/ResolverActivity.java b/java/src/com/android/intentresolver/v2/ResolverActivity.java index a56d15a2..dbc24604 100644 --- a/java/src/com/android/intentresolver/v2/ResolverActivity.java +++ b/java/src/com/android/intentresolver/v2/ResolverActivity.java @@ -151,7 +151,6 @@ public class ResolverActivity extends Hilt_ResolverActivity implements private PickTargetOptionRequest mPickOptionRequest; // Expected to be true if this object is ResolverActivity or is ResolverWrapperActivity. protected ResolverDrawerLayout mResolverDrawerLayout; - protected PackageManager mPm; private static final String TAG = "ResolverActivity"; private static final boolean DEBUG = false; @@ -257,7 +256,6 @@ public class ResolverActivity extends Hilt_ResolverActivity implements return; } - mPm = getPackageManager(); // The last argument of createResolverListAdapter is whether to do special handling // of the last used choice to highlight it in the list. We need to always @@ -755,7 +753,7 @@ public class ResolverActivity extends Hilt_ResolverActivity implements null); return new ResolverListController( this, - mPm, + getPackageManager(), mLogic.getTargetIntent(), mLogic.getReferrerPackageName(), requireAnnotatedUserHandles().userIdOfCallingApp, @@ -1239,8 +1237,8 @@ public class ResolverActivity extends Hilt_ResolverActivity implements if (ri != null) { ActivityInfo activityInfo = ri.activityInfo; - boolean hasRecordPermission = - mPm.checkPermission(android.Manifest.permission.RECORD_AUDIO, + boolean hasRecordPermission = getPackageManager() + .checkPermission(android.Manifest.permission.RECORD_AUDIO, activityInfo.packageName) == PackageManager.PERMISSION_GRANTED; diff --git a/java/src/com/android/intentresolver/v2/platform/AppPredictionModule.kt b/java/src/com/android/intentresolver/v2/platform/AppPredictionModule.kt new file mode 100644 index 00000000..9ca9d871 --- /dev/null +++ b/java/src/com/android/intentresolver/v2/platform/AppPredictionModule.kt @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.intentresolver.v2.platform + +import android.content.pm.PackageManager +import dagger.Module +import dagger.Provides +import dagger.Reusable +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Qualifier +import javax.inject.Singleton + +@Qualifier +@MustBeDocumented +@Retention(AnnotationRetention.RUNTIME) +annotation class AppPredictionAvailable + +@Module +@InstallIn(SingletonComponent::class) +object AppPredictionModule { + + /** + * Eventually replaced with: Optional<AppPredictionRepository>, etc. + */ + @Provides + @Singleton + @AppPredictionAvailable + fun isAppPredictionAvailable(packageManager: PackageManager): Boolean { + return packageManager.appPredictionServicePackageName != null + } +}
\ No newline at end of file diff --git a/tests/activity/src/com/android/intentresolver/v2/ChooserActivityOverrideData.java b/tests/activity/src/com/android/intentresolver/v2/ChooserActivityOverrideData.java index 32eabbed..c84c25e3 100644 --- a/tests/activity/src/com/android/intentresolver/v2/ChooserActivityOverrideData.java +++ b/tests/activity/src/com/android/intentresolver/v2/ChooserActivityOverrideData.java @@ -52,9 +52,6 @@ public class ChooserActivityOverrideData { } return sInstance; } - - @SuppressWarnings("Since15") - public Function<PackageManager, PackageManager> createPackageManager; public Function<TargetInfo, Boolean> onSafelyStartInternalCallback; public Function<TargetInfo, Boolean> onSafelyStartCallback; public Function2<UserHandle, Consumer<ShortcutLoader.Result>, ShortcutLoader> @@ -78,7 +75,6 @@ public class ChooserActivityOverrideData { public void reset() { onSafelyStartInternalCallback = null; isVoiceInteraction = null; - createPackageManager = null; imageLoader = null; resolverCursor = null; resolverForceException = false; diff --git a/tests/activity/src/com/android/intentresolver/v2/ChooserWrapperActivity.java b/tests/activity/src/com/android/intentresolver/v2/ChooserWrapperActivity.java index 8da045dc..cc14202f 100644 --- a/tests/activity/src/com/android/intentresolver/v2/ChooserWrapperActivity.java +++ b/tests/activity/src/com/android/intentresolver/v2/ChooserWrapperActivity.java @@ -172,14 +172,6 @@ public class ChooserWrapperActivity extends ChooserActivity implements IChooserW } @Override - public PackageManager getPackageManager() { - if (sOverrides.createPackageManager != null) { - return sOverrides.createPackageManager.apply(super.getPackageManager()); - } - return super.getPackageManager(); - } - - @Override public Resources getResources() { if (sOverrides.resources != null) { return sOverrides.resources; diff --git a/tests/activity/src/com/android/intentresolver/v2/UnbundledChooserActivityTest.java b/tests/activity/src/com/android/intentresolver/v2/UnbundledChooserActivityTest.java index 5245f655..770cabbc 100644 --- a/tests/activity/src/com/android/intentresolver/v2/UnbundledChooserActivityTest.java +++ b/tests/activity/src/com/android/intentresolver/v2/UnbundledChooserActivityTest.java @@ -131,6 +131,8 @@ import com.android.intentresolver.contentpreview.ImageLoader; import com.android.intentresolver.logging.EventLog; import com.android.intentresolver.logging.FakeEventLog; import com.android.intentresolver.shortcuts.ShortcutLoader; +import com.android.intentresolver.v2.platform.AppPredictionAvailable; +import com.android.intentresolver.v2.platform.AppPredictionModule; import com.android.intentresolver.v2.platform.ImageEditor; import com.android.intentresolver.v2.platform.ImageEditorModule; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; @@ -150,12 +152,12 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -165,16 +167,16 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; -import java.util.function.Function; /** * Instrumentation tests for ChooserActivity. * <p> * Legacy test suite migrated from framework CoreTests. */ +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") @RunWith(Parameterized.class) @HiltAndroidTest -@UninstallModules(ImageEditorModule.class) +@UninstallModules({ImageEditorModule.class, AppPredictionModule.class}) public class UnbundledChooserActivityTest { private static FakeEventLog getEventLog(ChooserWrapperActivity activity) { @@ -186,22 +188,12 @@ public class UnbundledChooserActivityTest { private static final UserHandle WORK_PROFILE_USER_HANDLE = UserHandle.of(10); private static final UserHandle CLONE_PROFILE_USER_HANDLE = UserHandle.of(11); - private static final Function<PackageManager, PackageManager> DEFAULT_PM = pm -> pm; - private static final Function<PackageManager, PackageManager> NO_APP_PREDICTION_SERVICE_PM = - pm -> { - PackageManager mock = Mockito.spy(pm); - when(mock.getAppPredictionServicePackageName()).thenReturn(null); - return mock; - }; - - @Parameterized.Parameters - public static Collection packageManagers() { - return Arrays.asList(new Object[][] { - // Default PackageManager - { DEFAULT_PM }, - // No App Prediction Service - { NO_APP_PREDICTION_SERVICE_PM} - }); + @Parameters(name = "appPrediction={0}") + public static Iterable<?> parameters() { + return Arrays.asList( + /* appPredictionAvailable = */ true, + /* appPredictionAvailable = */ false + ); } private static final String TEST_MIME_TYPE = "application/TestType"; @@ -233,8 +225,6 @@ public class UnbundledChooserActivityTest { mHiltAndroidRule.inject(); } - private final Function<PackageManager, PackageManager> mPackageManagerOverride; - /** An arbitrary pre-installed activity that handles this type of intent. */ @BindValue @ImageEditor @@ -242,9 +232,13 @@ public class UnbundledChooserActivityTest { ComponentName.unflattenFromString("com.google.android.apps.messaging/" + ".ui.conversationlist.ShareIntentActivity")); - public UnbundledChooserActivityTest( - Function<PackageManager, PackageManager> packageManagerOverride) { - mPackageManagerOverride = packageManagerOverride; + /** Whether an AppPredictionService is available for use. */ + @BindValue + @AppPredictionAvailable + final boolean mAppPredictionAvailable; + + public UnbundledChooserActivityTest(boolean appPredictionAvailable) { + mAppPredictionAvailable = appPredictionAvailable; } private void setDeviceConfigProperty( @@ -267,7 +261,6 @@ public class UnbundledChooserActivityTest { public void cleanOverrideData() { ChooserActivityOverrideData.getInstance().reset(); - ChooserActivityOverrideData.getInstance().createPackageManager = mPackageManagerOverride; setDeviceConfigProperty( SystemUiDeviceConfigFlags.APPLY_SHARING_APP_LIMITS_IN_SYSUI, |