Loading quickstep/src/com/android/quickstep/TaskShortcutFactory.java +5 −6 Original line number Diff line number Diff line Loading @@ -322,14 +322,13 @@ public interface TaskShortcutFactory { isLargeTileFocusedTask && isInExpectedScrollPosition; // No "save app pair" menu item if: // - app pairs feature is not enabled // - we are in 3p launcher // - the task in question is a single task // - the Overview Actions Button should be visible if (!FeatureFlags.enableAppPairs() || !recentsView.supportsAppPairs() || !taskView.containsMultipleTasks() || shouldShowActionsButtonInstead) { // - the task view is not a valid save-able split pair if (!recentsView.supportsAppPairs() || shouldShowActionsButtonInstead || !recentsView.getSplitSelectController().getAppPairsController() .canSaveAppPair(taskView)) { return null; } Loading quickstep/src/com/android/quickstep/util/AppPairsController.java +111 −26 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static com.android.wm.shell.common.split.SplitScreenConstants.isPersistentSnapPosition; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; Loading @@ -38,6 +39,7 @@ import android.content.pm.PackageManager; import android.util.Log; import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; Loading @@ -45,20 +47,25 @@ import com.android.internal.jank.Cuj; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; import com.android.launcher3.allapps.AllAppsStore; import com.android.launcher3.apppairs.AppPairIcon; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.icons.IconCache; import com.android.launcher3.logging.InstanceId; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.AppPairInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.taskbar.TaskbarActivityContext; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.SplitConfigurationOptions.StagePosition; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.TaskUtils; import com.android.quickstep.TopTaskTracker; import com.android.quickstep.views.GroupedTaskView; import com.android.quickstep.views.TaskView; Loading Loading @@ -87,18 +94,88 @@ public class AppPairsController { private Context mContext; private final SplitSelectStateController mSplitSelectStateController; private final StatsLogManager mStatsLogManager; private final String[] mLegacyMultiInstanceSupportedApps; public AppPairsController(Context context, SplitSelectStateController splitSelectStateController, StatsLogManager statsLogManager) { mContext = context; mSplitSelectStateController = splitSelectStateController; mStatsLogManager = statsLogManager; mLegacyMultiInstanceSupportedApps = mContext.getResources().getStringArray( R.array.config_appsSupportMultiInstancesSplit); } void onDestroy() { mContext = null; } /** * Returns whether the given component or its application supports multi-instance. */ private boolean supportsMultiInstance(@NonNull ComponentName component) { // Check the legacy hardcoded allowlist first for (String pkg : mLegacyMultiInstanceSupportedApps) { if (pkg.equals(component.getPackageName())) { return true; } } return false; } /** * Returns whether two apps should be considered the same for multi-instance purposes, which * requires additional checks to ensure they can be started as multiple instances. */ private boolean isSameAppForMultiInstance(@NonNull ItemInfo app1, @NonNull ItemInfo app2) { return app1.getTargetPackage().equals(app2.getTargetPackage()) && app1.user.equals(app2.user); } /** * Returns whether the specified GroupedTaskView can be saved as an app pair. */ public boolean canSaveAppPair(TaskView taskView) { if (mContext == null) { // Can ignore as the activity is already destroyed return false; } // Disallow saving app pairs if: // - app pairs feature is not enabled // - the task in question is a single task // - at least one app in app pair is unpinnable // - the task is not a GroupedTaskView // - both tasks in the GroupedTaskView are from the same app and the app does not // support multi-instance if (!FeatureFlags.enableAppPairs() || !taskView.containsMultipleTasks() || !(taskView instanceof GroupedTaskView)) { return false; } GroupedTaskView gtv = (GroupedTaskView) taskView; TaskView.TaskIdAttributeContainer[] attributes = gtv.getTaskIdAttributeContainers(); WorkspaceItemInfo info1 = attributes[0].getItemInfo(); WorkspaceItemInfo info2 = attributes[1].getItemInfo(); AppInfo app1 = resolveAppInfoByComponent(info1.getComponentKey()); AppInfo app2 = resolveAppInfoByComponent(info2.getComponentKey()); if (app1 == null || app2 == null) { // Disallow saving app pairs for apps that don't have a front-door in Launcher return false; } if (isSameAppForMultiInstance(app1, app2)) { if (!supportsMultiInstance(app1.getTargetComponent()) || !supportsMultiInstance(app2.getTargetComponent())) { return false; } } return true; } /** * Creates a new app pair ItemInfo and adds it to the workspace. * <br> Loading @@ -118,20 +195,16 @@ public class AppPairsController { TaskView.TaskIdAttributeContainer[] attributes = gtv.getTaskIdAttributeContainers(); WorkspaceItemInfo recentsInfo1 = attributes[0].getItemInfo(); WorkspaceItemInfo recentsInfo2 = attributes[1].getItemInfo(); WorkspaceItemInfo app1 = lookupLaunchableItem(recentsInfo1.getComponentKey()); WorkspaceItemInfo app2 = lookupLaunchableItem(recentsInfo2.getComponentKey()); // If app lookup fails, use the WorkspaceItemInfo that we have, but try to override default // intent with one from PackageManager. if (app1 == null) { Log.w(TAG, "Creating an app pair, but app lookup for " + recentsInfo1.title + " failed. Falling back to the WorkspaceItemInfo from Recents."); app1 = convertRecentsItemToAppItem(recentsInfo1); } if (app2 == null) { Log.w(TAG, "Creating an app pair, but app lookup for " + recentsInfo2.title + " failed. Falling back to the WorkspaceItemInfo from Recents."); app2 = convertRecentsItemToAppItem(recentsInfo2); WorkspaceItemInfo app1 = resolveAppPairWorkspaceInfo(recentsInfo1); WorkspaceItemInfo app2 = resolveAppPairWorkspaceInfo(recentsInfo2); if (app1 == null || app2 == null) { // This shouldn't happen if canSaveAppPair() is called above, but log an error and do // not create the app pair if the workspace items can't be resolved Log.w(TAG, "Failed to save app pair due to invalid apps (" + "app1=" + recentsInfo1.getComponentKey().componentName + " app2=" + recentsInfo2.getComponentKey().componentName + ")"); return; } // WorkspaceItemProcessor won't process these new ItemInfos until the next launcher restart, Loading @@ -141,8 +214,9 @@ public class AppPairsController { @PersistentSnapPosition int snapPosition = gtv.getSnapPosition(); if (!isPersistentSnapPosition(snapPosition)) { // if we received an illegal snap position, log an error and do not create the app pair. Log.wtf(TAG, "tried to save an app pair with illegal snapPosition " + snapPosition); // If we received an illegal snap position, log an error and do not create the app pair Log.wtf(TAG, "Tried to save an app pair with illegal snapPosition " + snapPosition); return; } Loading Loading @@ -228,25 +302,36 @@ public class AppPairsController { } /** * Creates a new launchable WorkspaceItemInfo of itemType=ITEM_TYPE_APPLICATION by looking the * ComponentKey up in the AllAppsStore. If no app is found, attempts a lookup by package * instead. If that lookup fails, returns null. * Returns an AppInfo associated with the app for the given ComponentKey, or null if no such * package exists in the AllAppsStore. */ @Nullable private WorkspaceItemInfo lookupLaunchableItem(@Nullable ComponentKey key) { if (key == null) { return null; } private AppInfo resolveAppInfoByComponent(@NonNull ComponentKey key) { AllAppsStore appsStore = Launcher.getLauncher(mContext).getAppsView().getAppsStore(); // Lookup by ComponentKey // First look up the app info in order of: // - The exact activity for the recent task // - The first(?) loaded activity from the package AppInfo appInfo = appsStore.getApp(key); if (appInfo == null) { // Lookup by package appInfo = appsStore.getApp(key, PACKAGE_KEY_COMPARATOR); } return appInfo; } /** * Creates a new launchable WorkspaceItemInfo of itemType=ITEM_TYPE_APPLICATION by looking the * ComponentKey up in the AllAppsStore. If no app is found, attempts a lookup by package * instead. If that lookup fails, returns null. */ @Nullable private WorkspaceItemInfo resolveAppPairWorkspaceInfo( @NonNull WorkspaceItemInfo recentTaskInfo) { // ComponentKey should never be null (see TaskView#getItemInfo) AppInfo appInfo = resolveAppInfoByComponent(recentTaskInfo.getComponentKey()); if (appInfo == null) { return null; } return appInfo != null ? appInfo.makeWorkspaceItem(mContext) : null; } Loading quickstep/src/com/android/quickstep/views/OverviewActionsView.java +7 −2 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.NavigationMode; import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks; import com.android.quickstep.util.AppPairsController; import com.android.quickstep.util.LayoutUtils; import java.lang.annotation.Retention; Loading Loading @@ -133,6 +134,7 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo protected DeviceProfile mDp; private final Rect mTaskSize = new Rect(); private boolean mIsGroupedTask = false; private boolean mCanSaveAppPair = false; public OverviewActionsView(Context context) { this(context, null); Loading Loading @@ -249,9 +251,12 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo * Updates a batch of flags to hide and show actions buttons when a grouped task (split screen) * is focused. * @param isGroupedTask True if the focused task is a grouped task. * @param canSaveAppPair True if the focused task is a grouped task and can be saved as an app * pair. */ public void updateForGroupedTask(boolean isGroupedTask) { public void updateForGroupedTask(boolean isGroupedTask, boolean canSaveAppPair) { mIsGroupedTask = isGroupedTask; mCanSaveAppPair = canSaveAppPair; updateActionButtonsVisibility(); } Loading @@ -268,7 +273,7 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo private void updateActionButtonsVisibility() { assert mDp != null; boolean showSingleTaskActions = !mIsGroupedTask; boolean showGroupActions = mIsGroupedTask && mDp.isTablet; boolean showGroupActions = mIsGroupedTask && mDp.isTablet && mCanSaveAppPair; getActionsAlphas().get(INDEX_GROUPED_ALPHA).setValue(showSingleTaskActions ? 1 : 0); getGroupActionsAlphas().get(INDEX_GROUPED_ALPHA).setValue(showGroupActions ? 1 : 0); } Loading quickstep/src/com/android/quickstep/views/RecentsView.java +6 −2 Original line number Diff line number Diff line Loading @@ -4023,7 +4023,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T * * Device is large screen */ private void updateCurrentTaskActionsVisibility() { boolean isCurrentSplit = getCurrentPageTaskView() instanceof GroupedTaskView; TaskView taskView = getCurrentPageTaskView(); boolean isCurrentSplit = taskView instanceof GroupedTaskView; GroupedTaskView groupedTaskView = isCurrentSplit ? (GroupedTaskView) taskView : null; // Update flags to see if entire actions bar should be hidden. if (!FeatureFlags.enableAppPairs()) { mActionsView.updateHiddenFlags(HIDDEN_SPLIT_SCREEN, isCurrentSplit); Loading @@ -4031,7 +4033,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mActionsView.updateHiddenFlags(HIDDEN_SPLIT_SELECT_ACTIVE, isSplitSelectionActive()); // Update flags to see if actions bar should show buttons for a single task or a pair of // tasks. mActionsView.updateForGroupedTask(isCurrentSplit); boolean canSaveAppPair = isCurrentSplit && supportsAppPairs() && getSplitSelectController().getAppPairsController().canSaveAppPair(groupedTaskView); mActionsView.updateForGroupedTask(isCurrentSplit, canSaveAppPair); if (isDesktopModeSupported()) { boolean isCurrentDesktop = getCurrentPageTaskView() instanceof DesktopTaskView; Loading res/values/config.xml +7 −0 Original line number Diff line number Diff line Loading @@ -274,4 +274,11 @@ <string-array name="skip_private_profile_shortcut_packages" translatable="false"> <item>com.android.settings</item> </string-array> <!-- Legacy list of components supporting multiple instances. DO NOT ADD TO THIS LIST. Apps should use the PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI property to declare multi-instance support in V+. This resource should match the resource of the same name in SystemUI. --> <string-array name="config_appsSupportMultiInstancesSplit"> </string-array> </resources> Loading
quickstep/src/com/android/quickstep/TaskShortcutFactory.java +5 −6 Original line number Diff line number Diff line Loading @@ -322,14 +322,13 @@ public interface TaskShortcutFactory { isLargeTileFocusedTask && isInExpectedScrollPosition; // No "save app pair" menu item if: // - app pairs feature is not enabled // - we are in 3p launcher // - the task in question is a single task // - the Overview Actions Button should be visible if (!FeatureFlags.enableAppPairs() || !recentsView.supportsAppPairs() || !taskView.containsMultipleTasks() || shouldShowActionsButtonInstead) { // - the task view is not a valid save-able split pair if (!recentsView.supportsAppPairs() || shouldShowActionsButtonInstead || !recentsView.getSplitSelectController().getAppPairsController() .canSaveAppPair(taskView)) { return null; } Loading
quickstep/src/com/android/quickstep/util/AppPairsController.java +111 −26 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static com.android.wm.shell.common.split.SplitScreenConstants.isPersistentSnapPosition; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; Loading @@ -38,6 +39,7 @@ import android.content.pm.PackageManager; import android.util.Log; import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; Loading @@ -45,20 +47,25 @@ import com.android.internal.jank.Cuj; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; import com.android.launcher3.allapps.AllAppsStore; import com.android.launcher3.apppairs.AppPairIcon; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.icons.IconCache; import com.android.launcher3.logging.InstanceId; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.AppPairInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.taskbar.TaskbarActivityContext; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.SplitConfigurationOptions.StagePosition; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.TaskUtils; import com.android.quickstep.TopTaskTracker; import com.android.quickstep.views.GroupedTaskView; import com.android.quickstep.views.TaskView; Loading Loading @@ -87,18 +94,88 @@ public class AppPairsController { private Context mContext; private final SplitSelectStateController mSplitSelectStateController; private final StatsLogManager mStatsLogManager; private final String[] mLegacyMultiInstanceSupportedApps; public AppPairsController(Context context, SplitSelectStateController splitSelectStateController, StatsLogManager statsLogManager) { mContext = context; mSplitSelectStateController = splitSelectStateController; mStatsLogManager = statsLogManager; mLegacyMultiInstanceSupportedApps = mContext.getResources().getStringArray( R.array.config_appsSupportMultiInstancesSplit); } void onDestroy() { mContext = null; } /** * Returns whether the given component or its application supports multi-instance. */ private boolean supportsMultiInstance(@NonNull ComponentName component) { // Check the legacy hardcoded allowlist first for (String pkg : mLegacyMultiInstanceSupportedApps) { if (pkg.equals(component.getPackageName())) { return true; } } return false; } /** * Returns whether two apps should be considered the same for multi-instance purposes, which * requires additional checks to ensure they can be started as multiple instances. */ private boolean isSameAppForMultiInstance(@NonNull ItemInfo app1, @NonNull ItemInfo app2) { return app1.getTargetPackage().equals(app2.getTargetPackage()) && app1.user.equals(app2.user); } /** * Returns whether the specified GroupedTaskView can be saved as an app pair. */ public boolean canSaveAppPair(TaskView taskView) { if (mContext == null) { // Can ignore as the activity is already destroyed return false; } // Disallow saving app pairs if: // - app pairs feature is not enabled // - the task in question is a single task // - at least one app in app pair is unpinnable // - the task is not a GroupedTaskView // - both tasks in the GroupedTaskView are from the same app and the app does not // support multi-instance if (!FeatureFlags.enableAppPairs() || !taskView.containsMultipleTasks() || !(taskView instanceof GroupedTaskView)) { return false; } GroupedTaskView gtv = (GroupedTaskView) taskView; TaskView.TaskIdAttributeContainer[] attributes = gtv.getTaskIdAttributeContainers(); WorkspaceItemInfo info1 = attributes[0].getItemInfo(); WorkspaceItemInfo info2 = attributes[1].getItemInfo(); AppInfo app1 = resolveAppInfoByComponent(info1.getComponentKey()); AppInfo app2 = resolveAppInfoByComponent(info2.getComponentKey()); if (app1 == null || app2 == null) { // Disallow saving app pairs for apps that don't have a front-door in Launcher return false; } if (isSameAppForMultiInstance(app1, app2)) { if (!supportsMultiInstance(app1.getTargetComponent()) || !supportsMultiInstance(app2.getTargetComponent())) { return false; } } return true; } /** * Creates a new app pair ItemInfo and adds it to the workspace. * <br> Loading @@ -118,20 +195,16 @@ public class AppPairsController { TaskView.TaskIdAttributeContainer[] attributes = gtv.getTaskIdAttributeContainers(); WorkspaceItemInfo recentsInfo1 = attributes[0].getItemInfo(); WorkspaceItemInfo recentsInfo2 = attributes[1].getItemInfo(); WorkspaceItemInfo app1 = lookupLaunchableItem(recentsInfo1.getComponentKey()); WorkspaceItemInfo app2 = lookupLaunchableItem(recentsInfo2.getComponentKey()); // If app lookup fails, use the WorkspaceItemInfo that we have, but try to override default // intent with one from PackageManager. if (app1 == null) { Log.w(TAG, "Creating an app pair, but app lookup for " + recentsInfo1.title + " failed. Falling back to the WorkspaceItemInfo from Recents."); app1 = convertRecentsItemToAppItem(recentsInfo1); } if (app2 == null) { Log.w(TAG, "Creating an app pair, but app lookup for " + recentsInfo2.title + " failed. Falling back to the WorkspaceItemInfo from Recents."); app2 = convertRecentsItemToAppItem(recentsInfo2); WorkspaceItemInfo app1 = resolveAppPairWorkspaceInfo(recentsInfo1); WorkspaceItemInfo app2 = resolveAppPairWorkspaceInfo(recentsInfo2); if (app1 == null || app2 == null) { // This shouldn't happen if canSaveAppPair() is called above, but log an error and do // not create the app pair if the workspace items can't be resolved Log.w(TAG, "Failed to save app pair due to invalid apps (" + "app1=" + recentsInfo1.getComponentKey().componentName + " app2=" + recentsInfo2.getComponentKey().componentName + ")"); return; } // WorkspaceItemProcessor won't process these new ItemInfos until the next launcher restart, Loading @@ -141,8 +214,9 @@ public class AppPairsController { @PersistentSnapPosition int snapPosition = gtv.getSnapPosition(); if (!isPersistentSnapPosition(snapPosition)) { // if we received an illegal snap position, log an error and do not create the app pair. Log.wtf(TAG, "tried to save an app pair with illegal snapPosition " + snapPosition); // If we received an illegal snap position, log an error and do not create the app pair Log.wtf(TAG, "Tried to save an app pair with illegal snapPosition " + snapPosition); return; } Loading Loading @@ -228,25 +302,36 @@ public class AppPairsController { } /** * Creates a new launchable WorkspaceItemInfo of itemType=ITEM_TYPE_APPLICATION by looking the * ComponentKey up in the AllAppsStore. If no app is found, attempts a lookup by package * instead. If that lookup fails, returns null. * Returns an AppInfo associated with the app for the given ComponentKey, or null if no such * package exists in the AllAppsStore. */ @Nullable private WorkspaceItemInfo lookupLaunchableItem(@Nullable ComponentKey key) { if (key == null) { return null; } private AppInfo resolveAppInfoByComponent(@NonNull ComponentKey key) { AllAppsStore appsStore = Launcher.getLauncher(mContext).getAppsView().getAppsStore(); // Lookup by ComponentKey // First look up the app info in order of: // - The exact activity for the recent task // - The first(?) loaded activity from the package AppInfo appInfo = appsStore.getApp(key); if (appInfo == null) { // Lookup by package appInfo = appsStore.getApp(key, PACKAGE_KEY_COMPARATOR); } return appInfo; } /** * Creates a new launchable WorkspaceItemInfo of itemType=ITEM_TYPE_APPLICATION by looking the * ComponentKey up in the AllAppsStore. If no app is found, attempts a lookup by package * instead. If that lookup fails, returns null. */ @Nullable private WorkspaceItemInfo resolveAppPairWorkspaceInfo( @NonNull WorkspaceItemInfo recentTaskInfo) { // ComponentKey should never be null (see TaskView#getItemInfo) AppInfo appInfo = resolveAppInfoByComponent(recentTaskInfo.getComponentKey()); if (appInfo == null) { return null; } return appInfo != null ? appInfo.makeWorkspaceItem(mContext) : null; } Loading
quickstep/src/com/android/quickstep/views/OverviewActionsView.java +7 −2 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.NavigationMode; import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks; import com.android.quickstep.util.AppPairsController; import com.android.quickstep.util.LayoutUtils; import java.lang.annotation.Retention; Loading Loading @@ -133,6 +134,7 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo protected DeviceProfile mDp; private final Rect mTaskSize = new Rect(); private boolean mIsGroupedTask = false; private boolean mCanSaveAppPair = false; public OverviewActionsView(Context context) { this(context, null); Loading Loading @@ -249,9 +251,12 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo * Updates a batch of flags to hide and show actions buttons when a grouped task (split screen) * is focused. * @param isGroupedTask True if the focused task is a grouped task. * @param canSaveAppPair True if the focused task is a grouped task and can be saved as an app * pair. */ public void updateForGroupedTask(boolean isGroupedTask) { public void updateForGroupedTask(boolean isGroupedTask, boolean canSaveAppPair) { mIsGroupedTask = isGroupedTask; mCanSaveAppPair = canSaveAppPair; updateActionButtonsVisibility(); } Loading @@ -268,7 +273,7 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo private void updateActionButtonsVisibility() { assert mDp != null; boolean showSingleTaskActions = !mIsGroupedTask; boolean showGroupActions = mIsGroupedTask && mDp.isTablet; boolean showGroupActions = mIsGroupedTask && mDp.isTablet && mCanSaveAppPair; getActionsAlphas().get(INDEX_GROUPED_ALPHA).setValue(showSingleTaskActions ? 1 : 0); getGroupActionsAlphas().get(INDEX_GROUPED_ALPHA).setValue(showGroupActions ? 1 : 0); } Loading
quickstep/src/com/android/quickstep/views/RecentsView.java +6 −2 Original line number Diff line number Diff line Loading @@ -4023,7 +4023,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T * * Device is large screen */ private void updateCurrentTaskActionsVisibility() { boolean isCurrentSplit = getCurrentPageTaskView() instanceof GroupedTaskView; TaskView taskView = getCurrentPageTaskView(); boolean isCurrentSplit = taskView instanceof GroupedTaskView; GroupedTaskView groupedTaskView = isCurrentSplit ? (GroupedTaskView) taskView : null; // Update flags to see if entire actions bar should be hidden. if (!FeatureFlags.enableAppPairs()) { mActionsView.updateHiddenFlags(HIDDEN_SPLIT_SCREEN, isCurrentSplit); Loading @@ -4031,7 +4033,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mActionsView.updateHiddenFlags(HIDDEN_SPLIT_SELECT_ACTIVE, isSplitSelectionActive()); // Update flags to see if actions bar should show buttons for a single task or a pair of // tasks. mActionsView.updateForGroupedTask(isCurrentSplit); boolean canSaveAppPair = isCurrentSplit && supportsAppPairs() && getSplitSelectController().getAppPairsController().canSaveAppPair(groupedTaskView); mActionsView.updateForGroupedTask(isCurrentSplit, canSaveAppPair); if (isDesktopModeSupported()) { boolean isCurrentDesktop = getCurrentPageTaskView() instanceof DesktopTaskView; Loading
res/values/config.xml +7 −0 Original line number Diff line number Diff line Loading @@ -274,4 +274,11 @@ <string-array name="skip_private_profile_shortcut_packages" translatable="false"> <item>com.android.settings</item> </string-array> <!-- Legacy list of components supporting multiple instances. DO NOT ADD TO THIS LIST. Apps should use the PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI property to declare multi-instance support in V+. This resource should match the resource of the same name in SystemUI. --> <string-array name="config_appsSupportMultiInstancesSplit"> </string-array> </resources>