1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.launcher3.taskbar.allapps; 17 18 import androidx.annotation.Nullable; 19 import androidx.annotation.VisibleForTesting; 20 21 import com.android.launcher3.R; 22 import com.android.launcher3.appprediction.PredictionRowView; 23 import com.android.launcher3.model.data.AppInfo; 24 import com.android.launcher3.model.data.ItemInfo; 25 import com.android.launcher3.taskbar.TaskbarControllers; 26 import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; 27 28 import java.util.List; 29 30 /** 31 * Handles the all apps overlay window initialization, updates, and its data. 32 * <p> 33 * All apps is in an application overlay window instead of taskbar's navigation bar panel window, 34 * because a navigation bar panel is higher than UI components that all apps should be below such as 35 * the notification tray. 36 * <p> 37 * The all apps window is created and destroyed upon opening and closing all apps, respectively. 38 * Application data may be bound while the window does not exist, so this controller will store 39 * the models for the next all apps session. 40 */ 41 public final class TaskbarAllAppsController { 42 43 private TaskbarControllers mControllers; 44 private @Nullable TaskbarAllAppsSlideInView mSlideInView; 45 private @Nullable TaskbarAllAppsContainerView mAppsView; 46 47 // Application data models. 48 private AppInfo[] mApps; 49 private int mAppsModelFlags; 50 private List<ItemInfo> mPredictedApps; 51 private boolean mDisallowGlobalDrag; 52 private boolean mDisallowLongClick; 53 54 /** Initialize the controller. */ init(TaskbarControllers controllers, boolean allAppsVisible)55 public void init(TaskbarControllers controllers, boolean allAppsVisible) { 56 mControllers = controllers; 57 58 /* 59 * Recreate All Apps if it was open in the previous Taskbar instance (e.g. the configuration 60 * changed). 61 */ 62 if (allAppsVisible) { 63 show(false); 64 } 65 } 66 67 /** Updates the current {@link AppInfo} instances. */ setApps(AppInfo[] apps, int flags)68 public void setApps(AppInfo[] apps, int flags) { 69 mApps = apps; 70 mAppsModelFlags = flags; 71 if (mAppsView != null) { 72 mAppsView.getAppsStore().setApps(mApps, mAppsModelFlags); 73 } 74 } 75 setDisallowGlobalDrag(boolean disableDragForOverviewState)76 public void setDisallowGlobalDrag(boolean disableDragForOverviewState) { 77 mDisallowGlobalDrag = disableDragForOverviewState; 78 } 79 setDisallowLongClick(boolean disallowLongClick)80 public void setDisallowLongClick(boolean disallowLongClick) { 81 mDisallowLongClick = disallowLongClick; 82 } 83 84 /** Updates the current predictions. */ setPredictedApps(List<ItemInfo> predictedApps)85 public void setPredictedApps(List<ItemInfo> predictedApps) { 86 mPredictedApps = predictedApps; 87 if (mAppsView != null) { 88 mAppsView.getFloatingHeaderView() 89 .findFixedRowByType(PredictionRowView.class) 90 .setPredictedApps(mPredictedApps); 91 } 92 } 93 94 /** Opens the {@link TaskbarAllAppsContainerView} in a new window. */ show()95 public void show() { 96 show(true); 97 } 98 99 /** Returns {@code true} if All Apps is open. */ isOpen()100 public boolean isOpen() { 101 return mSlideInView != null && mSlideInView.isOpen(); 102 } 103 show(boolean animate)104 private void show(boolean animate) { 105 if (mAppsView != null) { 106 return; 107 } 108 // mControllers and getSharedState should never be null here. Do not handle null-pointer 109 // to catch invalid states. 110 mControllers.getSharedState().allAppsVisible = true; 111 112 TaskbarOverlayContext overlayContext = 113 mControllers.taskbarOverlayController.requestWindow(); 114 mSlideInView = (TaskbarAllAppsSlideInView) overlayContext.getLayoutInflater().inflate( 115 R.layout.taskbar_all_apps, overlayContext.getDragLayer(), false); 116 mSlideInView.addOnCloseListener(() -> { 117 mControllers.getSharedState().allAppsVisible = false; 118 mSlideInView = null; 119 mAppsView = null; 120 }); 121 TaskbarAllAppsViewController viewController = new TaskbarAllAppsViewController( 122 overlayContext, mSlideInView, mControllers); 123 124 viewController.show(animate); 125 mAppsView = overlayContext.getAppsView(); 126 mAppsView.getAppsStore().setApps(mApps, mAppsModelFlags); 127 mAppsView.getFloatingHeaderView() 128 .findFixedRowByType(PredictionRowView.class) 129 .setPredictedApps(mPredictedApps); 130 // 1 alternative that would be more work: 131 // Create a shared drag layer between taskbar and taskbarAllApps so that when dragging 132 // starts and taskbarAllApps can close, but the drag layer that the view is being dragged in 133 // doesn't also close 134 overlayContext.getDragController().setDisallowGlobalDrag(mDisallowGlobalDrag); 135 overlayContext.getDragController().setDisallowLongClick(mDisallowLongClick); 136 } 137 138 139 @VisibleForTesting getTaskbarAllAppsTopPadding()140 public int getTaskbarAllAppsTopPadding() { 141 // Allow null-pointer since this should only be null if the apps view is not showing. 142 return mAppsView.getActiveRecyclerView().getClipBounds().top; 143 } 144 } 145