Merge "Relayer taskbar to application_overlay when shade is opened" into main
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index a648269..018903e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -65,6 +65,7 @@
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManager;
import android.os.IRemoteCallback;
import android.os.Process;
@@ -98,6 +99,7 @@
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.AnimatorPlaybackController;
@@ -107,6 +109,8 @@
import com.android.launcher3.desktop.DesktopAppLaunchTransition.AppLaunchType;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.icons.BitmapRenderer;
+import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.AppInfo;
@@ -141,6 +145,7 @@
import com.android.launcher3.taskbar.customization.TaskbarSpecsEvaluator;
import com.android.launcher3.taskbar.growth.NudgeController;
import com.android.launcher3.taskbar.navbutton.NearestTouchFrame;
+import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayController;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
@@ -161,6 +166,7 @@
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.NavHandle;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.SystemUiProxy;
@@ -171,6 +177,7 @@
import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
+import com.android.systemui.animation.ViewRootSync;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.rotation.RotationButtonController;
import com.android.systemui.shared.statusbar.phone.BarTransitions;
@@ -199,7 +206,7 @@
private static final String WINDOW_TITLE = "Taskbar";
- private static final DesktopModeFlag ENABLE_TASKBAR_BEHIND_SHADE = new DesktopModeFlag(
+ protected static final DesktopModeFlag ENABLE_TASKBAR_BEHIND_SHADE = new DesktopModeFlag(
Flags::enableTaskbarBehindShade, false);
private final @Nullable Context mNavigationBarPanelContext;
@@ -252,6 +259,10 @@
private TaskbarSpecsEvaluator mTaskbarSpecsEvaluator;
+ // Snapshot is used to temporarily draw taskbar behind the shade.
+ private @Nullable View mTaskbarSnapshotView;
+ private @Nullable TaskbarOverlayContext mTaskbarSnapshotOverlay;
+
public TaskbarActivityContext(Context windowContext,
@Nullable Context navigationBarPanelContext, DeviceProfile launcherDp,
TaskbarNavButtonController buttonController,
@@ -997,6 +1008,8 @@
mWindowManager.removeViewImmediate(mDragLayer);
mAddedWindow = false;
}
+ mTaskbarSnapshotView = null;
+ mTaskbarSnapshotOverlay = null;
}
public boolean isDestroyed() {
@@ -1068,6 +1081,80 @@
if (skipAnim) {
anim.end();
}
+
+ updateTaskbarSnapshot(anim, isExpanded);
+ }
+
+ private void updateTaskbarSnapshot(AnimatorSet anim, boolean isExpanded) {
+ if (!ENABLE_TASKBAR_BEHIND_SHADE.isTrue()) {
+ return;
+ }
+ if (mTaskbarSnapshotView == null) {
+ mTaskbarSnapshotView = new View(this);
+ }
+ if (isExpanded) {
+ if (!mTaskbarSnapshotView.isAttachedToWindow()
+ && mDragLayer.isAttachedToWindow()
+ && mDragLayer.isLaidOut()
+ && mTaskbarSnapshotView.getParent() == null) {
+ NearestTouchFrame navButtonsView = mDragLayer.findViewById(R.id.navbuttons_view);
+ int oldNavButtonsVisibility = navButtonsView.getVisibility();
+ navButtonsView.setVisibility(View.INVISIBLE);
+
+ Drawable drawable = new FastBitmapDrawable(BitmapRenderer.createHardwareBitmap(
+ mDragLayer.getWidth(),
+ mDragLayer.getHeight(),
+ mDragLayer::draw));
+
+ navButtonsView.setVisibility(oldNavButtonsVisibility);
+ mTaskbarSnapshotView.setBackground(drawable);
+ mTaskbarSnapshotView.setAlpha(0f);
+
+ mTaskbarSnapshotView.addOnAttachStateChangeListener(
+ new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(@NonNull View v) {
+ mTaskbarSnapshotView.removeOnAttachStateChangeListener(this);
+ anim.end();
+ mTaskbarSnapshotView.setAlpha(1f);
+ if (!Utilities.isRunningInTestHarness()) {
+ ViewRootSync.synchronizeNextDraw(mDragLayer,
+ mTaskbarSnapshotView,
+ () -> {});
+ }
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(@NonNull View v) {}
+ });
+ BaseDragLayer.LayoutParams layoutParams = new BaseDragLayer.LayoutParams(
+ mDragLayer.getWidth(), mDragLayer.getHeight());
+ layoutParams.gravity = mWindowLayoutParams.gravity;
+ layoutParams.ignoreInsets = true;
+ mTaskbarSnapshotOverlay = mControllers.taskbarOverlayController.requestWindow();
+ mTaskbarSnapshotOverlay.getDragLayer().addView(mTaskbarSnapshotView, layoutParams);
+ }
+ } else {
+ Runnable removeSnapshotView = () -> {
+ if (mTaskbarSnapshotOverlay != null) {
+ mTaskbarSnapshotOverlay.getDragLayer().removeView(mTaskbarSnapshotView);
+ mTaskbarSnapshotView = null;
+ mTaskbarSnapshotOverlay = null;
+ }
+ };
+ if (mTaskbarSnapshotView.isAttachedToWindow()) {
+ mTaskbarSnapshotView.setAlpha(0f);
+ anim.end();
+ if (Utilities.isRunningInTestHarness()) {
+ removeSnapshotView.run();
+ } else {
+ ViewRootSync.synchronizeNextDraw(mDragLayer, mTaskbarSnapshotView,
+ removeSnapshotView);
+ }
+ } else {
+ removeSnapshotView.run();
+ }
+ }
}
public void onRotationProposal(int rotation, boolean isValid) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index ad59c2e..eaf00b6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -28,6 +28,7 @@
import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NAVBAR_UNIFICATION;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TRANSIENT_TASKBAR_HIDE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TRANSIENT_TASKBAR_SHOW;
+import static com.android.launcher3.taskbar.TaskbarActivityContext.ENABLE_TASKBAR_BEHIND_SHADE;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.FlagDebugUtils.appendFlag;
import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange;
@@ -1138,7 +1139,10 @@
long startDelay = 0;
updateStateForFlag(FLAG_STASHED_IN_APP_SYSUI, hasAnyFlag(systemUiStateFlags,
- SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE | SYSUI_STATE_DIALOG_SHOWING));
+ SYSUI_STATE_DIALOG_SHOWING | (ENABLE_TASKBAR_BEHIND_SHADE.isTrue()
+ ? 0
+ : SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE)
+ ));
boolean stashForBubbles = hasAnyFlag(FLAG_IN_OVERVIEW)
&& hasAnyFlag(systemUiStateFlags, SYSUI_STATE_BUBBLES_EXPANDED)
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index 15a27d1..e8de0d2 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -402,16 +402,16 @@
canvas.scale(
mRingScale * (1f - RING_EFFECT_RATIO),
mRingScale * (1f - RING_EFFECT_RATIO),
- canvas.getWidth() / 2f,
- canvas.getHeight() / 2f);
+ getWidth() / 2f,
+ getHeight() / 2f);
} else if (Float.compare(1, mRingScale) != 0) {
- canvas.scale(mRingScale, mRingScale, canvas.getWidth() / 2f, canvas.getHeight() / 2f);
+ canvas.scale(mRingScale, mRingScale, getWidth() / 2f, getHeight() / 2f);
}
// Draw ring shadow around canvas.
canvas.drawPath(mRingPath, mIconRingPaint);
mIconRingPaint.setColor(mPlateColor.currentColor);
if (Flags.enableLauncherIconShapes()) {
- mIconRingPaint.setStrokeWidth(canvas.getWidth() * RING_EFFECT_RATIO);
+ mIconRingPaint.setStrokeWidth(getWidth() * RING_EFFECT_RATIO);
// Using FILL_AND_STROKE as there is still some gap to fill,
// between inner curve of ring / outer curve of icon.
mIconRingPaint.setStyle(Paint.Style.FILL_AND_STROKE);