diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2020-01-24 23:50:28 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-01-24 23:50:28 +0000 |
| commit | f82fd3dc815ac45248dab5ea53293d2dae45377a (patch) | |
| tree | 211bec996a44dbe89d1cd7bacc268f24dfafa248 /core/java | |
| parent | b359190aeab1ae0afca9eeda352a2e93a95922b8 (diff) | |
| parent | 5fc9e7ddeee16b6c43c88278ee8801ea52d64171 (diff) | |
Merge "Make direct share work with the work profile tab."
Diffstat (limited to 'core/java')
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; |
