summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2020-01-24 23:50:28 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-01-24 23:50:28 +0000
commitf82fd3dc815ac45248dab5ea53293d2dae45377a (patch)
tree211bec996a44dbe89d1cd7bacc268f24dfafa248 /core/java
parentb359190aeab1ae0afca9eeda352a2e93a95922b8 (diff)
parent5fc9e7ddeee16b6c43c88278ee8801ea52d64171 (diff)
Merge "Make direct share work with the work profile tab."
Diffstat (limited to 'core/java')
-rw-r--r--core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java24
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java276
-rw-r--r--core/java/com/android/internal/app/ChooserListAdapter.java39
-rw-r--r--core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java13
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java3
-rw-r--r--core/java/com/android/internal/app/ResolverListAdapter.java7
-rw-r--r--core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java13
-rw-r--r--core/java/com/android/internal/app/chooser/SelectableTargetInfo.java34
8 files changed, 274 insertions, 135 deletions
diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
index b2aa0431251d..77d8e0290f20 100644
--- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
@@ -156,14 +156,32 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
@VisibleForTesting
public abstract Object getAdapterForIndex(int pageIndex);
+ /**
+ * Returns the {@link ResolverListAdapter} instance of the profile that represents
+ * <code>userHandle</code>. If there is no such adapter for the specified
+ * <code>userHandle</code>, returns {@code null}.
+ * <p>For example, if there is a work profile on the device with user id 10, calling this method
+ * with <code>UserHandle.of(10)</code> returns the work profile {@link ResolverListAdapter}.
+ */
+ @Nullable
+ abstract ResolverListAdapter getListAdapterForUserHandle(UserHandle userHandle);
+
+ /**
+ * Returns the {@link ResolverListAdapter} instance of the profile that is currently visible
+ * to the user.
+ * <p>For example, if the user is viewing the work tab in the share sheet, this method returns
+ * the work profile {@link ResolverListAdapter}.
+ * @see #getInactiveListAdapter()
+ */
@VisibleForTesting
public abstract ResolverListAdapter getActiveListAdapter();
/**
* If this is a device with a work profile, returns the {@link ResolverListAdapter} instance
- * of the profile that is not the active one. Otherwise returns {@code null}. For example,
- * if the share sheet is launched in the work profile, this method returns the personal
- * profile {@link ResolverListAdapter}.
+ * of the profile that is <b><i>not</i></b> currently visible to the user. Otherwise returns
+ * {@code null}.
+ * <p>For example, if the user is viewing the work tab in the share sheet, this method returns
+ * the personal profile {@link ResolverListAdapter}.
* @see #getActiveListAdapter()
*/
@VisibleForTesting
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 8bbc343fa4ca..65128e4a2eda 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -72,7 +72,6 @@ import android.os.IBinder;
import android.os.Message;
import android.os.Parcelable;
import android.os.PatternMatcher;
-import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.UserHandle;
@@ -90,6 +89,7 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.HashedStringCache;
import android.util.Log;
+import android.util.Pair;
import android.util.Size;
import android.util.Slog;
import android.view.LayoutInflater;
@@ -150,6 +150,8 @@ public class ChooserActivity extends ResolverActivity implements
ChooserListAdapter.ChooserListCommunicator,
SelectableTargetInfoCommunicator {
private static final String TAG = "ChooserActivity";
+ private AppPredictor mPersonalAppPredictor;
+ private AppPredictor mWorkAppPredictor;
@UnsupportedAppUsage
public ChooserActivity() {
@@ -164,7 +166,7 @@ public class ChooserActivity extends ResolverActivity implements
private static final String PREF_NUM_SHEET_EXPANSIONS = "pref_num_sheet_expansions";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true;
private static final boolean USE_PREDICTION_MANAGER_FOR_SHARE_ACTIVITIES = true;
// TODO(b/123088566) Share these in a better way.
@@ -177,9 +179,8 @@ public class ChooserActivity extends ResolverActivity implements
public static final int LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS = 250;
private boolean mIsAppPredictorComponentAvailable;
- private AppPredictor mAppPredictor;
- private AppPredictor.Callback mAppPredictorCallback;
private Map<ChooserTarget, AppTarget> mDirectShareAppTargetCache;
+ private Map<ChooserTarget, ShortcutInfo> mDirectShareShortcutInfoCache;
public static final int TARGET_TYPE_DEFAULT = 0;
public static final int TARGET_TYPE_CHOOSER_TARGET = 1;
@@ -239,7 +240,7 @@ public class ChooserActivity extends ResolverActivity implements
private static final int MAX_RANKED_TARGETS = 4;
private final List<ChooserTargetServiceConnection> mServiceConnections = new ArrayList<>();
- private final Set<ComponentName> mServicesRequested = new HashSet<>();
+ private final Set<Pair<ComponentName, UserHandle>> mServicesRequested = new HashSet<>();
private static final int MAX_LOG_RANK_POSITION = 12;
@@ -422,6 +423,7 @@ public class ChooserActivity extends ResolverActivity implements
WATCHDOG_TIMEOUT_MIN_MILLIS);
sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT,
WATCHDOG_TIMEOUT_MAX_MILLIS);
+
}
private void maybeStopServiceRequestTimer() {
@@ -454,10 +456,14 @@ public class ChooserActivity extends ResolverActivity implements
break;
}
if (sri.resultTargets != null) {
- // TODO(arangelov): Instead of using getCurrentListAdapter(), pass the
- // profileId as part of the message.
- mChooserMultiProfilePagerAdapter.getActiveListAdapter().addServiceResults(
- sri.originalTarget, sri.resultTargets, TARGET_TYPE_CHOOSER_TARGET);
+ ChooserListAdapter adapterForUserHandle =
+ mChooserMultiProfilePagerAdapter.getListAdapterForUserHandle(
+ sri.userHandle);
+ if (adapterForUserHandle != null) {
+ adapterForUserHandle.addServiceResults(sri.originalTarget,
+ sri.resultTargets, TARGET_TYPE_CHOOSER_TARGET,
+ /* directShareShortcutInfoCache */ null);
+ }
}
unbindService(sri.connection);
sri.connection.destroy();
@@ -480,15 +486,23 @@ public class ChooserActivity extends ResolverActivity implements
Log.d(TAG, "LIST_VIEW_UPDATE_MESSAGE; ");
}
- mChooserMultiProfilePagerAdapter.getActiveListAdapter().refreshListView();
+ UserHandle userHandle = (UserHandle) msg.obj;
+ mChooserMultiProfilePagerAdapter.getListAdapterForUserHandle(userHandle)
+ .refreshListView();
break;
case SHORTCUT_MANAGER_SHARE_TARGET_RESULT:
if (DEBUG) Log.d(TAG, "SHORTCUT_MANAGER_SHARE_TARGET_RESULT");
final ServiceResultInfo resultInfo = (ServiceResultInfo) msg.obj;
if (resultInfo.resultTargets != null) {
- mChooserMultiProfilePagerAdapter.getActiveListAdapter().addServiceResults(
- resultInfo.originalTarget, resultInfo.resultTargets, msg.arg1);
+ ChooserListAdapter adapterForUserHandle =
+ mChooserMultiProfilePagerAdapter.getListAdapterForUserHandle(
+ resultInfo.userHandle);
+ if (adapterForUserHandle != null) {
+ adapterForUserHandle.addServiceResults(
+ resultInfo.originalTarget, resultInfo.resultTargets, msg.arg1,
+ mDirectShareShortcutInfoCache);
+ }
}
break;
@@ -638,45 +652,6 @@ public class ChooserActivity extends ResolverActivity implements
.addTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE, target.getType())
.addTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS, systemCost));
- AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled();
- if (appPredictor != null) {
- mDirectShareAppTargetCache = new HashMap<>();
- mAppPredictorCallback = resultList -> {
- //TODO(arangelov) Take care of edge case when callback called after swiping tabs
- if (isFinishing() || isDestroyed()) {
- return;
- }
- if (mChooserMultiProfilePagerAdapter.getActiveListAdapter().getCount() == 0) {
- return;
- }
- if (resultList.isEmpty()) {
- // APS may be disabled, so try querying targets ourselves.
- //TODO(arangelov) queryDirectShareTargets indirectly uses mIntents.
- // Investigate implications for work tab.
- queryDirectShareTargets(
- mChooserMultiProfilePagerAdapter.getActiveListAdapter(), true);
- return;
- }
- final List<DisplayResolveInfo> driList =
- getDisplayResolveInfos(
- mChooserMultiProfilePagerAdapter.getActiveListAdapter());
- final List<ShortcutManager.ShareShortcutInfo> shareShortcutInfos =
- new ArrayList<>();
- for (AppTarget appTarget : resultList) {
- if (appTarget.getShortcutInfo() == null) {
- continue;
- }
- shareShortcutInfos.add(new ShortcutManager.ShareShortcutInfo(
- appTarget.getShortcutInfo(),
- new ComponentName(
- appTarget.getPackageName(), appTarget.getClassName())));
- }
- sendShareShortcutInfoList(shareShortcutInfos, driList, resultList);
- };
- appPredictor
- .registerPredictionUpdates(this.getMainExecutor(), mAppPredictorCallback);
- }
-
mChooserRowServiceSpacing = getResources()
.getDimensionPixelSize(R.dimen.chooser_service_spacing);
@@ -707,6 +682,54 @@ public class ChooserActivity extends ResolverActivity implements
if (DEBUG) {
Log.d(TAG, "System Time Cost is " + systemCost);
}
+
+ mDirectShareShortcutInfoCache = new HashMap<>();
+ }
+
+ private AppPredictor setupAppPredictorForUser(UserHandle userHandle,
+ AppPredictor.Callback appPredictorCallback) {
+ AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled(userHandle);
+ if (appPredictor == null) {
+ return null;
+ }
+ mDirectShareAppTargetCache = new HashMap<>();
+ appPredictor.registerPredictionUpdates(this.getMainExecutor(), appPredictorCallback);
+ return appPredictor;
+ }
+
+ private AppPredictor.Callback createAppPredictorCallback(
+ ChooserListAdapter chooserListAdapter) {
+ return resultList -> {
+ //TODO(arangelov) Take care of edge case when callback called after swiping tabs
+ if (isFinishing() || isDestroyed()) {
+ return;
+ }
+ if (chooserListAdapter.getCount() == 0) {
+ return;
+ }
+ if (resultList.isEmpty()) {
+ // APS may be disabled, so try querying targets ourselves.
+ //TODO(arangelov) queryDirectShareTargets indirectly uses mIntents.
+ // Investigate implications for work tab.
+ queryDirectShareTargets(chooserListAdapter, true);
+ return;
+ }
+ final List<DisplayResolveInfo> driList =
+ getDisplayResolveInfos(chooserListAdapter);
+ final List<ShortcutManager.ShareShortcutInfo> shareShortcutInfos =
+ new ArrayList<>();
+ for (AppTarget appTarget : resultList) {
+ if (appTarget.getShortcutInfo() == null) {
+ continue;
+ }
+ shareShortcutInfos.add(new ShortcutManager.ShareShortcutInfo(
+ appTarget.getShortcutInfo(),
+ new ComponentName(
+ appTarget.getPackageName(), appTarget.getClassName())));
+ }
+ sendShareShortcutInfoList(shareShortcutInfos, driList, resultList,
+ chooserListAdapter.getUserHandle());
+ };
}
static SharedPreferences getPinnedSharedPrefs(Context context) {
@@ -1260,9 +1283,9 @@ public class ChooserActivity extends ResolverActivity implements
if (mPreviewCoord != null) mPreviewCoord.cancelLoads();
- if (mAppPredictor != null) {
- mAppPredictor.unregisterPredictionUpdates(mAppPredictorCallback);
- mAppPredictor.destroy();
+ mChooserMultiProfilePagerAdapter.getActiveListAdapter().destroyAppPredictor();
+ if (mChooserMultiProfilePagerAdapter.getInactiveListAdapter() != null) {
+ mChooserMultiProfilePagerAdapter.getInactiveListAdapter().destroyAppPredictor();
}
}
@@ -1312,7 +1335,8 @@ public class ChooserActivity extends ResolverActivity implements
mChooserMultiProfilePagerAdapter.getActiveListAdapter().addServiceResults(
/* origTarget */ null,
Lists.newArrayList(mCallerChooserTargets),
- TARGET_TYPE_DEFAULT);
+ TARGET_TYPE_DEFAULT,
+ /* directShareShortcutInfoCache */ null);
}
}
@@ -1541,8 +1565,10 @@ public class ChooserActivity extends ResolverActivity implements
void queryTargetServices(ChooserListAdapter adapter) {
mQueriedTargetServicesTimeMs = System.currentTimeMillis();
- final PackageManager pm = getPackageManager();
- ShortcutManager sm = (ShortcutManager) getSystemService(ShortcutManager.class);
+ Context selectedProfileContext = createContextAsUser(
+ adapter.getUserHandle(), 0 /* flags */);
+ final PackageManager pm = selectedProfileContext.getPackageManager();
+ ShortcutManager sm = selectedProfileContext.getSystemService(ShortcutManager.class);
int targetsToQuery = 0;
for (int i = 0, N = adapter.getDisplayResolveInfoCount(); i < N; i++) {
@@ -1565,10 +1591,13 @@ public class ChooserActivity extends ResolverActivity implements
final ComponentName serviceComponent = new ComponentName(
ai.packageName, serviceName);
- if (mServicesRequested.contains(serviceComponent)) {
+ UserHandle userHandle = adapter.getUserHandle();
+ Pair<ComponentName, UserHandle> requestedItem =
+ new Pair<>(serviceComponent, userHandle);
+ if (mServicesRequested.contains(requestedItem)) {
continue;
}
- mServicesRequested.add(serviceComponent);
+ mServicesRequested.add(requestedItem);
final Intent serviceIntent = new Intent(ChooserTargetService.SERVICE_INTERFACE)
.setComponent(serviceComponent);
@@ -1596,13 +1625,14 @@ public class ChooserActivity extends ResolverActivity implements
}
final ChooserTargetServiceConnection conn =
- new ChooserTargetServiceConnection(this, dri);
+ new ChooserTargetServiceConnection(this, dri,
+ adapter.getUserHandle());
- // Explicitly specify Process.myUserHandle instead of calling bindService
+ // Explicitly specify the user handle instead of calling bindService
// to avoid the warning from calling from the system process without an explicit
// user handle
if (bindServiceAsUser(serviceIntent, conn, BIND_AUTO_CREATE | BIND_NOT_FOREGROUND,
- Process.myUserHandle())) {
+ adapter.getUserHandle())) {
if (DEBUG) {
Log.d(TAG, "Binding service connection for target " + dri
+ " intent " + serviceIntent);
@@ -1684,8 +1714,9 @@ public class ChooserActivity extends ResolverActivity implements
private void queryDirectShareTargets(
ChooserListAdapter adapter, boolean skipAppPredictionService) {
mQueriedSharingShortcutsTimeMs = System.currentTimeMillis();
+ UserHandle userHandle = adapter.getUserHandle();
if (!skipAppPredictionService) {
- AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled();
+ AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled(userHandle);
if (appPredictor != null) {
appPredictor.requestPredictionUpdate();
return;
@@ -1700,17 +1731,18 @@ public class ChooserActivity extends ResolverActivity implements
final List<DisplayResolveInfo> driList = getDisplayResolveInfos(adapter);
AsyncTask.execute(() -> {
- //TODO(arangelov) use the selected probile tab's ShortcutManager
- ShortcutManager sm = (ShortcutManager) getSystemService(Context.SHORTCUT_SERVICE);
+ Context selectedProfileContext = createContextAsUser(userHandle, 0 /* flags */);
+ ShortcutManager sm = (ShortcutManager) selectedProfileContext
+ .getSystemService(Context.SHORTCUT_SERVICE);
List<ShortcutManager.ShareShortcutInfo> resultList = sm.getShareTargets(filter);
- sendShareShortcutInfoList(resultList, driList, null);
+ sendShareShortcutInfoList(resultList, driList, null, userHandle);
});
}
private void sendShareShortcutInfoList(
List<ShortcutManager.ShareShortcutInfo> resultList,
List<DisplayResolveInfo> driList,
- @Nullable List<AppTarget> appTargets) {
+ @Nullable List<AppTarget> appTargets, UserHandle userHandle) {
if (appTargets != null && appTargets.size() != resultList.size()) {
throw new RuntimeException("resultList and appTargets must have the same size."
+ " resultList.size()=" + resultList.size()
@@ -1749,9 +1781,11 @@ public class ChooserActivity extends ResolverActivity implements
List<ChooserTarget> chooserTargets = convertToChooserTarget(
matchingShortcuts, resultList, appTargets, shortcutType);
+
+
final Message msg = Message.obtain();
msg.what = ChooserHandler.SHORTCUT_MANAGER_SHARE_TARGET_RESULT;
- msg.obj = new ServiceResultInfo(driList.get(i), chooserTargets, null);
+ msg.obj = new ServiceResultInfo(driList.get(i), chooserTargets, null, userHandle);
msg.arg1 = shortcutType;
mChooserHandler.sendMessage(msg);
resultMessageSent = true;
@@ -1842,6 +1876,9 @@ public class ChooserActivity extends ResolverActivity implements
mDirectShareAppTargetCache.put(chooserTarget,
allAppTargets.get(indexInAllShortcuts));
}
+ if (mDirectShareShortcutInfoCache != null) {
+ mDirectShareShortcutInfoCache.put(chooserTarget, shortcutInfo);
+ }
}
// Sort ChooserTargets by score in descending order
Comparator<ChooserTarget> byScore =
@@ -1915,7 +1952,8 @@ public class ChooserActivity extends ResolverActivity implements
}
private void sendClickToAppPredictor(TargetInfo targetInfo) {
- AppPredictor directShareAppPredictor = getAppPredictorForDirectShareIfEnabled();
+ AppPredictor directShareAppPredictor = getAppPredictorForDirectShareIfEnabled(
+ mChooserMultiProfilePagerAdapter.getCurrentUserHandle());
if (directShareAppPredictor == null) {
return;
}
@@ -1937,34 +1975,54 @@ public class ChooserActivity extends ResolverActivity implements
}
@Nullable
- private AppPredictor getAppPredictor() {
+ private AppPredictor createAppPredictor(UserHandle userHandle) {
if (!mIsAppPredictorComponentAvailable) {
return null;
}
- if (mAppPredictor == 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);
+
+ if (getPersonalProfileUserHandle() == userHandle) {
+ if (mPersonalAppPredictor != null) {
+ return mPersonalAppPredictor;
+ }
+ } else {
+ if (mWorkAppPredictor != null) {
+ return mWorkAppPredictor;
+ }
+ }
+
+ // TODO(b/148230574): Currently AppPredictor fetches only the same-profile app targets.
+ // Make AppPredictor work cross-profile.
+ Context contextAsUser = createContextAsUser(userHandle, 0 /* flags */);
+ final IntentFilter filter = getTargetIntentFilter();
+ Bundle extras = new Bundle();
+ extras.putParcelable(APP_PREDICTION_INTENT_FILTER_KEY, filter);
+ AppPredictionContext appPredictionContext = new AppPredictionContext.Builder(contextAsUser)
+ .setUiSurface(APP_PREDICTION_SHARE_UI_SURFACE)
+ .setPredictedTargetCount(APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT)
+ .setExtras(extras)
+ .build();
+ AppPredictionManager appPredictionManager =
+ contextAsUser
+ .getSystemService(AppPredictionManager.class);
+ AppPredictor appPredictionSession = appPredictionManager.createAppPredictionSession(
+ appPredictionContext);
+ if (getPersonalProfileUserHandle() == userHandle) {
+ mPersonalAppPredictor = appPredictionSession;
+ } else {
+ mWorkAppPredictor = appPredictionSession;
}
- return mAppPredictor;
+ return appPredictionSession;
}
/**
* This will return an app predictor if it is enabled for direct share sorting
* and if one exists. Otherwise, it returns null.
+ * @param userHandle
*/
@Nullable
- private AppPredictor getAppPredictorForDirectShareIfEnabled() {
+ private AppPredictor getAppPredictorForDirectShareIfEnabled(UserHandle userHandle) {
return ChooserFlags.USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS
- && !ActivityManager.isLowRamDeviceStatic() ? getAppPredictor() : null;
+ && !ActivityManager.isLowRamDeviceStatic() ? createAppPredictor(userHandle) : null;
}
/**
@@ -1972,8 +2030,8 @@ public class ChooserActivity extends ResolverActivity implements
* and if one exists. Otherwise, it returns null.
*/
@Nullable
- private AppPredictor getAppPredictorForShareActivitesIfEnabled() {
- return USE_PREDICTION_MANAGER_FOR_SHARE_ACTIVITIES ? getAppPredictor() : null;
+ private AppPredictor getAppPredictorForShareActivitiesIfEnabled(UserHandle userHandle) {
+ return USE_PREDICTION_MANAGER_FOR_SHARE_ACTIVITIES ? createAppPredictor(userHandle) : null;
}
void onRefinementResult(TargetInfo selectedTarget, Intent matchingIntent) {
@@ -2016,12 +2074,13 @@ public class ChooserActivity extends ResolverActivity implements
return false;
}
- void filterServiceTargets(String packageName, List<ChooserTarget> targets) {
+ void filterServiceTargets(Context contextAsUser, String packageName,
+ List<ChooserTarget> targets) {
if (targets == null) {
return;
}
- final PackageManager pm = getPackageManager();
+ final PackageManager pm = contextAsUser.getPackageManager();
for (int i = targets.size() - 1; i >= 0; i--) {
final ChooserTarget target = targets.get(i);
final ComponentName targetName = target.getComponentName();
@@ -2104,19 +2163,24 @@ public class ChooserActivity extends ResolverActivity implements
public ChooserGridAdapter createChooserGridAdapter(Context context,
List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList,
boolean filterLastUsed, boolean useLayoutForBrowsables, UserHandle userHandle) {
- return new ChooserGridAdapter(
- new ChooserListAdapter(context, payloadIntents, initialIntents, rList,
- filterLastUsed, createListController(userHandle), useLayoutForBrowsables,
- this, this));
+ ChooserListAdapter chooserListAdapter = new ChooserListAdapter(context, payloadIntents,
+ initialIntents, rList,
+ filterLastUsed, createListController(userHandle), useLayoutForBrowsables,
+ this, this);
+ AppPredictor.Callback appPredictorCallback = createAppPredictorCallback(chooserListAdapter);
+ AppPredictor appPredictor = setupAppPredictorForUser(userHandle, appPredictorCallback);
+ chooserListAdapter.setAppPredictor(appPredictor);
+ chooserListAdapter.setAppPredictorCallback(appPredictorCallback);
+ return new ChooserGridAdapter(chooserListAdapter);
}
@VisibleForTesting
protected ResolverListController createListController(UserHandle userHandle) {
- AppPredictor appPredictor = getAppPredictorForShareActivitesIfEnabled();
+ AppPredictor appPredictor = getAppPredictorForShareActivitiesIfEnabled(userHandle);
AbstractResolverComparator resolverComparator;
if (appPredictor != null) {
resolverComparator = new AppPredictionServiceResolverComparator(this, getTargetIntent(),
- getReferrerPackageName(), appPredictor, getUser());
+ getReferrerPackageName(), appPredictor, userHandle);
} else {
resolverComparator =
new ResolverRankerServiceResolverComparator(this, getTargetIntent(),
@@ -2297,9 +2361,11 @@ public class ChooserActivity extends ResolverActivity implements
}
@Override // ChooserListCommunicator
- public void sendListViewUpdateMessage() {
- mChooserHandler.sendEmptyMessageDelayed(ChooserHandler.LIST_VIEW_UPDATE_MESSAGE,
- LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+ public void sendListViewUpdateMessage(UserHandle userHandle) {
+ Message msg = Message.obtain();
+ msg.what = ChooserHandler.LIST_VIEW_UPDATE_MESSAGE;
+ msg.obj = userHandle;
+ mChooserHandler.sendMessageDelayed(msg, LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
}
@Override
@@ -3158,6 +3224,7 @@ public class ChooserActivity extends ResolverActivity implements
private DisplayResolveInfo mOriginalTarget;
private ComponentName mConnectedComponent;
private ChooserActivity mChooserActivity;
+ private final UserHandle mUserHandle;
private final Object mLock = new Object();
private final IChooserTargetResult mChooserTargetResult = new IChooserTargetResult.Stub() {
@@ -3169,21 +3236,24 @@ public class ChooserActivity extends ResolverActivity implements
+ mConnectedComponent + "; ignoring...");
return;
}
- mChooserActivity.filterServiceTargets(
+ Context contextAsUser =
+ mChooserActivity.createContextAsUser(mUserHandle, 0 /* flags */);
+ mChooserActivity.filterServiceTargets(contextAsUser,
mOriginalTarget.getResolveInfo().activityInfo.packageName, targets);
final Message msg = Message.obtain();
msg.what = ChooserHandler.CHOOSER_TARGET_SERVICE_RESULT;
msg.obj = new ServiceResultInfo(mOriginalTarget, targets,
- ChooserTargetServiceConnection.this);
+ ChooserTargetServiceConnection.this, mUserHandle);
mChooserActivity.mChooserHandler.sendMessage(msg);
}
}
};
public ChooserTargetServiceConnection(ChooserActivity chooserActivity,
- DisplayResolveInfo dri) {
+ DisplayResolveInfo dri, UserHandle userHandle) {
mChooserActivity = chooserActivity;
mOriginalTarget = dri;
+ mUserHandle = userHandle;
}
@Override
@@ -3249,12 +3319,14 @@ public class ChooserActivity extends ResolverActivity implements
public final DisplayResolveInfo originalTarget;
public final List<ChooserTarget> resultTargets;
public final ChooserTargetServiceConnection connection;
+ public final UserHandle userHandle;
public ServiceResultInfo(DisplayResolveInfo ot, List<ChooserTarget> rt,
- ChooserTargetServiceConnection c) {
+ ChooserTargetServiceConnection c, UserHandle userHandle) {
originalTarget = ot;
resultTargets = rt;
connection = c;
+ this.userHandle = userHandle;
}
}
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index 6ff844a2eaae..ca3b7e7a7837 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -19,7 +19,9 @@ package com.android.internal.app;
import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE;
import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER;
+import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.prediction.AppPredictor;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -27,7 +29,9 @@ import android.content.pm.ActivityInfo;
import android.content.pm.LabeledIntent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.pm.ShortcutInfo;
import android.os.AsyncTask;
+import android.os.UserHandle;
import android.os.UserManager;
import android.service.chooser.ChooserTarget;
import android.util.Log;
@@ -90,6 +94,8 @@ public class ChooserListAdapter extends ResolverListAdapter {
// Sorted list of DisplayResolveInfos for the alphabetical app section.
private List<DisplayResolveInfo> mSortedList = new ArrayList<>();
+ private AppPredictor mAppPredictor;
+ private AppPredictor.Callback mAppPredictorCallback;
public ChooserListAdapter(Context context, List<Intent> payloadIntents,
Intent[] initialIntents, List<ResolveInfo> rList,
@@ -160,6 +166,10 @@ public class ChooserListAdapter extends ResolverListAdapter {
}
}
+ AppPredictor getAppPredictor() {
+ return mAppPredictor;
+ }
+
@Override
public void handlePackagesChanged() {
if (DEBUG) {
@@ -173,7 +183,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
@Override
public void notifyDataSetChanged() {
if (!mListViewDataChanged) {
- mChooserListCommunicator.sendListViewUpdateMessage();
+ mChooserListCommunicator.sendListViewUpdateMessage(getUserHandle());
mListViewDataChanged = true;
}
}
@@ -383,7 +393,8 @@ public class ChooserListAdapter extends ResolverListAdapter {
* if score is too low.
*/
public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets,
- @ChooserActivity.ShareTargetType int targetType) {
+ @ChooserActivity.ShareTargetType int targetType,
+ Map<ChooserTarget, ShortcutInfo> directShareToShortcutInfos) {
if (DEBUG) {
Log.d(TAG, "addServiceResults " + origTarget + ", " + targets.size()
+ " targets");
@@ -412,8 +423,11 @@ public class ChooserListAdapter extends ResolverListAdapter {
// This incents ChooserTargetServices to define what's truly better.
targetScore = lastScore * 0.95f;
}
- boolean isInserted = insertServiceTarget(new SelectableTargetInfo(
- mContext, origTarget, target, targetScore, mSelectableTargetInfoComunicator));
+ UserHandle userHandle = getUserHandle();
+ Context contextAsUser = mContext.createContextAsUser(userHandle, 0 /* flags */);
+ boolean isInserted = insertServiceTarget(new SelectableTargetInfo(contextAsUser,
+ origTarget, target, targetScore, mSelectableTargetInfoComunicator,
+ (isShortcutResult ? directShareToShortcutInfos.get(target) : null)));
if (isInserted && isShortcutResult) {
mNumShortcutResults++;
@@ -547,6 +561,21 @@ public class ChooserListAdapter extends ResolverListAdapter {
};
}
+ public void setAppPredictor(AppPredictor appPredictor) {
+ mAppPredictor = appPredictor;
+ }
+
+ public void setAppPredictorCallback(AppPredictor.Callback appPredictorCallback) {
+ mAppPredictorCallback = appPredictorCallback;
+ }
+
+ public void destroyAppPredictor() {
+ if (getAppPredictor() != null) {
+ getAppPredictor().unregisterPredictionUpdates(mAppPredictorCallback);
+ getAppPredictor().destroy();
+ }
+ }
+
/**
* Necessary methods to communicate between {@link ChooserListAdapter}
* and {@link ChooserActivity}.
@@ -555,7 +584,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
int getMaxRankedTargets();
- void sendListViewUpdateMessage();
+ void sendListViewUpdateMessage(UserHandle userHandle);
boolean isSendAction(Intent targetIntent);
}
diff --git a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
index 1c52d0e8f9f1..663e0255feb9 100644
--- a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
@@ -18,6 +18,7 @@ package com.android.internal.app;
import android.annotation.Nullable;
import android.content.Context;
+import android.os.UserHandle;
import android.view.LayoutInflater;
import android.view.ViewGroup;
@@ -84,6 +85,18 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd
}
@Override
+ @Nullable
+ ChooserListAdapter getListAdapterForUserHandle(UserHandle userHandle) {
+ if (getActiveListAdapter().getUserHandle() == userHandle) {
+ return getActiveListAdapter();
+ } else if (getInactiveListAdapter() != null
+ && getInactiveListAdapter().getUserHandle() == userHandle) {
+ return getInactiveListAdapter();
+ }
+ return null;
+ }
+
+ @Override
void setupListAdapter(int pageIndex) {
final RecyclerView recyclerView = getItem(pageIndex).recyclerView;
ChooserActivity.ChooserGridAdapter chooserGridAdapter =
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 96ab0bb4afc4..30a41d338806 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -543,6 +543,9 @@ public class ResolverActivity extends Activity implements
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged();
+ if (mMultiProfilePagerAdapter.getInactiveListAdapter() != null) {
+ mMultiProfilePagerAdapter.getInactiveListAdapter().handlePackagesChanged();
+ }
if (mSystemWindowInsets != null) {
mResolverDrawerLayout.setPadding(mSystemWindowInsets.left, mSystemWindowInsets.top,
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index d227ec5c1b38..405112d99fe7 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -407,6 +407,7 @@ public class ResolverListAdapter extends BaseAdapter {
// We assume that at this point we've already filtered out the only intent for a different
// targetUserId which we're going to use.
private void addResolveInfo(DisplayResolveInfo dri) {
+ // TODO(arangelov): Is that UserHandle.USER_CURRENT check okay?
if (dri != null && dri.getResolveInfo() != null
&& dri.getResolveInfo().targetUserId == UserHandle.USER_CURRENT) {
// Checks if this info is already listed in display.
@@ -575,7 +576,7 @@ public class ResolverListAdapter extends BaseAdapter {
Drawable loadIconForResolveInfo(ResolveInfo ri) {
// Load icons based on the current process. If in work profile icons should be badged.
- return makePresentationGetter(ri).getIcon(mResolverListController.getUserHandle());
+ return makePresentationGetter(ri).getIcon(getUserHandle());
}
void loadFilteredItemIconTaskAsync(@NonNull ImageView iconView) {
@@ -585,6 +586,10 @@ public class ResolverListAdapter extends BaseAdapter {
}
}
+ UserHandle getUserHandle() {
+ return mResolverListController.getUserHandle();
+ }
+
/**
* Necessary methods to communicate between {@link ResolverListAdapter}
* and {@link ResolverActivity}.
diff --git a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
index 567ed74670bf..9d3c6c9ad8b1 100644
--- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
@@ -18,6 +18,7 @@ package com.android.internal.app;
import android.annotation.Nullable;
import android.content.Context;
+import android.os.UserHandle;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.ListView;
@@ -88,6 +89,18 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA
}
@Override
+ @Nullable
+ ResolverListAdapter getListAdapterForUserHandle(UserHandle userHandle) {
+ if (getActiveListAdapter().getUserHandle() == userHandle) {
+ return getActiveListAdapter();
+ } else if (getInactiveListAdapter() != null
+ && getInactiveListAdapter().getUserHandle() == userHandle) {
+ return getInactiveListAdapter();
+ }
+ return null;
+ }
+
+ @Override
@VisibleForTesting
public ResolverListAdapter getActiveListAdapter() {
return getAdapterForIndex(getCurrentPage());
diff --git a/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java b/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java
index 86a0d10cf67e..246a07d3d0fe 100644
--- a/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java
+++ b/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java
@@ -16,6 +16,7 @@
package com.android.internal.app.chooser;
+import android.annotation.Nullable;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
@@ -70,7 +71,8 @@ public final class SelectableTargetInfo implements ChooserTargetInfo {
public SelectableTargetInfo(Context context, DisplayResolveInfo sourceInfo,
ChooserTarget chooserTarget,
- float modifiedScore, SelectableTargetInfoCommunicator selectableTargetInfoComunicator) {
+ float modifiedScore, SelectableTargetInfoCommunicator selectableTargetInfoComunicator,
+ @Nullable ShortcutInfo shortcutInfo) {
mContext = context;
mSourceInfo = sourceInfo;
mChooserTarget = chooserTarget;
@@ -91,7 +93,7 @@ public final class SelectableTargetInfo implements ChooserTargetInfo {
}
}
// TODO(b/121287224): do this in the background thread, and only for selected targets
- mDisplayIcon = getChooserTargetIconDrawable(chooserTarget);
+ mDisplayIcon = getChooserTargetIconDrawable(chooserTarget, shortcutInfo);
if (sourceInfo != null) {
mBackupResolveInfo = null;
@@ -134,34 +136,18 @@ public final class SelectableTargetInfo implements ChooserTargetInfo {
return mIsSuspended;
}
- /**
- * Since ShortcutInfos are returned by ShortcutManager, we can cache the shortcuts and skip
- * the call to LauncherApps#getShortcuts(ShortcutQuery).
- */
- // TODO(121287224): Refactor code to apply the suggestion above
- private Drawable getChooserTargetIconDrawable(ChooserTarget target) {
+ private Drawable getChooserTargetIconDrawable(ChooserTarget target,
+ @Nullable ShortcutInfo shortcutInfo) {
Drawable directShareIcon = null;
// First get the target drawable and associated activity info
final Icon icon = target.getIcon();
if (icon != null) {
directShareIcon = icon.loadDrawable(mContext);
- } else if (ChooserFlags.USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS) {
- Bundle extras = target.getIntentExtras();
- if (extras != null && extras.containsKey(Intent.EXTRA_SHORTCUT_ID)) {
- CharSequence shortcutId = extras.getCharSequence(Intent.EXTRA_SHORTCUT_ID);
- LauncherApps launcherApps = (LauncherApps) mContext.getSystemService(
- Context.LAUNCHER_APPS_SERVICE);
- final LauncherApps.ShortcutQuery q = new LauncherApps.ShortcutQuery();
- q.setPackage(target.getComponentName().getPackageName());
- q.setShortcutIds(Arrays.asList(shortcutId.toString()));
- q.setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC);
- final List<ShortcutInfo> shortcuts =
- launcherApps.getShortcuts(q, mContext.getUser());
- if (shortcuts != null && shortcuts.size() > 0) {
- directShareIcon = launcherApps.getShortcutIconDrawable(shortcuts.get(0), 0);
- }
- }
+ } else if (ChooserFlags.USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS && shortcutInfo != null) {
+ LauncherApps launcherApps = (LauncherApps) mContext.getSystemService(
+ Context.LAUNCHER_APPS_SERVICE);
+ directShareIcon = launcherApps.getShortcutIconDrawable(shortcutInfo, 0);
}
if (directShareIcon == null) return null;