summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java83
-rw-r--r--core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java35
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