diff options
| -rw-r--r-- | core/java/com/android/internal/app/ChooserActivity.java | 83 | ||||
| -rw-r--r-- | core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java | 35 |
2 files changed, 90 insertions, 28 deletions
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 4d4fe0397791..b8ac6dc96db9 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -24,6 +24,7 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.IntDef; +import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityManager; import android.app.prediction.AppPredictionContext; @@ -131,6 +132,7 @@ import java.util.List; public class ChooserActivity extends ResolverActivity { private static final String TAG = "ChooserActivity"; + /** * Boolean extra to change the following behavior: Normally, ChooserActivity finishes itself * in onStop when launched in a new task. If this extra is set to true, we do not finish @@ -141,7 +143,6 @@ public class ChooserActivity extends ResolverActivity { private static final boolean DEBUG = false; - /** * If {@link #USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS} and this is set to true, * {@link AppPredictionManager} will be queried for direct share targets. @@ -433,18 +434,8 @@ public class ChooserActivity extends ResolverActivity { .addTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE, target.getType()) .addTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS, systemCost)); - if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { - final IntentFilter filter = getTargetIntentFilter(); - Bundle extras = new Bundle(); - extras.putParcelable(APP_PREDICTION_INTENT_FILTER_KEY, filter); - AppPredictionManager appPredictionManager = - getSystemService(AppPredictionManager.class); - mAppPredictor = appPredictionManager.createAppPredictionSession( - new AppPredictionContext.Builder(this) - .setPredictedTargetCount(APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT) - .setUiSurface(APP_PREDICTION_SHARE_UI_SURFACE) - .setExtras(extras) - .build()); + AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled(); + if (appPredictor != null) { mAppPredictorCallback = resultList -> { if (isFinishing() || isDestroyed()) { return; @@ -467,8 +458,10 @@ public class ChooserActivity extends ResolverActivity { appTarget.getPackageName(), appTarget.getClassName()))); } sendShareShortcutInfoList(shareShortcutInfos, driList); + sendShortcutManagerShareTargetResultCompleted(); }; - mAppPredictor.registerPredictionUpdates(this.getMainExecutor(), mAppPredictorCallback); + appPredictor + .registerPredictionUpdates(this.getMainExecutor(), mAppPredictorCallback); } mChooserRowLayer = getResources().getDrawable(R.drawable.chooser_row_layer_list, null); @@ -872,7 +865,7 @@ public class ChooserActivity extends ResolverActivity { mChooserHandler.removeMessages(LIST_VIEW_UPDATE_MESSAGE); mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT); - if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { + if (mAppPredictor != null) { mAppPredictor.unregisterPredictionUpdates(mAppPredictorCallback); mAppPredictor.destroy(); } @@ -1205,10 +1198,12 @@ public class ChooserActivity extends ResolverActivity { } private void queryDirectShareTargets(ChooserListAdapter adapter) { - if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { - mAppPredictor.requestPredictionUpdate(); + AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled(); + if (appPredictor != null) { + appPredictor.requestPredictionUpdate(); return; } + // Default to just querying ShortcutManager if AppPredictor not present. final IntentFilter filter = getTargetIntentFilter(); if (filter == null) { return; @@ -1248,12 +1243,16 @@ public class ChooserActivity extends ResolverActivity { } if (resultMessageSent) { - final Message msg = Message.obtain(); - msg.what = SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED; - mChooserHandler.sendMessage(msg); + sendShortcutManagerShareTargetResultCompleted(); } } + private void sendShortcutManagerShareTargetResultCompleted() { + final Message msg = Message.obtain(); + msg.what = SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED; + mChooserHandler.sendMessage(msg); + } + private ChooserTarget convertToChooserTarget(ShortcutManager.ShareShortcutInfo shareShortcut) { ShortcutInfo shortcutInfo = shareShortcut.getShortcutInfo(); Bundle extras = new Bundle(); @@ -1309,9 +1308,7 @@ public class ChooserActivity extends ResolverActivity { void updateModelAndChooserCounts(TargetInfo info) { if (info != null) { - if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { - sendClickToAppPredictor(info); - } + sendClickToAppPredictor(info); final ResolveInfo ri = info.getResolveInfo(); Intent targetIntent = getTargetIntent(); if (ri != null && ri.activityInfo != null && targetIntent != null) { @@ -1332,6 +1329,10 @@ public class ChooserActivity extends ResolverActivity { } private void sendClickToAppPredictor(TargetInfo targetInfo) { + AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled(); + if (appPredictor == null) { + return; + } if (!(targetInfo instanceof ChooserTargetInfo)) { return; } @@ -1345,8 +1346,9 @@ public class ChooserActivity extends ResolverActivity { if (shortcutId == null) { return; } - mAppPredictor.notifyAppTargetEvent( + appPredictor.notifyAppTargetEvent( new AppTargetEvent.Builder( + // TODO(b/124404997) Send full shortcut info, not just Id with AppTargetId. new AppTarget.Builder(new AppTargetId(shortcutId)) .setTarget(componentName.getPackageName(), getUser()) .setClassName(componentName.getClassName()) @@ -1356,6 +1358,34 @@ public class ChooserActivity extends ResolverActivity { .build()); } + @Nullable + private AppPredictor getAppPredictor() { + if (mAppPredictor == null + && getPackageManager().getAppPredictionServicePackageName() != null) { + final IntentFilter filter = getTargetIntentFilter(); + Bundle extras = new Bundle(); + extras.putParcelable(APP_PREDICTION_INTENT_FILTER_KEY, filter); + AppPredictionContext appPredictionContext = new AppPredictionContext.Builder(this) + .setUiSurface(APP_PREDICTION_SHARE_UI_SURFACE) + .setPredictedTargetCount(APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT) + .setExtras(extras) + .build(); + AppPredictionManager appPredictionManager + = getSystemService(AppPredictionManager.class); + mAppPredictor = appPredictionManager.createAppPredictionSession(appPredictionContext); + } + return mAppPredictor; + } + + /** + * This will return an app predictor if it is enabled for direct share sorting + * and if one exists. Otherwise, it returns null. + */ + @Nullable + private AppPredictor getAppPredictorForDirectShareIfEnabled() { + return USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS ? getAppPredictor() : null; + } + void onRefinementResult(TargetInfo selectedTarget, Intent matchingIntent) { if (mRefinementResultReceiver != null) { mRefinementResultReceiver.destroy(); @@ -2014,7 +2044,8 @@ public class ChooserActivity extends ResolverActivity { } } - if (USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS) { + if (USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS + || USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { if (DEBUG) { Log.d(TAG, "querying direct share targets from ShortcutManager"); } @@ -2242,7 +2273,7 @@ public class ChooserActivity extends ResolverActivity { return CALLER_TARGET_SCORE_BOOST; } - if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { + if (getAppPredictorForDirectShareIfEnabled() != null) { return SHORTCUT_TARGET_SCORE_BOOST; } diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java index 00b4a225c55f..ac039dddb66c 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java @@ -42,6 +42,7 @@ import android.content.ClipboardManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.database.Cursor; import android.graphics.Bitmap; @@ -53,7 +54,6 @@ import android.metrics.LogMaker; import android.net.Uri; import android.service.chooser.ChooserTarget; -import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; @@ -62,10 +62,14 @@ import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import java.util.Arrays; +import java.util.Collection; +import java.util.function.Function; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; @@ -75,21 +79,48 @@ import java.util.List; /** * Chooser activity instrumentation tests */ -@RunWith(AndroidJUnit4.class) +@RunWith(Parameterized.class) public class ChooserActivityTest { + 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[][] { + {0, "Default PackageManager", DEFAULT_PM}, + {1, "No App Prediction Service", NO_APP_PREDICTION_SERVICE_PM} + }); + } + private static final int CONTENT_PREVIEW_IMAGE = 1; private static final int CONTENT_PREVIEW_FILE = 2; private static final int CONTENT_PREVIEW_TEXT = 3; + private Function<PackageManager, PackageManager> mPackageManagerOverride; + private int mTestNum; @Rule public ActivityTestRule<ChooserWrapperActivity> mActivityRule = new ActivityTestRule<>(ChooserWrapperActivity.class, false, false); + public ChooserActivityTest( + int testNum, + String testName, + Function<PackageManager, PackageManager> packageManagerOverride) { + mPackageManagerOverride = packageManagerOverride; + mTestNum = testNum; + } + @Before public void cleanOverrideData() { sOverrides.reset(); + sOverrides.createPackageManager = mPackageManagerOverride; } @Test |