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

Commit 711c596c authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Binding Taskbar directly from Launcher model

This allows taskbar to be loaded even in case of 3P Launchers
and removes dependency on LauncherActivity lifecycle

Bug: 187353581
Bug: 188788621
Test: Manual
Change-Id: I5a0988e0697b41677d4c58f0213aef14ec0c0972
parent d642b651
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -262,10 +262,6 @@ public class HotseatPredictionController implements DragController.DragListener,
        } else {
            removeOutlineDrawings();
        }

        if (mLauncher.getTaskbarUIController() != null) {
            mLauncher.getTaskbarUIController().onHotseatUpdated();
        }
    }

    private void removeOutlineDrawings() {
+0 −12
Original line number Diff line number Diff line
@@ -48,7 +48,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController {

    private final BaseQuickstepLauncher mLauncher;
    private final TaskbarStateHandler mTaskbarStateHandler;
    private final TaskbarHotseatController mHotseatController;

    private final TaskbarActivityContext mContext;
    private final TaskbarDragLayer mTaskbarDragLayer;
@@ -77,8 +76,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController {

        mLauncher = launcher;
        mTaskbarStateHandler = mLauncher.getTaskbarStateHandler();
        mHotseatController = new TaskbarHotseatController(
                mLauncher, mTaskbarView::updateHotseatItems);
    }

    @Override
@@ -91,7 +88,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
        MultiValueAlpha taskbarIconAlpha = mControllers.taskbarViewController.getTaskbarIconAlpha();
        mIconAlphaForHome = taskbarIconAlpha.getProperty(ALPHA_INDEX_HOME);

        mHotseatController.init();
        mLauncher.setTaskbarUIController(this);
        mKeyguardController = taskbarControllers.taskbarKeyguardController;

@@ -106,7 +102,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
        mIconAlignmentForResumedState.finishAnimation();
        mIconAlignmentForGestureState.finishAnimation();

        mHotseatController.cleanup();
        mLauncher.getHotseat().setIconsAlpha(1f);
        mLauncher.setTaskbarUIController(null);
    }
@@ -243,13 +238,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
        return mControllers.taskbarStashController.onLongPressToUnstashTaskbar();
    }

    /**
     * Should be called when one or more items in the Hotseat have changed.
     */
    public void onHotseatUpdated() {
        mHotseatController.onHotseatUpdated();
    }

    /**
     * @param ev MotionEvent in screen coordinates.
     * @return Whether any Taskbar item could handle the given MotionEvent if given the chance.
+1 −0
Original line number Diff line number Diff line
@@ -85,5 +85,6 @@ public class TaskbarControllers {
        rotationButtonController.onDestroy();
        taskbarDragLayerController.onDestroy();
        taskbarKeyguardController.onDestroy();
        taskbarViewController.onDestroy();
    }
}
+0 −91
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.launcher3.taskbar;

import android.view.View;

import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DropTarget;
import com.android.launcher3.Hotseat;
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.model.data.ItemInfo;

import java.util.function.Consumer;

/**
 * Works with TaskbarController to update the TaskbarView's Hotseat items.
 */
public class TaskbarHotseatController {

    private final BaseQuickstepLauncher mLauncher;
    private final Hotseat mHotseat;
    private final Consumer<ItemInfo[]> mTaskbarCallbacks;
    private final int mNumHotseatIcons;

    private final DragController.DragListener mDragListener = new DragController.DragListener() {
        @Override
        public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { }

        @Override
        public void onDragEnd() {
            onHotseatUpdated();
        }
    };

    public TaskbarHotseatController(
            BaseQuickstepLauncher launcher, Consumer<ItemInfo[]> taskbarCallbacks) {
        mLauncher = launcher;
        mHotseat = mLauncher.getHotseat();
        mTaskbarCallbacks = taskbarCallbacks;
        mNumHotseatIcons = mLauncher.getDeviceProfile().numShownHotseatIcons;
    }

    protected void init() {
        mLauncher.getDragController().addDragListener(mDragListener);
        onHotseatUpdated();
    }

    protected void cleanup() {
        mLauncher.getDragController().removeDragListener(mDragListener);
    }

    /**
     * Called when any Hotseat item changes, and reports the new list of items to TaskbarController.
     */
    protected void onHotseatUpdated() {
        ShortcutAndWidgetContainer shortcutsAndWidgets = mHotseat.getShortcutsAndWidgets();
        ItemInfo[] hotseatItemInfos = new ItemInfo[mNumHotseatIcons];
        for (int i = 0; i < shortcutsAndWidgets.getChildCount(); i++) {
            View child = shortcutsAndWidgets.getChildAt(i);
            Object tag = shortcutsAndWidgets.getChildAt(i).getTag();
            if (tag instanceof ItemInfo) {
                ItemInfo itemInfo = (ItemInfo) tag;
                CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
                // Since the hotseat might be laid out vertically or horizontally, use whichever
                // index is higher.
                int index = Math.max(lp.cellX, lp.cellY);
                if (0 <= index && index < hotseatItemInfos.length) {
                    hotseatItemInfos[index] = itemInfo;
                }
            }
        }

        mTaskbarCallbacks.accept(hotseatItemInfos);
    }
}
+174 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.launcher3.taskbar;

