diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 00206fc38d1d4..faeecda7250c8 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -164,6 +164,8 @@ public class ChooserActivity extends ResolverActivity { public static final String LAUNCH_LOCATON_DIRECT_SHARE = "direct_share"; private static final int APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20; public static final String APP_PREDICTION_INTENT_FILTER_KEY = "intent_filter"; + + private boolean mIsAppPredictorComponentAvailable; private AppPredictor mAppPredictor; private AppPredictor.Callback mAppPredictorCallback; private Map mDirectShareAppTargetCache; @@ -617,6 +619,9 @@ public class ChooserActivity extends ResolverActivity { .addTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE, target.getType()) .addTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS, systemCost)); + // This is the only place this value is being set. Effectively final. + mIsAppPredictorComponentAvailable = isAppPredictionServiceAvailable(); + AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled(); if (appPredictor != null) { mDirectShareAppTargetCache = new HashMap<>(); @@ -706,6 +711,32 @@ public class ChooserActivity extends ResolverActivity { } } + /** + * Returns true if app prediction service is defined and the component exists on device. + */ + private boolean isAppPredictionServiceAvailable() { + final String appPredictionServiceName = + getString(R.string.config_defaultAppPredictionService); + if (appPredictionServiceName == null) { + return false; + } + final ComponentName appPredictionComponentName = + ComponentName.unflattenFromString(appPredictionServiceName); + if (appPredictionComponentName == null) { + return false; + } + + // Check if the app prediction component actually exists on the device. + Intent intent = new Intent(); + intent.setComponent(appPredictionComponentName); + if (getPackageManager().resolveService(intent, PackageManager.MATCH_ALL) == null) { + Log.e(TAG, "App prediction service is defined, but does not exist: " + + appPredictionServiceName); + return false; + } + return true; + } + /** * Check if the profile currently used is a work profile. * @return true if it is work profile, false if it is parent profile (or no work profile is @@ -1693,6 +1724,9 @@ public class ChooserActivity extends ResolverActivity { @Nullable private AppPredictor getAppPredictor() { + if (!mIsAppPredictorComponentAvailable) { + return null; + } if (mAppPredictor == null && getPackageManager().getAppPredictionServicePackageName() != null) { final IntentFilter filter = getTargetIntentFilter();