Merge "Implement overlay window for Taskbar EDU and All Apps." into tm-qpr-dev
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index b9b4fc3..03d00c4 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -276,13 +276,6 @@
&& !mLauncher.getOnboardingPrefs().getBoolean(OnboardingPrefs.TASKBAR_EDU_SEEN);
}
- /**
- * Manually ends the taskbar education flow.
- */
- public void hideEdu() {
- mControllers.taskbarEduController.hideEdu();
- }
-
@Override
public void onTaskbarIconLaunched(ItemInfo item) {
InstanceId instanceId = new InstanceIdSequence().newInstanceId();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 0c488cb..4c5e0be 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -76,6 +76,7 @@
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
+import com.android.launcher3.taskbar.overlay.TaskbarOverlayController;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.touch.ItemClickHandler;
@@ -211,7 +212,8 @@
new TaskbarAutohideSuspendController(this),
new TaskbarPopupController(this),
new TaskbarForceVisibleImmersiveController(this),
- new TaskbarAllAppsController(this, dp),
+ new TaskbarOverlayController(this, dp),
+ new TaskbarAllAppsController(),
new TaskbarInsetsController(this),
new VoiceInteractionWindowController(this),
isDesktopMode
@@ -243,7 +245,7 @@
/** Updates {@link DeviceProfile} instances for any Taskbar windows. */
public void updateDeviceProfile(DeviceProfile dp, NavigationMode navMode) {
mNavMode = navMode;
- mControllers.taskbarAllAppsController.updateDeviceProfile(dp);
+ mControllers.taskbarOverlayController.updateDeviceProfile(dp);
mDeviceProfile = dp.copy(this);
updateIconSize(getResources());
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index 707023b..9c2d21e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -22,6 +22,7 @@
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
+import com.android.launcher3.taskbar.overlay.TaskbarOverlayController;
import com.android.systemui.shared.rotation.RotationButtonController;
import java.io.PrintWriter;
@@ -54,6 +55,7 @@
public final TaskbarInsetsController taskbarInsetsController;
public final VoiceInteractionWindowController voiceInteractionWindowController;
public final TaskbarRecentAppsController taskbarRecentAppsController;
+ public final TaskbarOverlayController taskbarOverlayController;
@Nullable private LoggableTaskbarController[] mControllersToLog = null;
@@ -81,6 +83,7 @@
TaskbarAutohideSuspendController taskbarAutoHideSuspendController,
TaskbarPopupController taskbarPopupController,
TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController,
+ TaskbarOverlayController taskbarOverlayController,
TaskbarAllAppsController taskbarAllAppsController,
TaskbarInsetsController taskbarInsetsController,
VoiceInteractionWindowController voiceInteractionWindowController,
@@ -101,6 +104,7 @@
this.taskbarAutohideSuspendController = taskbarAutoHideSuspendController;
this.taskbarPopupController = taskbarPopupController;
this.taskbarForceVisibleImmersiveController = taskbarForceVisibleImmersiveController;
+ this.taskbarOverlayController = taskbarOverlayController;
this.taskbarAllAppsController = taskbarAllAppsController;
this.taskbarInsetsController = taskbarInsetsController;
this.voiceInteractionWindowController = voiceInteractionWindowController;
@@ -129,6 +133,7 @@
taskbarEduController.init(this);
taskbarPopupController.init(this);
taskbarForceVisibleImmersiveController.init(this);
+ taskbarOverlayController.init(this);
taskbarAllAppsController.init(this, sharedState.allAppsVisible);
navButtonController.init(this);
taskbarInsetsController.init(this);
@@ -179,7 +184,7 @@
taskbarAutohideSuspendController.onDestroy();
taskbarPopupController.onDestroy();
taskbarForceVisibleImmersiveController.onDestroy();
- taskbarAllAppsController.onDestroy();
+ taskbarOverlayController.onDestroy();
navButtonController.onDestroy();
taskbarInsetsController.onDestroy();
voiceInteractionWindowController.onDestroy();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
index 95b93fe..16cc0ac 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
@@ -35,6 +35,7 @@
import com.android.launcher3.R;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import com.android.launcher3.uioverrides.PredictedAppIcon;
import java.io.PrintWriter;
@@ -87,8 +88,10 @@
void showEdu() {
mActivity.setTaskbarWindowFullscreen(true);
mActivity.getDragLayer().post(() -> {
- mTaskbarEduView = (TaskbarEduView) mActivity.getLayoutInflater().inflate(
- R.layout.taskbar_edu, mActivity.getDragLayer(), false);
+ TaskbarOverlayContext overlayContext =
+ mControllers.taskbarOverlayController.requestWindow();
+ mTaskbarEduView = (TaskbarEduView) overlayContext.getLayoutInflater().inflate(
+ R.layout.taskbar_edu, overlayContext.getDragLayer(), false);
mTaskbarEduView.init(new TaskbarEduCallbacks());
mControllers.navbarButtonsViewController.setSlideInViewVisible(true);
mTaskbarEduView.setOnCloseBeginListener(
@@ -99,12 +102,6 @@
});
}
- void hideEdu() {
- if (mTaskbarEduView != null) {
- mTaskbarEduView.close(true /* animate */);
- }
- }
-
/**
* Starts the given animation, ending the previous animation first if it's still playing.
*/
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java
index c0cbbd6..bb87f48 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java
@@ -28,10 +28,11 @@
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
+import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import com.android.launcher3.views.AbstractSlideInView;
/** Education view about the Taskbar. */
-public class TaskbarEduView extends AbstractSlideInView<TaskbarActivityContext>
+public class TaskbarEduView extends AbstractSlideInView<TaskbarOverlayContext>
implements Insettable {
private static final int DEFAULT_OPEN_DURATION = 500;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
index bbbc1e6..a34aa15 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
@@ -29,7 +29,7 @@
import android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD
import android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION
import com.android.launcher3.AbstractFloatingView
-import com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS
+import com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_OVERLAY_PROXY
import com.android.launcher3.DeviceProfile
import com.android.launcher3.anim.AlphaUpdateListener
import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
@@ -158,8 +158,11 @@
} else if (controllers.taskbarDragController.isSystemDragInProgress) {
// Let touches pass through us.
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
- } else if (AbstractFloatingView.hasOpenView(context, TYPE_TASKBAR_ALL_APPS)) {
- // Let touches pass through us.
+ } else if (AbstractFloatingView.hasOpenView(context, TYPE_TASKBAR_OVERLAY_PROXY)) {
+ // Let touches pass through us if icons are hidden.
+ if (controllers.taskbarViewController.areIconsVisible()) {
+ insetsInfo.touchableRegion.set(touchableRegion)
+ }
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
} else if (controllers.taskbarViewController.areIconsVisible()
|| AbstractFloatingView.hasOpenView(context, AbstractFloatingView.TYPE_ALL)
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 114bfec..49dba95 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -80,10 +80,10 @@
}
/**
- * Manually closes the all apps window.
+ * Manually closes the overlay window.
*/
- public void hideAllApps() {
- mControllers.taskbarAllAppsController.hide();
+ public void hideOverlayWindow() {
+ mControllers.taskbarOverlayController.hideWindow();
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
index 51fa4d9..ce51f7d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
@@ -24,10 +24,11 @@
import com.android.launcher3.allapps.AlphabeticalAppsList;
import com.android.launcher3.allapps.BaseAdapterProvider;
import com.android.launcher3.allapps.BaseAllAppsAdapter;
+import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
/** All apps container accessible from taskbar. */
public class TaskbarAllAppsContainerView extends
- ActivityAllAppsContainerView<TaskbarAllAppsContext> {
+ ActivityAllAppsContainerView<TaskbarOverlayContext> {
public TaskbarAllAppsContainerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -44,8 +45,8 @@
}
@Override
- protected BaseAllAppsAdapter<TaskbarAllAppsContext> createAdapter(
- AlphabeticalAppsList<TaskbarAllAppsContext> appsList,
+ protected BaseAllAppsAdapter<TaskbarOverlayContext> createAdapter(
+ AlphabeticalAppsList<TaskbarOverlayContext> appsList,
BaseAdapterProvider[] adapterProviders) {
return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), appsList,
adapterProviders);
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java
deleted file mode 100644
index 0372f67..0000000
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2022 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.allapps;
-
-import static android.view.KeyEvent.ACTION_UP;
-import static android.view.KeyEvent.KEYCODE_BACK;
-import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-
-import android.content.Context;
-import android.graphics.Insets;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
-import android.view.WindowInsets;
-
-import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.allapps.ActivityAllAppsContainerView;
-import com.android.launcher3.allapps.search.DefaultSearchAdapterProvider;
-import com.android.launcher3.allapps.search.SearchAdapterProvider;
-import com.android.launcher3.dot.DotInfo;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.popup.PopupDataProvider;
-import com.android.launcher3.taskbar.BaseTaskbarContext;
-import com.android.launcher3.taskbar.TaskbarActivityContext;
-import com.android.launcher3.taskbar.TaskbarControllers;
-import com.android.launcher3.taskbar.TaskbarDragController;
-import com.android.launcher3.taskbar.TaskbarStashController;
-import com.android.launcher3.testing.TestLogging;
-import com.android.launcher3.testing.shared.TestProtocol;
-import com.android.launcher3.util.OnboardingPrefs;
-import com.android.launcher3.util.TouchController;
-import com.android.launcher3.views.BaseDragLayer;
-
-/**
- * Window context for the taskbar all apps overlay.
- * <p>
- * All apps has its own window and needs a window context. Some properties are delegated to the
- * {@link TaskbarActivityContext} such as {@link DeviceProfile} and {@link PopupDataProvider}.
- */
-class TaskbarAllAppsContext extends BaseTaskbarContext {
- private final TaskbarActivityContext mTaskbarContext;
- private final OnboardingPrefs<TaskbarAllAppsContext> mOnboardingPrefs;
-
- private final TaskbarAllAppsController mWindowController;
- private final TaskbarAllAppsViewController mAllAppsViewController;
- private final TaskbarDragController mDragController;
- private final TaskbarAllAppsDragLayer mDragLayer;
- private final TaskbarAllAppsContainerView mAppsView;
-
- // We automatically stash taskbar when all apps is opened in gesture navigation mode.
- private final boolean mWillTaskbarBeVisuallyStashed;
- private final int mStashedTaskbarHeight;
-
- TaskbarAllAppsContext(
- TaskbarActivityContext taskbarContext,
- TaskbarAllAppsController windowController,
- TaskbarControllers taskbarControllers) {
- super(taskbarContext.createWindowContext(TYPE_APPLICATION_OVERLAY, null));
- mTaskbarContext = taskbarContext;
- mWindowController = windowController;
- mDragController = new TaskbarDragController(this);
- mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
-
- mDragLayer = new TaskbarAllAppsDragLayer(this);
- TaskbarAllAppsSlideInView slideInView = (TaskbarAllAppsSlideInView) mLayoutInflater.inflate(
- R.layout.taskbar_all_apps, mDragLayer, false);
- mAllAppsViewController = new TaskbarAllAppsViewController(
- this,
- slideInView,
- windowController,
- taskbarControllers);
- mAppsView = slideInView.getAppsView();
-
- TaskbarStashController taskbarStashController = taskbarControllers.taskbarStashController;
- mWillTaskbarBeVisuallyStashed = taskbarStashController.supportsVisualStashing();
- mStashedTaskbarHeight = taskbarStashController.getStashedHeight();
- }
-
- TaskbarAllAppsViewController getAllAppsViewController() {
- return mAllAppsViewController;
- }
-
- @Override
- public DeviceProfile getDeviceProfile() {
- return mWindowController.getDeviceProfile();
- }
-
- @Override
- public TaskbarDragController getDragController() {
- return mDragController;
- }
-
- @Override
- public TaskbarAllAppsDragLayer getDragLayer() {
- return mDragLayer;
- }
-
- @Override
- public TaskbarAllAppsContainerView getAppsView() {
- return mAppsView;
- }
-
- @Override
- public OnboardingPrefs<TaskbarAllAppsContext> getOnboardingPrefs() {
- return mOnboardingPrefs;
- }
-
- @Override
- public boolean isBindingItems() {
- return mTaskbarContext.isBindingItems();
- }
-
- @Override
- public View.OnClickListener getItemOnClickListener() {
- return mTaskbarContext.getItemOnClickListener();
- }
-
- @Override
- public PopupDataProvider getPopupDataProvider() {
- return mTaskbarContext.getPopupDataProvider();
- }
-
- @Override
- public DotInfo getDotInfoForItem(ItemInfo info) {
- return mTaskbarContext.getDotInfoForItem(info);
- }
-
- @Override
- public void onDragStart() {}
-
- @Override
- public void onDragEnd() {
- mWindowController.maybeCloseWindow();
- }
-
- @Override
- public void onPopupVisibilityChanged(boolean isVisible) {}
-
- @Override
- public SearchAdapterProvider<?> createSearchAdapterProvider(
- ActivityAllAppsContainerView<?> appsView) {
- return new DefaultSearchAdapterProvider(this);
- }
-
- /** Root drag layer for this context. */
- private static class TaskbarAllAppsDragLayer extends
- BaseDragLayer<TaskbarAllAppsContext> implements OnComputeInternalInsetsListener {
-
- private TaskbarAllAppsDragLayer(Context context) {
- super(context, null, 1);
- setClipChildren(false);
- recreateControllers();
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- getViewTreeObserver().addOnComputeInternalInsetsListener(this);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
- }
-
- @Override
- public void recreateControllers() {
- mControllers = new TouchController[]{mActivity.mDragController};
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- TestLogging.recordMotionEvent(TestProtocol.SEQUENCE_MAIN, "Touch event", ev);
- return super.dispatchTouchEvent(ev);
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- if (event.getAction() == ACTION_UP && event.getKeyCode() == KEYCODE_BACK) {
- AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
- if (topView != null && topView.onBackPressed()) {
- return true;
- }
- }
- return super.dispatchKeyEvent(event);
- }
-
- @Override
- public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
- if (mActivity.mDragController.isSystemDragInProgress()) {
- inoutInfo.touchableRegion.setEmpty();
- inoutInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
- }
- }
-
- @Override
- public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- return updateInsetsDueToStashing(insets);
- }
-
- /**
- * Taskbar automatically stashes when opening all apps, but we don't report the insets as
- * changing to avoid moving the underlying app. But internally, the apps view should still
- * layout according to the stashed insets rather than the unstashed insets. So this method
- * does two things:
- * 1) Sets navigationBars bottom inset to stashedHeight.
- * 2) Sets tappableInsets bottom inset to 0.
- */
- private WindowInsets updateInsetsDueToStashing(WindowInsets oldInsets) {
- if (!mActivity.mWillTaskbarBeVisuallyStashed) {
- return oldInsets;
- }
- WindowInsets.Builder updatedInsetsBuilder = new WindowInsets.Builder(oldInsets);
-
- Insets oldNavInsets = oldInsets.getInsets(WindowInsets.Type.navigationBars());
- Insets newNavInsets = Insets.of(oldNavInsets.left, oldNavInsets.top, oldNavInsets.right,
- mActivity.mStashedTaskbarHeight);
- updatedInsetsBuilder.setInsets(WindowInsets.Type.navigationBars(), newNavInsets);
-
- Insets oldTappableInsets = oldInsets.getInsets(WindowInsets.Type.tappableElement());
- Insets newTappableInsets = Insets.of(oldTappableInsets.left, oldTappableInsets.top,
- oldTappableInsets.right, 0);
- updatedInsetsBuilder.setInsets(WindowInsets.Type.tappableElement(), newTappableInsets);
-
- return updatedInsetsBuilder.build();
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
index 1671a0f..ea37944 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
@@ -15,34 +15,17 @@
*/
package com.android.launcher3.taskbar.allapps;
-import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-
-import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
-import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
-
-import android.content.Context;
-import android.graphics.PixelFormat;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
-
import androidx.annotation.Nullable;
-import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
import com.android.launcher3.appprediction.PredictionRowView;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.taskbar.TaskbarActivityContext;
import com.android.launcher3.taskbar.TaskbarControllers;
-import com.android.systemui.shared.system.TaskStackChangeListener;
-import com.android.systemui.shared.system.TaskStackChangeListeners;
+import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import java.util.List;
-import java.util.Optional;
/**
* Handles the all apps overlay window initialization, updates, and its data.
@@ -57,36 +40,14 @@
*/
public final class TaskbarAllAppsController {
- private static final String WINDOW_TITLE = "Taskbar All Apps";
-
- private final TaskbarActivityContext mTaskbarContext;
- private final TaskbarAllAppsProxyView mProxyView;
- private final LayoutParams mLayoutParams;
-
- private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
- @Override
- public void onTaskStackChanged() {
- mProxyView.close(false);
- }
- };
-
- private DeviceProfile mDeviceProfile;
private TaskbarControllers mControllers;
- /** Window context for all apps if it is open. */
- private @Nullable TaskbarAllAppsContext mAllAppsContext;
+ private @Nullable TaskbarAllAppsContainerView mAppsView;
// Application data models.
private AppInfo[] mApps;
private int mAppsModelFlags;
private List<ItemInfo> mPredictedApps;
- public TaskbarAllAppsController(TaskbarActivityContext context, DeviceProfile dp) {
- mDeviceProfile = dp;
- mTaskbarContext = context;
- mProxyView = new TaskbarAllAppsProxyView(mTaskbarContext);
- mLayoutParams = createLayoutParams();
- }
-
/** Initialize the controller. */
public void init(TaskbarControllers controllers, boolean allAppsVisible) {
if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
@@ -111,8 +72,8 @@
mApps = apps;
mAppsModelFlags = flags;
- if (mAllAppsContext != null) {
- mAllAppsContext.getAppsView().getAppsStore().setApps(mApps, mAppsModelFlags);
+ if (mAppsView != null) {
+ mAppsView.getAppsStore().setApps(mApps, mAppsModelFlags);
}
}
@@ -123,8 +84,8 @@
}
mPredictedApps = predictedApps;
- if (mAllAppsContext != null) {
- mAllAppsContext.getAppsView().getFloatingHeaderView()
+ if (mAppsView != null) {
+ mAppsView.getFloatingHeaderView()
.findFixedRowByType(PredictionRowView.class)
.setPredictedApps(mPredictedApps);
}
@@ -136,120 +97,30 @@
}
private void show(boolean animate) {
- if (mProxyView.isOpen()) {
+ if (mAppsView != null) {
return;
}
- mProxyView.show();
// mControllers and getSharedState should never be null here. Do not handle null-pointer
// to catch invalid states.
mControllers.getSharedState().allAppsVisible = true;
- mAllAppsContext = new TaskbarAllAppsContext(mTaskbarContext, this, mControllers);
- mAllAppsContext.getDragController().init(mControllers);
- TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
- Optional.ofNullable(mAllAppsContext.getSystemService(WindowManager.class))
- .ifPresent(m -> m.addView(mAllAppsContext.getDragLayer(), mLayoutParams));
+ TaskbarOverlayContext overlayContext =
+ mControllers.taskbarOverlayController.requestWindow();
+ TaskbarAllAppsSlideInView slideInView =
+ (TaskbarAllAppsSlideInView) overlayContext.getLayoutInflater().inflate(
+ R.layout.taskbar_all_apps, overlayContext.getDragLayer(), false);
+ slideInView.addOnCloseListener(() -> {
+ mControllers.getSharedState().allAppsVisible = false;
+ mAppsView = null;
+ });
+ TaskbarAllAppsViewController viewController = new TaskbarAllAppsViewController(
+ overlayContext, slideInView, mControllers);
- mAllAppsContext.getAppsView().getAppsStore().setApps(mApps, mAppsModelFlags);
- mAllAppsContext.getAppsView().getFloatingHeaderView()
+ viewController.show(animate);
+ mAppsView = overlayContext.getAppsView();
+ mAppsView.getAppsStore().setApps(mApps, mAppsModelFlags);
+ mAppsView.getFloatingHeaderView()
.findFixedRowByType(PredictionRowView.class)
.setPredictedApps(mPredictedApps);
- mAllAppsContext.getAllAppsViewController().show(animate);
- }
-
- /** Closes the {@link TaskbarAllAppsContainerView}. */
- public void hide() {
- mProxyView.close(true);
- }
-
- /**
- * Removes the all apps window from the hierarchy, if all floating views are closed and there is
- * no system drag operation in progress.
- * <p>
- * This method should be called after an exit animation finishes, if applicable.
- */
- void maybeCloseWindow() {
- if (mAllAppsContext != null && (AbstractFloatingView.hasOpenView(mAllAppsContext, TYPE_ALL)
- || mAllAppsContext.getDragController().isSystemDragInProgress())) {
- return;
- }
- mProxyView.close(false);
- // mControllers and getSharedState should never be null here. Do not handle null-pointer
- // to catch invalid states.
- mControllers.getSharedState().allAppsVisible = false;
- onDestroy();
- }
-
- /** Destroys the controller and any All Apps window if present. */
- public void onDestroy() {
- TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
- Optional.ofNullable(mAllAppsContext)
- .map(c -> c.getSystemService(WindowManager.class))
- .ifPresent(m -> m.removeViewImmediate(mAllAppsContext.getDragLayer()));
- mAllAppsContext = null;
- }
-
- /** Updates {@link DeviceProfile} instance for Taskbar's All Apps window. */
- public void updateDeviceProfile(DeviceProfile dp) {
- mDeviceProfile = dp;
- Optional.ofNullable(mAllAppsContext).ifPresent(c -> {
- AbstractFloatingView.closeAllOpenViewsExcept(c, false, TYPE_REBIND_SAFE);
- c.dispatchDeviceProfileChanged();
- });
- }
-
- DeviceProfile getDeviceProfile() {
- return mDeviceProfile;
- }
-
- private LayoutParams createLayoutParams() {
- LayoutParams layoutParams = new LayoutParams(
- TYPE_APPLICATION_OVERLAY,
- WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
- PixelFormat.TRANSLUCENT);
- layoutParams.setTitle(WINDOW_TITLE);
- layoutParams.gravity = Gravity.BOTTOM;
- layoutParams.packageName = mTaskbarContext.getPackageName();
- layoutParams.setFitInsetsTypes(0); // Handled by container view.
- layoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- layoutParams.setSystemApplicationOverlay(true);
- return layoutParams;
- }
-
- /**
- * Proxy view connecting taskbar drag layer to the all apps window.
- * <p>
- * The all apps view is in a separate window and has its own drag layer, but this proxy lets it
- * behave as though its in the taskbar drag layer. For instance, when the taskbar closes all
- * {@link AbstractFloatingView} instances, the all apps window will also close.
- */
- private class TaskbarAllAppsProxyView extends AbstractFloatingView {
-
- private TaskbarAllAppsProxyView(Context context) {
- super(context, null);
- }
-
- private void show() {
- mIsOpen = true;
- mTaskbarContext.getDragLayer().addView(this);
- }
-
- @Override
- protected void handleClose(boolean animate) {
- mTaskbarContext.getDragLayer().removeView(this);
- Optional.ofNullable(mAllAppsContext)
- .map(TaskbarAllAppsContext::getAllAppsViewController)
- .ifPresent(v -> v.close(animate));
- }
-
- @Override
- protected boolean isOfType(int type) {
- return (type & TYPE_TASKBAR_ALL_APPS) != 0;
- }
-
- @Override
- public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
- return false;
- }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
index 9d48c8d..c8bfc2a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
@@ -28,10 +28,11 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
+import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import com.android.launcher3.views.AbstractSlideInView;
/** Wrapper for taskbar all apps with slide-in behavior. */
-public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarAllAppsContext>
+public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarOverlayContext>
implements Insettable, DeviceProfile.OnDeviceProfileChangeListener {
private TaskbarAllAppsContainerView mAppsView;
private float mShiftRange;
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
index 128fa5e..54392b2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
@@ -25,6 +25,7 @@
import com.android.launcher3.taskbar.NavbarButtonsViewController;
import com.android.launcher3.taskbar.TaskbarControllers;
import com.android.launcher3.taskbar.TaskbarStashController;
+import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
/**
* Handles the {@link TaskbarAllAppsContainerView} behavior and synchronizes its transitions with
@@ -32,16 +33,15 @@
*/
final class TaskbarAllAppsViewController {
- private final TaskbarAllAppsContext mContext;
+ private final TaskbarOverlayContext mContext;
private final TaskbarAllAppsSlideInView mSlideInView;
private final TaskbarAllAppsContainerView mAppsView;
private final TaskbarStashController mTaskbarStashController;
private final NavbarButtonsViewController mNavbarButtonsViewController;
TaskbarAllAppsViewController(
- TaskbarAllAppsContext context,
+ TaskbarOverlayContext context,
TaskbarAllAppsSlideInView slideInView,
- TaskbarAllAppsController windowController,
TaskbarControllers taskbarControllers) {
mContext = context;
@@ -53,7 +53,6 @@
setUpIconLongClick();
setUpAppDivider();
setUpTaskbarStashing();
- mSlideInView.addOnCloseListener(windowController::maybeCloseWindow);
}
/** Starts the {@link TaskbarAllAppsSlideInView} enter transition. */
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
new file mode 100644
index 0000000..5701de0
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2022 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.overlay;
+
+import android.content.Context;
+import android.view.View;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.allapps.ActivityAllAppsContainerView;
+import com.android.launcher3.allapps.search.DefaultSearchAdapterProvider;
+import com.android.launcher3.allapps.search.SearchAdapterProvider;
+import com.android.launcher3.dot.DotInfo;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.popup.PopupDataProvider;
+import com.android.launcher3.taskbar.BaseTaskbarContext;
+import com.android.launcher3.taskbar.TaskbarActivityContext;
+import com.android.launcher3.taskbar.TaskbarControllers;
+import com.android.launcher3.taskbar.TaskbarDragController;
+import com.android.launcher3.taskbar.TaskbarStashController;
+import com.android.launcher3.taskbar.allapps.TaskbarAllAppsContainerView;
+import com.android.launcher3.util.OnboardingPrefs;
+
+/**
+ * Window context for the taskbar overlays such as All Apps and EDU.
+ * <p>
+ * Overlays have their own window and need a window context. Some properties are delegated to the
+ * {@link TaskbarActivityContext} such as {@link PopupDataProvider}.
+ */
+public class TaskbarOverlayContext extends BaseTaskbarContext {
+ private final TaskbarActivityContext mTaskbarContext;
+ private final OnboardingPrefs<TaskbarOverlayContext> mOnboardingPrefs;
+
+ private final TaskbarOverlayController mOverlayController;
+ private final TaskbarDragController mDragController;
+ private final TaskbarOverlayDragLayer mDragLayer;
+
+ // We automatically stash taskbar when All Apps is opened in gesture navigation mode.
+ private final boolean mWillTaskbarBeVisuallyStashed;
+ private final int mStashedTaskbarHeight;
+
+ public TaskbarOverlayContext(
+ Context windowContext,
+ TaskbarActivityContext taskbarContext,
+ TaskbarControllers controllers) {
+ super(windowContext);
+ mTaskbarContext = taskbarContext;
+ mOverlayController = controllers.taskbarOverlayController;
+ mDragController = new TaskbarDragController(this);
+ mDragController.init(controllers);
+ mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
+ mDragLayer = new TaskbarOverlayDragLayer(this);
+
+ TaskbarStashController taskbarStashController = controllers.taskbarStashController;
+ mWillTaskbarBeVisuallyStashed = taskbarStashController.supportsVisualStashing();
+ mStashedTaskbarHeight = taskbarStashController.getStashedHeight();
+ }
+
+ boolean willTaskbarBeVisuallyStashed() {
+ return mWillTaskbarBeVisuallyStashed;
+ }
+
+ int getStashedTaskbarHeight() {
+ return mStashedTaskbarHeight;
+ }
+
+ public TaskbarOverlayController getOverlayController() {
+ return mOverlayController;
+ }
+
+ @Override
+ public DeviceProfile getDeviceProfile() {
+ return mOverlayController.getDeviceProfile();
+ }
+
+ @Override
+ public TaskbarDragController getDragController() {
+ return mDragController;
+ }
+
+ @Override
+ public TaskbarOverlayDragLayer getDragLayer() {
+ return mDragLayer;
+ }
+
+ @Override
+ public TaskbarAllAppsContainerView getAppsView() {
+ return mDragLayer.findViewById(R.id.apps_view);
+ }
+
+ @Override
+ public OnboardingPrefs<TaskbarOverlayContext> getOnboardingPrefs() {
+ return mOnboardingPrefs;
+ }
+
+ @Override
+ public boolean isBindingItems() {
+ return mTaskbarContext.isBindingItems();
+ }
+
+ @Override
+ public View.OnClickListener getItemOnClickListener() {
+ return mTaskbarContext.getItemOnClickListener();
+ }
+
+ @Override
+ public PopupDataProvider getPopupDataProvider() {
+ return mTaskbarContext.getPopupDataProvider();
+ }
+
+ @Override
+ public DotInfo getDotInfoForItem(ItemInfo info) {
+ return mTaskbarContext.getDotInfoForItem(info);
+ }
+
+ @Override
+ public void onDragStart() {}
+
+ @Override
+ public void onDragEnd() {
+ mOverlayController.maybeCloseWindow();
+ }
+
+ @Override
+ public void onPopupVisibilityChanged(boolean isVisible) {}
+
+ @Override
+ public SearchAdapterProvider<?> createSearchAdapterProvider(
+ ActivityAllAppsContainerView<?> appsView) {
+ return new DefaultSearchAdapterProvider(this);
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
new file mode 100644
index 0000000..0574058
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2022 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.overlay;
+
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
+import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
+import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.taskbar.TaskbarActivityContext;
+import com.android.launcher3.taskbar.TaskbarControllers;
+import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.shared.system.TaskStackChangeListeners;
+
+import java.util.Optional;
+
+/**
+ * Handles the Taskbar overlay window lifecycle.
+ * <p>
+ * Overlays need to be inflated in a separate window so that have the correct hierarchy. For
+ * instance, they need to be below the notification tray. If there are multiple overlays open, the
+ * same window is used.
+ */
+public final class TaskbarOverlayController {
+
+ private static final String WINDOW_TITLE = "Taskbar Overlay";
+
+ private final TaskbarActivityContext mTaskbarContext;
+ private final Context mWindowContext;
+ private final TaskbarOverlayProxyView mProxyView;
+ private final LayoutParams mLayoutParams;
+
+ private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
+ @Override
+ public void onTaskStackChanged() {
+ mProxyView.close(false);
+ }
+ };
+
+ private DeviceProfile mDeviceProfile;
+ private @Nullable TaskbarOverlayContext mOverlayContext;
+ private TaskbarControllers mControllers; // Initialized in init.
+
+ public TaskbarOverlayController(
+ TaskbarActivityContext taskbarContext, DeviceProfile deviceProfile) {
+ mTaskbarContext = taskbarContext;
+ mWindowContext = mTaskbarContext.createWindowContext(TYPE_APPLICATION_OVERLAY, null);
+ mProxyView = new TaskbarOverlayProxyView();
+ mLayoutParams = createLayoutParams();
+ mDeviceProfile = deviceProfile;
+ }
+
+ /** Initialize the controller. */
+ public void init(TaskbarControllers controllers) {
+ mControllers = controllers;
+ }
+
+ /**
+ * Creates a window for Taskbar overlays, if it does not already exist. Returns the window
+ * context for the current overlay window.
+ */
+ public TaskbarOverlayContext requestWindow() {
+ if (mOverlayContext == null) {
+ mOverlayContext = new TaskbarOverlayContext(
+ mWindowContext, mTaskbarContext, mControllers);
+ }
+
+ if (!mProxyView.isOpen()) {
+ mProxyView.show();
+ Optional.ofNullable(mOverlayContext.getSystemService(WindowManager.class))
+ .ifPresent(m -> m.addView(mOverlayContext.getDragLayer(), mLayoutParams));
+ TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
+ }
+
+ return mOverlayContext;
+ }
+
+ /** Hides the current overlay window with animation. */
+ public void hideWindow() {
+ mProxyView.close(true);
+ }
+
+ /**
+ * Removes the overlay window from the hierarchy, if all floating views are closed and there is
+ * no system drag operation in progress.
+ * <p>
+ * This method should be called after an exit animation finishes, if applicable.
+ */
+ @SuppressLint("WrongConstant")
+ void maybeCloseWindow() {
+ if (mOverlayContext != null && (AbstractFloatingView.hasOpenView(mOverlayContext, TYPE_ALL)
+ || mOverlayContext.getDragController().isSystemDragInProgress())) {
+ return;
+ }
+ mProxyView.close(false);
+ onDestroy();
+ }
+
+ /** Destroys the controller and any overlay window if present. */
+ public void onDestroy() {
+ TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
+ Optional.ofNullable(mOverlayContext)
+ .map(c -> c.getSystemService(WindowManager.class))
+ .ifPresent(m -> m.removeViewImmediate(mOverlayContext.getDragLayer()));
+ mOverlayContext = null;
+ }
+
+ /** The current device profile for the overlay window. */
+ public DeviceProfile getDeviceProfile() {
+ return mDeviceProfile;
+ }
+
+ /** Updates {@link DeviceProfile} instance for Taskbar's overlay window. */
+ public void updateDeviceProfile(DeviceProfile dp) {
+ mDeviceProfile = dp;
+ Optional.ofNullable(mOverlayContext).ifPresent(c -> {
+ AbstractFloatingView.closeAllOpenViewsExcept(c, false, TYPE_REBIND_SAFE);
+ c.dispatchDeviceProfileChanged();
+ });
+ }
+
+ @SuppressLint("WrongConstant")
+ private LayoutParams createLayoutParams() {
+ LayoutParams layoutParams = new LayoutParams(
+ TYPE_APPLICATION_OVERLAY,
+ LayoutParams.FLAG_SPLIT_TOUCH,
+ PixelFormat.TRANSLUCENT);
+ layoutParams.setTitle(WINDOW_TITLE);
+ layoutParams.gravity = Gravity.BOTTOM;
+ layoutParams.packageName = mTaskbarContext.getPackageName();
+ layoutParams.setFitInsetsTypes(0); // Handled by container view.
+ layoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ layoutParams.setSystemApplicationOverlay(true);
+ return layoutParams;
+ }
+
+ /**
+ * Proxy view connecting taskbar drag layer to the overlay window.
+ *
+ * Overlays are in a separate window and has its own drag layer, but this proxy lets its views
+ * behave as though they are in the taskbar drag layer. For instance, when the taskbar closes
+ * all {@link AbstractFloatingView} instances, the overlay window will also close.
+ */
+ private class TaskbarOverlayProxyView extends AbstractFloatingView {
+
+ private TaskbarOverlayProxyView() {
+ super(mTaskbarContext, null);
+ }
+
+ private void show() {
+ mIsOpen = true;
+ mTaskbarContext.getDragLayer().addView(this);
+ }
+
+ @Override
+ protected void handleClose(boolean animate) {
+ mTaskbarContext.getDragLayer().removeView(this);
+ Optional.ofNullable(mOverlayContext).ifPresent(c -> closeAllOpenViews(c, animate));
+ }
+
+ @Override
+ protected boolean isOfType(int type) {
+ return (type & TYPE_TASKBAR_OVERLAY_PROXY) != 0;
+ }
+
+ @Override
+ public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
+ return false;
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
new file mode 100644
index 0000000..044afd6
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2022 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.overlay;
+
+import static android.view.KeyEvent.ACTION_UP;
+import static android.view.KeyEvent.KEYCODE_BACK;
+import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
+
+import android.content.Context;
+import android.graphics.Insets;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.WindowInsets;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.testing.TestLogging;
+import com.android.launcher3.testing.shared.TestProtocol;
+import com.android.launcher3.util.TouchController;
+import com.android.launcher3.views.BaseDragLayer;
+
+/** Root drag layer for the Taskbar overlay window. */
+public class TaskbarOverlayDragLayer extends
+ BaseDragLayer<TaskbarOverlayContext> implements
+ ViewTreeObserver.OnComputeInternalInsetsListener {
+
+ TaskbarOverlayDragLayer(Context context) {
+ super(context, null, 1);
+ setClipChildren(false);
+ recreateControllers();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ getViewTreeObserver().addOnComputeInternalInsetsListener(this);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
+ }
+
+ @Override
+ public void recreateControllers() {
+ mControllers = new TouchController[]{mActivity.getDragController()};
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ TestLogging.recordMotionEvent(TestProtocol.SEQUENCE_MAIN, "Touch event", ev);
+ return super.dispatchTouchEvent(ev);
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (event.getAction() == ACTION_UP && event.getKeyCode() == KEYCODE_BACK) {
+ AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
+ if (topView != null && topView.onBackPressed()) {
+ return true;
+ }
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
+ @Override
+ public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
+ if (mActivity.getDragController().isSystemDragInProgress()) {
+ inoutInfo.touchableRegion.setEmpty();
+ inoutInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
+ }
+ }
+
+ @Override
+ public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+ return updateInsetsDueToStashing(insets);
+ }
+
+ @Override
+ public void onViewRemoved(View child) {
+ super.onViewRemoved(child);
+ mActivity.getOverlayController().maybeCloseWindow();
+ }
+
+ /**
+ * Taskbar automatically stashes when opening all apps, but we don't report the insets as
+ * changing to avoid moving the underlying app. But internally, the apps view should still
+ * layout according to the stashed insets rather than the unstashed insets. So this method
+ * does two things:
+ * 1) Sets navigationBars bottom inset to stashedHeight.
+ * 2) Sets tappableInsets bottom inset to 0.
+ */
+ private WindowInsets updateInsetsDueToStashing(WindowInsets oldInsets) {
+ if (!mActivity.willTaskbarBeVisuallyStashed()) {
+ return oldInsets;
+ }
+ WindowInsets.Builder updatedInsetsBuilder = new WindowInsets.Builder(oldInsets);
+
+ Insets oldNavInsets = oldInsets.getInsets(WindowInsets.Type.navigationBars());
+ Insets newNavInsets = Insets.of(oldNavInsets.left, oldNavInsets.top, oldNavInsets.right,
+ mActivity.getStashedTaskbarHeight());
+ updatedInsetsBuilder.setInsets(WindowInsets.Type.navigationBars(), newNavInsets);
+
+ Insets oldTappableInsets = oldInsets.getInsets(WindowInsets.Type.tappableElement());
+ Insets newTappableInsets = Insets.of(oldTappableInsets.left, oldTappableInsets.top,
+ oldTappableInsets.right, 0);
+ updatedInsetsBuilder.setInsets(WindowInsets.Type.tappableElement(), newTappableInsets);
+
+ return updatedInsetsBuilder.build();
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index a343c2d..d432004 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -188,7 +188,8 @@
* Closes any overlays.
*/
public void closeOverlay() {
- Optional.ofNullable(getTaskbarController()).ifPresent(TaskbarUIController::hideAllApps);
+ Optional.ofNullable(getTaskbarController()).ifPresent(
+ TaskbarUIController::hideOverlayWindow);
}
public void switchRunningTaskViewToScreenshot(HashMap<Integer, ThumbnailData> thumbnailDatas,
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index e9588d6..8522a87 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -290,10 +290,6 @@
} else {
om.hideOverlay(150);
}
- LauncherTaskbarUIController taskbarController = getTaskbarController();
- if (taskbarController != null) {
- taskbarController.hideEdu();
- }
}
@Override
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 5ee6fce..73acd87 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -94,6 +94,7 @@
public static final int TYPE_TASKBAR_EDUCATION_DIALOG = 1 << 16;
public static final int TYPE_TASKBAR_ALL_APPS = 1 << 17;
public static final int TYPE_ADD_TO_HOME_CONFIRMATION = 1 << 18;
+ public static final int TYPE_TASKBAR_OVERLAY_PROXY = 1 << 19;
public static final int TYPE_ALL = TYPE_FOLDER | TYPE_ACTION_POPUP
| TYPE_WIDGETS_BOTTOM_SHEET | TYPE_WIDGET_RESIZE_FRAME | TYPE_WIDGETS_FULL_SHEET