Loading quickstep/src/com/android/quickstep/TaskShortcutFactory.java +5 −5 Original line number Diff line number Diff line Loading @@ -128,19 +128,19 @@ public interface TaskShortcutFactory { * A menu item, "Save app pair", that allows the user to preserve the current app combination as * a single persistent icon on the Home screen, allowing for quick split screen initialization. */ class SaveAppPairSystemShortcut extends SystemShortcut { class SaveAppPairSystemShortcut extends SystemShortcut<BaseDraggingActivity> { private final TaskView mTaskView; public SaveAppPairSystemShortcut(BaseDraggingActivity target, TaskView taskView) { super(R.drawable.ic_save_app_pair, R.string.save_app_pair, target, public SaveAppPairSystemShortcut(BaseDraggingActivity activity, TaskView taskView) { super(R.drawable.ic_save_app_pair, R.string.save_app_pair, activity, taskView.getItemInfo(), taskView); mTaskView = taskView; } @Override public void onClick(View view) { // TODO (b/274189428): Call "saveAppPair" function in new AppPairController class ((RecentsView) mTarget.getOverviewPanel()) .getSplitSelectController().getAppPairsController().saveAppPair(mTaskView); } } Loading quickstep/src/com/android/quickstep/util/AppPairsController.java 0 → 100644 +104 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.quickstep.util; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import android.content.Context; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; import com.android.launcher3.icons.IconCache; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.quickstep.views.TaskView; /** * Mini controller class that handles app pair interactions: saving, modifying, deleting, etc. */ public class AppPairsController { private static final int POINT_THREE_RATIO = 0; private static final int POINT_FIVE_RATIO = 1; private static final int POINT_SEVEN_RATIO = 2; /** * Used to calculate {@link #complement(int)} */ private static final int FULL_RATIO = 2; private static final int LEFT_TOP = 0; private static final int RIGHT_BOTTOM = 1 << 2; // TODO (jeremysim b/274189428): Support saving different ratios in future. public int DEFAULT_RATIO = POINT_FIVE_RATIO; private final Context mContext; private final SplitSelectStateController mSplitSelectStateController; public AppPairsController(Context context, SplitSelectStateController splitSelectStateController) { mContext = context; mSplitSelectStateController = splitSelectStateController; } /** * Creates a new app pair ItemInfo and adds it to the workspace */ public void saveAppPair(TaskView taskView) { TaskView.TaskIdAttributeContainer[] attributes = taskView.getTaskIdAttributeContainers(); WorkspaceItemInfo app1 = attributes[0].getItemInfo().clone(); WorkspaceItemInfo app2 = attributes[1].getItemInfo().clone(); app1.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; app2.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; app1.rank = DEFAULT_RATIO + LEFT_TOP; app2.rank = complement(DEFAULT_RATIO) + RIGHT_BOTTOM; FolderInfo newAppPair = FolderInfo.createAppPair(app1, app2); // TODO (jeremysim b/274189428): Generate default title here. newAppPair.title = "App pair 1"; IconCache iconCache = LauncherAppState.getInstance(mContext).getIconCache(); MODEL_EXECUTOR.execute(() -> { newAppPair.contents.forEach(member -> { member.title = ""; member.bitmap = iconCache.getDefaultIcon(newAppPair.user); iconCache.getTitleAndIcon(member, member.usingLowResIcon()); }); MAIN_EXECUTOR.execute(() -> { LauncherAccessibilityDelegate delegate = Launcher.getLauncher(mContext).getAccessibilityDelegate(); if (delegate != null) { MAIN_EXECUTOR.execute(() -> delegate.addToWorkspace(newAppPair, true)); } }); }); } /** * Used to calculate the "opposite" side of the split ratio, so we can know how big the split * apps are supposed to be. This math works because POINT_THREE_RATIO is internally represented * by 0, POINT_FIVE_RATIO is represented by 1, and POINT_SEVEN_RATIO is represented by 2. There * are no other supported ratios for now. */ private int complement(int ratio1) { int ratio2 = FULL_RATIO - ratio1; return ratio2; } } quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +6 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ public class SplitSelectStateController { private final Handler mHandler; private final RecentsModel mRecentTasksModel; private final SplitAnimationController mSplitAnimationController; private final AppPairsController mAppPairsController; private StatsLogManager mStatsLogManager; private final SystemUiProxy mSystemUiProxy; private final StateManager mStateManager; Loading Loading @@ -128,6 +129,7 @@ public class SplitSelectStateController { mDepthController = depthController; mRecentTasksModel = recentsModel; mSplitAnimationController = new SplitAnimationController(this); mAppPairsController = new AppPairsController(context, this); } /** Loading Loading @@ -587,4 +589,8 @@ public class SplitSelectStateController { public FloatingTaskView getFirstFloatingTaskView() { return mFirstFloatingTaskView; } public AppPairsController getAppPairsController() { return mAppPairsController; } } src/com/android/launcher3/Launcher.java +8 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,8 @@ import static com.android.launcher3.popup.SystemShortcut.INSTALL; import static com.android.launcher3.popup.SystemShortcut.WIDGETS; import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK; import static com.android.launcher3.states.RotationHelper.REQUEST_NONE; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import static com.android.launcher3.util.ItemInfoMatcher.forFolderMatch; import android.animation.Animator; Loading Loading @@ -2414,6 +2416,12 @@ public class Launcher extends StatefulActivity<LauncherState> (FolderInfo) item); break; } case LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR: { FolderInfo info = (FolderInfo) item; // TODO (jeremysim b/274189428): Create app pair icon view = null; break; } case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: { view = inflateAppWidget((LauncherAppWidgetInfo) item); Loading src/com/android/launcher3/LauncherSettings.java +5 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,10 @@ public class LauncherSettings { */ public static final int ITEM_TYPE_DEEP_SHORTCUT = 6; /** * The favorite is an app pair for launching split screen */ public static final int ITEM_TYPE_APP_PAIR = 10; // *** Below enum values are used for metrics purpose but not used in Favorites DB *** Loading Loading @@ -233,6 +237,7 @@ public class LauncherSettings { case ITEM_TYPE_DEEP_SHORTCUT: return "DEEPSHORTCUT"; case ITEM_TYPE_TASK: return "TASK"; case ITEM_TYPE_QSB: return "QSB"; case ITEM_TYPE_APP_PAIR: return "APP_PAIR"; default: return String.valueOf(type); } } Loading Loading
quickstep/src/com/android/quickstep/TaskShortcutFactory.java +5 −5 Original line number Diff line number Diff line Loading @@ -128,19 +128,19 @@ public interface TaskShortcutFactory { * A menu item, "Save app pair", that allows the user to preserve the current app combination as * a single persistent icon on the Home screen, allowing for quick split screen initialization. */ class SaveAppPairSystemShortcut extends SystemShortcut { class SaveAppPairSystemShortcut extends SystemShortcut<BaseDraggingActivity> { private final TaskView mTaskView; public SaveAppPairSystemShortcut(BaseDraggingActivity target, TaskView taskView) { super(R.drawable.ic_save_app_pair, R.string.save_app_pair, target, public SaveAppPairSystemShortcut(BaseDraggingActivity activity, TaskView taskView) { super(R.drawable.ic_save_app_pair, R.string.save_app_pair, activity, taskView.getItemInfo(), taskView); mTaskView = taskView; } @Override public void onClick(View view) { // TODO (b/274189428): Call "saveAppPair" function in new AppPairController class ((RecentsView) mTarget.getOverviewPanel()) .getSplitSelectController().getAppPairsController().saveAppPair(mTaskView); } } Loading
quickstep/src/com/android/quickstep/util/AppPairsController.java 0 → 100644 +104 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.quickstep.util; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import android.content.Context; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; import com.android.launcher3.icons.IconCache; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.quickstep.views.TaskView; /** * Mini controller class that handles app pair interactions: saving, modifying, deleting, etc. */ public class AppPairsController { private static final int POINT_THREE_RATIO = 0; private static final int POINT_FIVE_RATIO = 1; private static final int POINT_SEVEN_RATIO = 2; /** * Used to calculate {@link #complement(int)} */ private static final int FULL_RATIO = 2; private static final int LEFT_TOP = 0; private static final int RIGHT_BOTTOM = 1 << 2; // TODO (jeremysim b/274189428): Support saving different ratios in future. public int DEFAULT_RATIO = POINT_FIVE_RATIO; private final Context mContext; private final SplitSelectStateController mSplitSelectStateController; public AppPairsController(Context context, SplitSelectStateController splitSelectStateController) { mContext = context; mSplitSelectStateController = splitSelectStateController; } /** * Creates a new app pair ItemInfo and adds it to the workspace */ public void saveAppPair(TaskView taskView) { TaskView.TaskIdAttributeContainer[] attributes = taskView.getTaskIdAttributeContainers(); WorkspaceItemInfo app1 = attributes[0].getItemInfo().clone(); WorkspaceItemInfo app2 = attributes[1].getItemInfo().clone(); app1.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; app2.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; app1.rank = DEFAULT_RATIO + LEFT_TOP; app2.rank = complement(DEFAULT_RATIO) + RIGHT_BOTTOM; FolderInfo newAppPair = FolderInfo.createAppPair(app1, app2); // TODO (jeremysim b/274189428): Generate default title here. newAppPair.title = "App pair 1"; IconCache iconCache = LauncherAppState.getInstance(mContext).getIconCache(); MODEL_EXECUTOR.execute(() -> { newAppPair.contents.forEach(member -> { member.title = ""; member.bitmap = iconCache.getDefaultIcon(newAppPair.user); iconCache.getTitleAndIcon(member, member.usingLowResIcon()); }); MAIN_EXECUTOR.execute(() -> { LauncherAccessibilityDelegate delegate = Launcher.getLauncher(mContext).getAccessibilityDelegate(); if (delegate != null) { MAIN_EXECUTOR.execute(() -> delegate.addToWorkspace(newAppPair, true)); } }); }); } /** * Used to calculate the "opposite" side of the split ratio, so we can know how big the split * apps are supposed to be. This math works because POINT_THREE_RATIO is internally represented * by 0, POINT_FIVE_RATIO is represented by 1, and POINT_SEVEN_RATIO is represented by 2. There * are no other supported ratios for now. */ private int complement(int ratio1) { int ratio2 = FULL_RATIO - ratio1; return ratio2; } }
quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +6 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ public class SplitSelectStateController { private final Handler mHandler; private final RecentsModel mRecentTasksModel; private final SplitAnimationController mSplitAnimationController; private final AppPairsController mAppPairsController; private StatsLogManager mStatsLogManager; private final SystemUiProxy mSystemUiProxy; private final StateManager mStateManager; Loading Loading @@ -128,6 +129,7 @@ public class SplitSelectStateController { mDepthController = depthController; mRecentTasksModel = recentsModel; mSplitAnimationController = new SplitAnimationController(this); mAppPairsController = new AppPairsController(context, this); } /** Loading Loading @@ -587,4 +589,8 @@ public class SplitSelectStateController { public FloatingTaskView getFirstFloatingTaskView() { return mFirstFloatingTaskView; } public AppPairsController getAppPairsController() { return mAppPairsController; } }
src/com/android/launcher3/Launcher.java +8 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,8 @@ import static com.android.launcher3.popup.SystemShortcut.INSTALL; import static com.android.launcher3.popup.SystemShortcut.WIDGETS; import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK; import static com.android.launcher3.states.RotationHelper.REQUEST_NONE; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import static com.android.launcher3.util.ItemInfoMatcher.forFolderMatch; import android.animation.Animator; Loading Loading @@ -2414,6 +2416,12 @@ public class Launcher extends StatefulActivity<LauncherState> (FolderInfo) item); break; } case LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR: { FolderInfo info = (FolderInfo) item; // TODO (jeremysim b/274189428): Create app pair icon view = null; break; } case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: { view = inflateAppWidget((LauncherAppWidgetInfo) item); Loading
src/com/android/launcher3/LauncherSettings.java +5 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,10 @@ public class LauncherSettings { */ public static final int ITEM_TYPE_DEEP_SHORTCUT = 6; /** * The favorite is an app pair for launching split screen */ public static final int ITEM_TYPE_APP_PAIR = 10; // *** Below enum values are used for metrics purpose but not used in Favorites DB *** Loading Loading @@ -233,6 +237,7 @@ public class LauncherSettings { case ITEM_TYPE_DEEP_SHORTCUT: return "DEEPSHORTCUT"; case ITEM_TYPE_TASK: return "TASK"; case ITEM_TYPE_QSB: return "QSB"; case ITEM_TYPE_APP_PAIR: return "APP_PAIR"; default: return String.valueOf(type); } } Loading