Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dab51b76 authored by James O'Leary's avatar James O'Leary Committed by Automerger Merge Worker
Browse files

Merging from ub-launcher3-rvc-dev @ build 6469858 am: fe68c9ee

Change-Id: I4a7de539c323b1e6064e53186a0b4e90b8bfa096
parents ebfbffd0 fe68c9ee
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -156,7 +156,6 @@
        <provider
            android:name="com.android.launcher3.graphics.GridOptionsProvider"
            android:authorities="${packageName}.grid_control"
            android:enabled="false"
            android:exported="true" />

        <!--
+25 −17
Original line number Diff line number Diff line
@@ -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 {
@@ -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
@@ -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 {
@@ -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;
  }
}

+3 −6
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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);

@@ -151,6 +147,7 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti

        return () -> {
            overview.setFreezeViewVisibility(false);
            overview.setTranslationY(0);
            mLauncher.getStateManager().reapplyState();
        };
    }
+32 −35
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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";

@@ -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;

@@ -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();
    }

    /**
@@ -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
@@ -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() {
@@ -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);
+82 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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 {
@@ -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();
@@ -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);
@@ -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
@@ -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