OSDN Git Service

Skip using the AppPredictionService if the component is not available
authorMehdi Alizadeh <mett@google.com>
Thu, 15 Aug 2019 23:31:38 +0000 (16:31 -0700)
committerMehdi Alizadeh <mett@google.com>
Fri, 16 Aug 2019 23:57:46 +0000 (23:57 +0000)
This CL adds a safeguard in ShareSheet to avoid calls to
AppPredictionService when the service is defined but is not available,
for example in the case of a wrong AiAi apk pushed from GooglePlay.

Bug: 138595943
Test: Manual test by removing the AiAi package from device

Change-Id: I4109c5122faa753d5111ee45698301cb6ccdd7b5

core/java/com/android/internal/app/ChooserActivity.java

index 00206fc..faeecda 100644 (file)
@@ -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<ChooserTarget, AppTarget> 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<>();
@@ -707,6 +712,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
      * set up)
@@ -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();