import android.util.SparseArray;
import android.view.View;

import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.LauncherBindableItemsContainer;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

/**
 * Launcher model Callbacks for rendering taskbar.
 */
public class TaskbarModelCallbacks implements
        BgDataModel.Callbacks, LauncherBindableItemsContainer {

    private final SparseArray<ItemInfo> mHotseatItems = new SparseArray<>();
    private List<ItemInfo> mPredictedItems = Collections.emptyList();

    private final TaskbarActivityContext mContext;
    private final TaskbarView mContainer;

    private boolean mBindInProgress = false;

    public TaskbarModelCallbacks(
            TaskbarActivityContext context, TaskbarView container) {
        mContext = context;
        mContainer = container;
    }

    @Override
    public void startBinding() {
        mBindInProgress = true;
        mHotseatItems.clear();
        mPredictedItems = Collections.emptyList();
    }

    @Override
    public void finishBindingItems(IntSet pagesBoundFirst) {
        mBindInProgress = false;
        commitItemsToUI();
    }

    @Override
    public void bindAppsAdded(IntArray newScreens, ArrayList<ItemInfo> addNotAnimated,
            ArrayList<ItemInfo> addAnimated) {
        boolean add1 = handleItemsAdded(addNotAnimated);
        boolean add2 = handleItemsAdded(addAnimated);
        if (add1 || add2) {
            commitItemsToUI();
        }
    }

    @Override
    public void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) {
        if (handleItemsAdded(shortcuts)) {
            commitItemsToUI();
        }
    }

    private boolean handleItemsAdded(List<ItemInfo> items) {
        boolean modified = false;
        for (ItemInfo item : items) {
            if (item.container == Favorites.CONTAINER_HOTSEAT) {
                mHotseatItems.put(item.screenId, item);
                modified = true;
            }
        }
        return modified;
    }


    @Override
    public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) {
        updateWorkspaceItems(updated, mContext);
    }

    @Override
    public void bindRestoreItemsChange(HashSet<ItemInfo> updates) {
        updateRestoreItems(updates, mContext);
    }

    @Override
    public void mapOverItems(ItemOperator op) {
        final int itemCount = mContainer.getChildCount();
        for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) {
            View item = mContainer.getChildAt(itemIdx);
            if (op.evaluate((ItemInfo) item.getTag(), item)) {
                return;
            }
        }
    }

    @Override
    public void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher) {
        if (handleItemsRemoved(matcher)) {
            commitItemsToUI();
        }
    }

    private boolean handleItemsRemoved(ItemInfoMatcher matcher) {
        boolean modified = false;
        for (int i = mHotseatItems.size() - 1; i >= 0; i--) {
            if (matcher.matchesInfo(mHotseatItems.valueAt(i))) {
                modified = true;
                mHotseatItems.removeAt(i);
            }
        }
        return modified;
    }

    @Override
    public void bindItemsModified(List<ItemInfo> items) {
        boolean removed = handleItemsRemoved(ItemInfoMatcher.ofItems(items));
        boolean added = handleItemsAdded(items);
        if (removed || added) {
            commitItemsToUI();
        }
    }

    @Override
    public void bindExtraContainerItems(FixedContainerItems item) {
        if (item.containerId == Favorites.CONTAINER_HOTSEAT_PREDICTION) {
            mPredictedItems = item.items;
            commitItemsToUI();
        }
    }

    private void commitItemsToUI() {
        if (mBindInProgress) {
            return;
        }

        ItemInfo[] hotseatItemInfos =
                new ItemInfo[mContext.getDeviceProfile().numShownHotseatIcons];
        int predictionSize = mPredictedItems.size();
        int predictionNextIndex = 0;

        for (int i = 0; i < hotseatItemInfos.length; i++) {
            hotseatItemInfos[i] = mHotseatItems.get(i);
            if (hotseatItemInfos[i] == null && predictionNextIndex < predictionSize) {
                hotseatItemInfos[i] = mPredictedItems.get(predictionNextIndex);
                hotseatItemInfos[i].screenId = i;
                predictionNextIndex++;
            }
        }
        mContainer.updateHotseatItems(hotseatItemInfos);
    }
}
Loading