Skip using the AppPredictionService if the component is not available

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
This commit is contained in:
Mehdi Alizadeh
2019-08-15 16:31:38 -07:00
parent 37e74a8420
commit a1c18a81af

View 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<>();
@@ -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();