Loading AndroidManifest-common.xml +0 −1 Original line number Diff line number Diff line Loading @@ -156,7 +156,6 @@ <provider android:name="com.android.launcher3.graphics.GridOptionsProvider" android:authorities="${packageName}.grid_control" android:enabled="false" android:exported="true" /> <!-- Loading protos/launcher_atom.proto +25 −17 Original line number Diff line number Diff line Loading @@ -34,13 +34,23 @@ message ItemInfo { optional bool is_work = 6; // Item can be child node to parent container or parent containers (nested) optional ContainerInfo container_info = 7; // Stores the origin of the Item optional Origin source = 8; } // Represents various launcher surface where items are placed. message ContainerInfo { oneof Container { WorkspaceContainer workspace = 7; HotseatContainer hotseat = 8; FolderContainer folder = 9; WorkspaceContainer workspace = 1; HotseatContainer hotseat = 2; FolderContainer folder = 3; AllAppsContainer all_apps_container = 4; } // Stores the origin of the Item optional Origin source = 10; } message AllAppsContainer { } enum Origin { Loading Loading @@ -68,8 +78,8 @@ message Shortcut { // AppWidgets handled by AppWidgetManager message Widget { optional int32 span_x = 1; optional int32 span_y = 2; optional int32 span_x = 1 [default = 1]; optional int32 span_y = 2 [default = 1]; optional int32 app_widget_id = 3; optional string package_name = 4; // only populated during snapshot if from workspace optional string component_name = 5; // only populated during snapshot if from workspace Loading @@ -86,9 +96,9 @@ message Task { // Containers message WorkspaceContainer { optional int32 page_index = 1; // range [-1, l], 0 is the index of the main homescreen optional int32 grid_x = 2; // [0, m], m varies based on the display density and resolution optional int32 grid_y = 3; // [0, n], n varies based on the display density and resolution optional int32 page_index = 1 [default = -2]; // range [-1, l], 0 is the index of the main homescreen optional int32 grid_x = 2 [default = -1]; // [0, m], m varies based on the display density and resolution optional int32 grid_y = 3 [default = -1]; // [0, n], n varies based on the display density and resolution } message HotseatContainer { Loading @@ -96,13 +106,11 @@ message HotseatContainer { } message FolderContainer { optional int32 page_index = 1; optional int32 grid_x = 2; optional int32 grid_y = 3; oneof Container { optional int32 page_index = 1 [default = -1]; optional int32 grid_x = 2 [default = -1]; optional int32 grid_y = 3 [default = -1]; oneof ParentContainer { WorkspaceContainer workspace = 4; HotseatContainer hotseat = 5; } } quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java +3 −6 Original line number Diff line number Diff line Loading @@ -49,7 +49,6 @@ import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.SpringAnimationBuilder; import com.android.launcher3.states.StateAnimationConfig; import com.android.quickstep.util.AppWindowAnimationHelper; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; Loading Loading @@ -86,11 +85,8 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti boolean skipLauncherChanges = !launcherClosing; TaskView taskView = findTaskViewToLaunch(mLauncher, v, appTargets); AppWindowAnimationHelper helper = new AppWindowAnimationHelper(recentsView.getPagedViewOrientedState(), mLauncher); Animator recentsAnimator = getRecentsWindowAnimator(taskView, skipLauncherChanges, appTargets, wallpaperTargets, mLauncher.getDepthController(), helper); appTargets, wallpaperTargets, mLauncher.getDepthController()); anim.play(recentsAnimator.setDuration(RECENTS_LAUNCH_DURATION)); Animator childStateAnimation = null; Loading @@ -98,7 +94,7 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti Animator launcherAnim; final AnimatorListenerAdapter windowAnimEndListener; if (launcherClosing) { launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView, helper); launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView); launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR); launcherAnim.setDuration(RECENTS_LAUNCH_DURATION); Loading Loading @@ -151,6 +147,7 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti return () -> { overview.setFreezeViewVisibility(false); overview.setTranslationY(0); mLauncher.getStateManager().reapplyState(); }; } Loading quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java +32 −35 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.launcher3.DropTarget; import com.android.launcher3.Hotseat; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherState; import com.android.launcher3.R; Loading @@ -56,6 +57,7 @@ import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.icons.IconCache; import com.android.launcher3.logging.FileLog; import com.android.launcher3.model.PredictionModel; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.ItemInfo; Loading @@ -69,6 +71,7 @@ import com.android.launcher3.uioverrides.PredictedAppIcon; import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.IntArray; import java.lang.ref.WeakReference; import java.util.ArrayList; Loading @@ -93,8 +96,6 @@ public class HotseatPredictionController implements DragController.DragListener, //TODO: replace this with AppTargetEvent.ACTION_UNPIN (b/144119543) private static final int APPTARGET_ACTION_UNPIN = 4; private static final String PREDICTED_ITEMS_CACHE_KEY = "predicted_item_keys"; private static final String APP_LOCATION_HOTSEAT = "hotseat"; private static final String APP_LOCATION_WORKSPACE = "workspace"; Loading @@ -115,11 +116,13 @@ public class HotseatPredictionController implements DragController.DragListener, private DynamicItemCache mDynamicItemCache; private final PredictionModel mPredictionModel; private AppPredictor mAppPredictor; private AllAppsStore mAllAppsStore; private AnimatorSet mIconRemoveAnimators; private boolean mUIUpdatePaused = false; private boolean mRequiresCacheUpdate = false; private boolean mRequiresCacheUpdate = true; private boolean mIsCacheEmpty; private HotseatEduController mHotseatEduController; Loading @@ -138,15 +141,16 @@ public class HotseatPredictionController implements DragController.DragListener, mLauncher = launcher; mHotseat = launcher.getHotseat(); mAllAppsStore = mLauncher.getAppsView().getAppsStore(); mPredictionModel = LauncherAppState.INSTANCE.get(launcher).getPredictionModel(); mAllAppsStore.addUpdateListener(this); mDynamicItemCache = new DynamicItemCache(mLauncher, this::fillGapsWithPrediction); mHotSeatItemsCount = mLauncher.getDeviceProfile().inv.numHotseatIcons; launcher.getDeviceProfile().inv.addOnChangeListener(this); mHotseat.addOnAttachStateChangeListener(this); mIsCacheEmpty = mPredictionModel.getPredictionComponentKeys().isEmpty(); if (mHotseat.isAttachedToWindow()) { onViewAttachedToWindow(mHotseat); } showCachedItems(); } /** Loading Loading @@ -185,6 +189,11 @@ public class HotseatPredictionController implements DragController.DragListener, return; } List<WorkspaceItemInfo> predictedApps = mapToWorkspaceItemInfo(mComponentKeyMappers); if (mComponentKeyMappers.isEmpty() != predictedApps.isEmpty()) { // Safely ignore update as AppsList is not ready yet. This will called again once // apps are ready (HotseatPredictionController#onAppsUpdated) return; } int predictionIndex = 0; ArrayList<WorkspaceItemInfo> newItems = new ArrayList<>(); // make sure predicted icon removal and filling predictions don't step on each other Loading Loading @@ -305,14 +314,23 @@ public class HotseatPredictionController implements DragController.DragListener, mAppPredictor.requestPredictionUpdate(); } private void showCachedItems() { ArrayList<ComponentKey> componentKeys = getCachedComponentKeys(); /** * Create WorkspaceItemInfo objects and binds PredictedAppIcon views for cached predicted items. */ public void showCachedItems(List<AppInfo> apps, IntArray ranks) { int count = Math.min(ranks.size(), apps.size()); List<WorkspaceItemInfo> items = new ArrayList<>(count); for (int i = 0; i < count; i++) { WorkspaceItemInfo item = new WorkspaceItemInfo(apps.get(i)); preparePredictionInfo(item, ranks.get(i)); items.add(item); } mComponentKeyMappers.clear(); for (ComponentKey key : componentKeys) { for (ComponentKey key : mPredictionModel.getPredictionComponentKeys()) { mComponentKeyMappers.add(new ComponentKeyMapper(key, mDynamicItemCache)); } updateDependencies(); fillGapsWithPrediction(); bindItems(items, false, null); } private Bundle getAppPredictionContextExtra() { Loading Loading @@ -394,37 +412,16 @@ public class HotseatPredictionController implements DragController.DragListener, if (!isEduSeen() && mHotseatEduController != null) { mHotseatEduController.setPredictedApps(mapToWorkspaceItemInfo(mComponentKeyMappers)); } // should invalidate cache if AiAi sends empty list of AppTargets if (appTargets.isEmpty()) { mRequiresCacheUpdate = true; } cachePredictionComponentKeys(componentKeys); cachePredictionComponentKeysIfNecessary(componentKeys); } private void cachePredictionComponentKeys(ArrayList<ComponentKey> componentKeys) { if (!mRequiresCacheUpdate) return; StringBuilder builder = new StringBuilder(); for (ComponentKey componentKey : componentKeys) { builder.append(componentKey); builder.append("\n"); } mLauncher.getDevicePrefs().edit().putString(PREDICTED_ITEMS_CACHE_KEY, builder.toString()).apply(); private void cachePredictionComponentKeysIfNecessary(ArrayList<ComponentKey> componentKeys) { if (!mRequiresCacheUpdate && componentKeys.isEmpty() == mIsCacheEmpty) return; mPredictionModel.cachePredictionComponentKeys(componentKeys); mIsCacheEmpty = componentKeys.isEmpty(); mRequiresCacheUpdate = false; } private ArrayList<ComponentKey> getCachedComponentKeys() { String cachedBlob = mLauncher.getDevicePrefs().getString(PREDICTED_ITEMS_CACHE_KEY, ""); ArrayList<ComponentKey> results = new ArrayList<>(); for (String line : cachedBlob.split("\n")) { ComponentKey key = ComponentKey.fromString(line); if (key != null) { results.add(key); } } return results; } private void updateDependencies() { mDynamicItemCache.updateDependencies(mComponentKeyMappers, mAllAppsStore, this, mHotSeatItemsCount); Loading quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +82 −1 Original line number Diff line number Diff line Loading @@ -15,8 +15,16 @@ */ package com.android.launcher3.uioverrides; import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK; import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent; import static com.android.launcher3.testing.TestProtocol.HINT_STATE_ORDINAL; import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL; import static com.android.launcher3.testing.TestProtocol.QUICK_SWITCH_STATE_ORDINAL; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import android.content.Intent; Loading @@ -30,10 +38,13 @@ import com.android.launcher3.BaseQuickstepLauncher; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.Workspace; import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.folder.Folder; import com.android.launcher3.hybridhotseat.HotseatPredictionController; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.popup.SystemShortcut; Loading @@ -48,6 +59,7 @@ import com.android.launcher3.uioverrides.touchcontrollers.QuickSwitchTouchContro import com.android.launcher3.uioverrides.touchcontrollers.StatusBarTouchController; import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController; import com.android.launcher3.uioverrides.touchcontrollers.TransposedQuickSwitchTouchController; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.TouchController; import com.android.launcher3.util.UiThreadHelper; import com.android.launcher3.util.UiThreadHelper.AsyncCommand; Loading @@ -56,8 +68,12 @@ import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; public class QuickstepLauncher extends BaseQuickstepLauncher { Loading Loading @@ -165,6 +181,14 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { } } @Override public void bindPredictedItems(List<AppInfo> appInfos, IntArray ranks) { super.bindPredictedItems(appInfos, ranks); if (mHotseatPredictionController != null) { mHotseatPredictionController.showCachedItems(appInfos, ranks); } } @Override public void onDestroy() { super.onDestroy(); Loading @@ -174,6 +198,49 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { } } @Override public void onStateSetEnd(LauncherState state) { super.onStateSetEnd(state); switch (state.ordinal) { case HINT_STATE_ORDINAL: { Workspace workspace = getWorkspace(); boolean willMoveScreens = workspace.getNextPage() != Workspace.DEFAULT_PAGE; getStateManager().goToState(NORMAL, true, willMoveScreens ? null : getScrimView()::startDragHandleEducationAnim); if (willMoveScreens) { workspace.post(workspace::moveToDefaultScreen); } break; } case OVERVIEW_STATE_ORDINAL: { DiscoveryBounce.showForOverviewIfNeeded(this); RecentsView rv = getOverviewPanel(); sendCustomAccessibilityEvent( rv.getPageAt(rv.getCurrentPage()), TYPE_VIEW_FOCUSED, null); break; } case QUICK_SWITCH_STATE_ORDINAL: { RecentsView rv = getOverviewPanel(); TaskView tasktolaunch = rv.getTaskViewAt(0); if (tasktolaunch != null) { tasktolaunch.launchTask(false, success -> { if (!success) { getStateManager().goToState(OVERVIEW); tasktolaunch.notifyTaskLaunchFailed(TAG); } else { getStateManager().moveToRestState(); } }, MAIN_EXECUTOR.getHandler()); } else { getStateManager().goToState(NORMAL); } break; } } } @Override public TouchController[] createTouchControllers() { Mode mode = SysUINavigationMode.getMode(this); Loading Loading @@ -221,7 +288,12 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { @Override protected boolean isRecentsInteractive() { return mActivity.isInState(OVERVIEW); return mActivity.isInState(OVERVIEW) || mActivity.isInState(OVERVIEW_MODAL_TASK); } @Override protected boolean isRecentsModal() { return mActivity.isInState(OVERVIEW_MODAL_TASK); } @Override Loading @@ -229,4 +301,13 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { mActivity.getStateManager().setCurrentUserControlledAnimation(animController); } } @Override public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { super.dump(prefix, fd, writer, args); RecentsView recentsView = getOverviewPanel(); writer.println("\nQuickstepLauncher:"); writer.println(prefix + "\tmOrientationState: " + (recentsView == null ? "recentsNull" : recentsView.getPagedViewOrientedState())); } } Loading
AndroidManifest-common.xml +0 −1 Original line number Diff line number Diff line Loading @@ -156,7 +156,6 @@ <provider android:name="com.android.launcher3.graphics.GridOptionsProvider" android:authorities="${packageName}.grid_control" android:enabled="false" android:exported="true" /> <!-- Loading
protos/launcher_atom.proto +25 −17 Original line number Diff line number Diff line Loading @@ -34,13 +34,23 @@ message ItemInfo { optional bool is_work = 6; // Item can be child node to parent container or parent containers (nested) optional ContainerInfo container_info = 7; // Stores the origin of the Item optional Origin source = 8; } // Represents various launcher surface where items are placed. message ContainerInfo { oneof Container { WorkspaceContainer workspace = 7; HotseatContainer hotseat = 8; FolderContainer folder = 9; WorkspaceContainer workspace = 1; HotseatContainer hotseat = 2; FolderContainer folder = 3; AllAppsContainer all_apps_container = 4; } // Stores the origin of the Item optional Origin source = 10; } message AllAppsContainer { } enum Origin { Loading Loading @@ -68,8 +78,8 @@ message Shortcut { // AppWidgets handled by AppWidgetManager message Widget { optional int32 span_x = 1; optional int32 span_y = 2; optional int32 span_x = 1 [default = 1]; optional int32 span_y = 2 [default = 1]; optional int32 app_widget_id = 3; optional string package_name = 4; // only populated during snapshot if from workspace optional string component_name = 5; // only populated during snapshot if from workspace Loading @@ -86,9 +96,9 @@ message Task { // Containers message WorkspaceContainer { optional int32 page_index = 1; // range [-1, l], 0 is the index of the main homescreen optional int32 grid_x = 2; // [0, m], m varies based on the display density and resolution optional int32 grid_y = 3; // [0, n], n varies based on the display density and resolution optional int32 page_index = 1 [default = -2]; // range [-1, l], 0 is the index of the main homescreen optional int32 grid_x = 2 [default = -1]; // [0, m], m varies based on the display density and resolution optional int32 grid_y = 3 [default = -1]; // [0, n], n varies based on the display density and resolution } message HotseatContainer { Loading @@ -96,13 +106,11 @@ message HotseatContainer { } message FolderContainer { optional int32 page_index = 1; optional int32 grid_x = 2; optional int32 grid_y = 3; oneof Container { optional int32 page_index = 1 [default = -1]; optional int32 grid_x = 2 [default = -1]; optional int32 grid_y = 3 [default = -1]; oneof ParentContainer { WorkspaceContainer workspace = 4; HotseatContainer hotseat = 5; } }
quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java +3 −6 Original line number Diff line number Diff line Loading @@ -49,7 +49,6 @@ import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.SpringAnimationBuilder; import com.android.launcher3.states.StateAnimationConfig; import com.android.quickstep.util.AppWindowAnimationHelper; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; Loading Loading @@ -86,11 +85,8 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti boolean skipLauncherChanges = !launcherClosing; TaskView taskView = findTaskViewToLaunch(mLauncher, v, appTargets); AppWindowAnimationHelper helper = new AppWindowAnimationHelper(recentsView.getPagedViewOrientedState(), mLauncher); Animator recentsAnimator = getRecentsWindowAnimator(taskView, skipLauncherChanges, appTargets, wallpaperTargets, mLauncher.getDepthController(), helper); appTargets, wallpaperTargets, mLauncher.getDepthController()); anim.play(recentsAnimator.setDuration(RECENTS_LAUNCH_DURATION)); Animator childStateAnimation = null; Loading @@ -98,7 +94,7 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti Animator launcherAnim; final AnimatorListenerAdapter windowAnimEndListener; if (launcherClosing) { launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView, helper); launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView); launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR); launcherAnim.setDuration(RECENTS_LAUNCH_DURATION); Loading Loading @@ -151,6 +147,7 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti return () -> { overview.setFreezeViewVisibility(false); overview.setTranslationY(0); mLauncher.getStateManager().reapplyState(); }; } Loading
quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java +32 −35 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.launcher3.DropTarget; import com.android.launcher3.Hotseat; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherState; import com.android.launcher3.R; Loading @@ -56,6 +57,7 @@ import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.icons.IconCache; import com.android.launcher3.logging.FileLog; import com.android.launcher3.model.PredictionModel; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.ItemInfo; Loading @@ -69,6 +71,7 @@ import com.android.launcher3.uioverrides.PredictedAppIcon; import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.IntArray; import java.lang.ref.WeakReference; import java.util.ArrayList; Loading @@ -93,8 +96,6 @@ public class HotseatPredictionController implements DragController.DragListener, //TODO: replace this with AppTargetEvent.ACTION_UNPIN (b/144119543) private static final int APPTARGET_ACTION_UNPIN = 4; private static final String PREDICTED_ITEMS_CACHE_KEY = "predicted_item_keys"; private static final String APP_LOCATION_HOTSEAT = "hotseat"; private static final String APP_LOCATION_WORKSPACE = "workspace"; Loading @@ -115,11 +116,13 @@ public class HotseatPredictionController implements DragController.DragListener, private DynamicItemCache mDynamicItemCache; private final PredictionModel mPredictionModel; private AppPredictor mAppPredictor; private AllAppsStore mAllAppsStore; private AnimatorSet mIconRemoveAnimators; private boolean mUIUpdatePaused = false; private boolean mRequiresCacheUpdate = false; private boolean mRequiresCacheUpdate = true; private boolean mIsCacheEmpty; private HotseatEduController mHotseatEduController; Loading @@ -138,15 +141,16 @@ public class HotseatPredictionController implements DragController.DragListener, mLauncher = launcher; mHotseat = launcher.getHotseat(); mAllAppsStore = mLauncher.getAppsView().getAppsStore(); mPredictionModel = LauncherAppState.INSTANCE.get(launcher).getPredictionModel(); mAllAppsStore.addUpdateListener(this); mDynamicItemCache = new DynamicItemCache(mLauncher, this::fillGapsWithPrediction); mHotSeatItemsCount = mLauncher.getDeviceProfile().inv.numHotseatIcons; launcher.getDeviceProfile().inv.addOnChangeListener(this); mHotseat.addOnAttachStateChangeListener(this); mIsCacheEmpty = mPredictionModel.getPredictionComponentKeys().isEmpty(); if (mHotseat.isAttachedToWindow()) { onViewAttachedToWindow(mHotseat); } showCachedItems(); } /** Loading Loading @@ -185,6 +189,11 @@ public class HotseatPredictionController implements DragController.DragListener, return; } List<WorkspaceItemInfo> predictedApps = mapToWorkspaceItemInfo(mComponentKeyMappers); if (mComponentKeyMappers.isEmpty() != predictedApps.isEmpty()) { // Safely ignore update as AppsList is not ready yet. This will called again once // apps are ready (HotseatPredictionController#onAppsUpdated) return; } int predictionIndex = 0; ArrayList<WorkspaceItemInfo> newItems = new ArrayList<>(); // make sure predicted icon removal and filling predictions don't step on each other Loading Loading @@ -305,14 +314,23 @@ public class HotseatPredictionController implements DragController.DragListener, mAppPredictor.requestPredictionUpdate(); } private void showCachedItems() { ArrayList<ComponentKey> componentKeys = getCachedComponentKeys(); /** * Create WorkspaceItemInfo objects and binds PredictedAppIcon views for cached predicted items. */ public void showCachedItems(List<AppInfo> apps, IntArray ranks) { int count = Math.min(ranks.size(), apps.size()); List<WorkspaceItemInfo> items = new ArrayList<>(count); for (int i = 0; i < count; i++) { WorkspaceItemInfo item = new WorkspaceItemInfo(apps.get(i)); preparePredictionInfo(item, ranks.get(i)); items.add(item); } mComponentKeyMappers.clear(); for (ComponentKey key : componentKeys) { for (ComponentKey key : mPredictionModel.getPredictionComponentKeys()) { mComponentKeyMappers.add(new ComponentKeyMapper(key, mDynamicItemCache)); } updateDependencies(); fillGapsWithPrediction(); bindItems(items, false, null); } private Bundle getAppPredictionContextExtra() { Loading Loading @@ -394,37 +412,16 @@ public class HotseatPredictionController implements DragController.DragListener, if (!isEduSeen() && mHotseatEduController != null) { mHotseatEduController.setPredictedApps(mapToWorkspaceItemInfo(mComponentKeyMappers)); } // should invalidate cache if AiAi sends empty list of AppTargets if (appTargets.isEmpty()) { mRequiresCacheUpdate = true; } cachePredictionComponentKeys(componentKeys); cachePredictionComponentKeysIfNecessary(componentKeys); } private void cachePredictionComponentKeys(ArrayList<ComponentKey> componentKeys) { if (!mRequiresCacheUpdate) return; StringBuilder builder = new StringBuilder(); for (ComponentKey componentKey : componentKeys) { builder.append(componentKey); builder.append("\n"); } mLauncher.getDevicePrefs().edit().putString(PREDICTED_ITEMS_CACHE_KEY, builder.toString()).apply(); private void cachePredictionComponentKeysIfNecessary(ArrayList<ComponentKey> componentKeys) { if (!mRequiresCacheUpdate && componentKeys.isEmpty() == mIsCacheEmpty) return; mPredictionModel.cachePredictionComponentKeys(componentKeys); mIsCacheEmpty = componentKeys.isEmpty(); mRequiresCacheUpdate = false; } private ArrayList<ComponentKey> getCachedComponentKeys() { String cachedBlob = mLauncher.getDevicePrefs().getString(PREDICTED_ITEMS_CACHE_KEY, ""); ArrayList<ComponentKey> results = new ArrayList<>(); for (String line : cachedBlob.split("\n")) { ComponentKey key = ComponentKey.fromString(line); if (key != null) { results.add(key); } } return results; } private void updateDependencies() { mDynamicItemCache.updateDependencies(mComponentKeyMappers, mAllAppsStore, this, mHotSeatItemsCount); Loading
quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +82 −1 Original line number Diff line number Diff line Loading @@ -15,8 +15,16 @@ */ package com.android.launcher3.uioverrides; import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK; import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent; import static com.android.launcher3.testing.TestProtocol.HINT_STATE_ORDINAL; import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL; import static com.android.launcher3.testing.TestProtocol.QUICK_SWITCH_STATE_ORDINAL; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import android.content.Intent; Loading @@ -30,10 +38,13 @@ import com.android.launcher3.BaseQuickstepLauncher; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.Workspace; import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.folder.Folder; import com.android.launcher3.hybridhotseat.HotseatPredictionController; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.popup.SystemShortcut; Loading @@ -48,6 +59,7 @@ import com.android.launcher3.uioverrides.touchcontrollers.QuickSwitchTouchContro import com.android.launcher3.uioverrides.touchcontrollers.StatusBarTouchController; import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController; import com.android.launcher3.uioverrides.touchcontrollers.TransposedQuickSwitchTouchController; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.TouchController; import com.android.launcher3.util.UiThreadHelper; import com.android.launcher3.util.UiThreadHelper.AsyncCommand; Loading @@ -56,8 +68,12 @@ import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; public class QuickstepLauncher extends BaseQuickstepLauncher { Loading Loading @@ -165,6 +181,14 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { } } @Override public void bindPredictedItems(List<AppInfo> appInfos, IntArray ranks) { super.bindPredictedItems(appInfos, ranks); if (mHotseatPredictionController != null) { mHotseatPredictionController.showCachedItems(appInfos, ranks); } } @Override public void onDestroy() { super.onDestroy(); Loading @@ -174,6 +198,49 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { } } @Override public void onStateSetEnd(LauncherState state) { super.onStateSetEnd(state); switch (state.ordinal) { case HINT_STATE_ORDINAL: { Workspace workspace = getWorkspace(); boolean willMoveScreens = workspace.getNextPage() != Workspace.DEFAULT_PAGE; getStateManager().goToState(NORMAL, true, willMoveScreens ? null : getScrimView()::startDragHandleEducationAnim); if (willMoveScreens) { workspace.post(workspace::moveToDefaultScreen); } break; } case OVERVIEW_STATE_ORDINAL: { DiscoveryBounce.showForOverviewIfNeeded(this); RecentsView rv = getOverviewPanel(); sendCustomAccessibilityEvent( rv.getPageAt(rv.getCurrentPage()), TYPE_VIEW_FOCUSED, null); break; } case QUICK_SWITCH_STATE_ORDINAL: { RecentsView rv = getOverviewPanel(); TaskView tasktolaunch = rv.getTaskViewAt(0); if (tasktolaunch != null) { tasktolaunch.launchTask(false, success -> { if (!success) { getStateManager().goToState(OVERVIEW); tasktolaunch.notifyTaskLaunchFailed(TAG); } else { getStateManager().moveToRestState(); } }, MAIN_EXECUTOR.getHandler()); } else { getStateManager().goToState(NORMAL); } break; } } } @Override public TouchController[] createTouchControllers() { Mode mode = SysUINavigationMode.getMode(this); Loading Loading @@ -221,7 +288,12 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { @Override protected boolean isRecentsInteractive() { return mActivity.isInState(OVERVIEW); return mActivity.isInState(OVERVIEW) || mActivity.isInState(OVERVIEW_MODAL_TASK); } @Override protected boolean isRecentsModal() { return mActivity.isInState(OVERVIEW_MODAL_TASK); } @Override Loading @@ -229,4 +301,13 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { mActivity.getStateManager().setCurrentUserControlledAnimation(animController); } } @Override public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { super.dump(prefix, fd, writer, args); RecentsView recentsView = getOverviewPanel(); writer.println("\nQuickstepLauncher:"); writer.println(prefix + "\tmOrientationState: " + (recentsView == null ? "recentsNull" : recentsView.getPagedViewOrientedState())); } }