Merge "Fix null surface crash when switch split" into tm-qpr-dev
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 09f5cf1..c743582 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -61,7 +61,6 @@
 import com.android.wm.shell.desktopmode.DesktopModeController;
 import com.android.wm.shell.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
-import com.android.wm.shell.desktopmode.DesktopTasksController;
 import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
 import com.android.wm.shell.displayareahelper.DisplayAreaHelperController;
 import com.android.wm.shell.draganddrop.DragAndDropController;
@@ -678,11 +677,7 @@
     @WMSingleton
     @Provides
     static Optional<DesktopMode> provideDesktopMode(
-            Optional<DesktopModeController> desktopModeController,
-            Optional<DesktopTasksController> desktopTasksController) {
-        if (DesktopModeStatus.isProto2Enabled()) {
-            return desktopTasksController.map(DesktopTasksController::asDesktopMode);
-        }
+            Optional<DesktopModeController> desktopModeController) {
         return desktopModeController.map(DesktopModeController::asDesktopMode);
     }
 
@@ -705,23 +700,6 @@
 
     @BindsOptionalOf
     @DynamicOverride
-    abstract DesktopTasksController optionalDesktopTasksController();
-
-    @WMSingleton
-    @Provides
-    static Optional<DesktopTasksController> providesDesktopTasksController(
-            @DynamicOverride Optional<Lazy<DesktopTasksController>> desktopTasksController) {
-        // Use optional-of-lazy for the dependency that this provider relies on.
-        // Lazy ensures that this provider will not be the cause the dependency is created
-        // when it will not be returned due to the condition below.
-        if (DesktopModeStatus.isProto2Enabled()) {
-            return desktopTasksController.map(Lazy::get);
-        }
-        return Optional.empty();
-    }
-
-    @BindsOptionalOf
-    @DynamicOverride
     abstract DesktopModeTaskRepository optionalDesktopModeTaskRepository();
 
     @WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 701a3a4..6be8305 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -50,7 +50,6 @@
 import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.desktopmode.DesktopModeController;
 import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
-import com.android.wm.shell.desktopmode.DesktopTasksController;
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.freeform.FreeformComponents;
 import com.android.wm.shell.freeform.FreeformTaskListener;
@@ -190,8 +189,7 @@
             ShellTaskOrganizer taskOrganizer,
             DisplayController displayController,
             SyncTransactionQueue syncQueue,
-            Optional<DesktopModeController> desktopModeController,
-            Optional<DesktopTasksController> desktopTasksController) {
+            Optional<DesktopModeController> desktopModeController) {
         return new CaptionWindowDecorViewModel(
                     context,
                     mainHandler,
@@ -199,8 +197,7 @@
                     taskOrganizer,
                     displayController,
                     syncQueue,
-                    desktopModeController,
-                    desktopTasksController);
+                    desktopModeController);
     }
 
     //
@@ -619,22 +616,6 @@
     @WMSingleton
     @Provides
     @DynamicOverride
-    static DesktopTasksController provideDesktopTasksController(
-            Context context,
-            ShellInit shellInit,
-            ShellController shellController,
-            ShellTaskOrganizer shellTaskOrganizer,
-            Transitions transitions,
-            @DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository,
-            @ShellMainThread ShellExecutor mainExecutor
-    ) {
-        return new DesktopTasksController(context, shellInit, shellController, shellTaskOrganizer,
-                transitions, desktopModeTaskRepository, mainExecutor);
-    }
-
-    @WMSingleton
-    @Provides
-    @DynamicOverride
     static DesktopModeTaskRepository provideDesktopModeTaskRepository() {
         return new DesktopModeTaskRepository();
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
index 055949f..67f4a19 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
@@ -70,13 +70,9 @@
      * @return {@code true} if active
      */
     public static boolean isActive(Context context) {
-        if (!isAnyEnabled()) {
+        if (!IS_SUPPORTED) {
             return false;
         }
-        if (isProto2Enabled()) {
-            // Desktop mode is always active in prototype 2
-            return true;
-        }
         try {
             int result = Settings.System.getIntForUser(context.getContentResolver(),
                     Settings.System.DESKTOP_MODE, UserHandle.USER_CURRENT);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
deleted file mode 100644
index b075b14..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ /dev/null
@@ -1,231 +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.wm.shell.desktopmode
-
-import android.app.ActivityManager
-import android.app.WindowConfiguration
-import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
-import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
-import android.app.WindowConfiguration.WindowingMode
-import android.content.Context
-import android.view.WindowManager
-import android.window.WindowContainerTransaction
-import androidx.annotation.BinderThread
-import com.android.internal.protolog.common.ProtoLog
-import com.android.wm.shell.ShellTaskOrganizer
-import com.android.wm.shell.common.ExecutorUtils
-import com.android.wm.shell.common.ExternalInterfaceBinder
-import com.android.wm.shell.common.RemoteCallable
-import com.android.wm.shell.common.ShellExecutor
-import com.android.wm.shell.common.annotations.ExternalThread
-import com.android.wm.shell.common.annotations.ShellMainThread
-import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener
-import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
-import com.android.wm.shell.sysui.ShellController
-import com.android.wm.shell.sysui.ShellInit
-import com.android.wm.shell.sysui.ShellSharedConstants
-import com.android.wm.shell.transition.Transitions
-import java.util.concurrent.Executor
-import java.util.function.Consumer
-
-/** Handles moving tasks in and out of desktop */
-class DesktopTasksController(
-    private val context: Context,
-    shellInit: ShellInit,
-    private val shellController: ShellController,
-    private val shellTaskOrganizer: ShellTaskOrganizer,
-    private val transitions: Transitions,
-    private val desktopModeTaskRepository: DesktopModeTaskRepository,
-    @ShellMainThread private val mainExecutor: ShellExecutor
-) : RemoteCallable<DesktopTasksController> {
-
-    private val desktopMode: DesktopModeImpl
-
-    init {
-        desktopMode = DesktopModeImpl()
-        if (DesktopModeStatus.isProto2Enabled()) {
-            shellInit.addInitCallback({ onInit() }, this)
-        }
-    }
-
-    private fun onInit() {
-        ProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopTasksController")
-        shellController.addExternalInterface(
-            ShellSharedConstants.KEY_EXTRA_SHELL_DESKTOP_MODE,
-            { createExternalInterface() },
-            this
-        )
-    }
-
-    /** Show all tasks, that are part of the desktop, on top of launcher */
-    fun showDesktopApps() {
-        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "showDesktopApps")
-        val wct = WindowContainerTransaction()
-
-        bringDesktopAppsToFront(wct)
-
-        // Execute transaction if there are pending operations
-        if (!wct.isEmpty) {
-            if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-                transitions.startTransition(WindowManager.TRANSIT_TO_FRONT, wct, null /* handler */)
-            } else {
-                shellTaskOrganizer.applyTransaction(wct)
-            }
-        }
-    }
-
-    /** Move a task with given `taskId` to desktop */
-    fun moveToDesktop(taskId: Int) {
-        shellTaskOrganizer.getRunningTaskInfo(taskId)?.let { task -> moveToDesktop(task) }
-    }
-
-    /** Move a task to desktop */
-    fun moveToDesktop(task: ActivityManager.RunningTaskInfo) {
-        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "moveToDesktop: %d", task.taskId)
-
-        val wct = WindowContainerTransaction()
-        // Bring other apps to front first
-        bringDesktopAppsToFront(wct)
-
-        wct.setWindowingMode(task.getToken(), WindowConfiguration.WINDOWING_MODE_FREEFORM)
-        wct.reorder(task.getToken(), true /* onTop */)
-
-        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-            transitions.startTransition(WindowManager.TRANSIT_CHANGE, wct, null /* handler */)
-        } else {
-            shellTaskOrganizer.applyTransaction(wct)
-        }
-    }
-
-    /** Move a task with given `taskId` to fullscreen */
-    fun moveToFullscreen(taskId: Int) {
-        shellTaskOrganizer.getRunningTaskInfo(taskId)?.let { task -> moveToFullscreen(task) }
-    }
-
-    /** Move a task to fullscreen */
-    fun moveToFullscreen(task: ActivityManager.RunningTaskInfo) {
-        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "moveToFullscreen: %d", task.taskId)
-
-        val wct = WindowContainerTransaction()
-        wct.setWindowingMode(task.getToken(), WindowConfiguration.WINDOWING_MODE_FULLSCREEN)
-        wct.setBounds(task.getToken(), null)
-        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-            transitions.startTransition(WindowManager.TRANSIT_CHANGE, wct, null /* handler */)
-        } else {
-            shellTaskOrganizer.applyTransaction(wct)
-        }
-    }
-
-    /**
-     * Get windowing move for a given `taskId`
-     *
-     * @return [WindowingMode] for the task or [WINDOWING_MODE_UNDEFINED] if task is not found
-     */
-    @WindowingMode
-    fun getTaskWindowingMode(taskId: Int): Int {
-        return shellTaskOrganizer.getRunningTaskInfo(taskId)?.windowingMode
-            ?: WINDOWING_MODE_UNDEFINED
-    }
-
-    private fun bringDesktopAppsToFront(wct: WindowContainerTransaction) {
-        val activeTasks = desktopModeTaskRepository.getActiveTasks()
-
-        // Skip if all tasks are already visible
-        if (activeTasks.isNotEmpty() && activeTasks.all(desktopModeTaskRepository::isVisibleTask)) {
-            ProtoLog.d(
-                WM_SHELL_DESKTOP_MODE,
-                "bringDesktopAppsToFront: active tasks are already in front, skipping."
-            )
-            return
-        }
-
-        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront")
-
-        // First move home to front and then other tasks on top of it
-        moveHomeTaskToFront(wct)
-
-        val allTasksInZOrder = desktopModeTaskRepository.getFreeformTasksInZOrder()
-        activeTasks
-            // Sort descending as the top task is at index 0. It should be ordered to top last
-            .sortedByDescending { taskId -> allTasksInZOrder.indexOf(taskId) }
-            .mapNotNull { taskId -> shellTaskOrganizer.getRunningTaskInfo(taskId) }
-            .forEach { task -> wct.reorder(task.token, true /* onTop */) }
-    }
-
-    private fun moveHomeTaskToFront(wct: WindowContainerTransaction) {
-        shellTaskOrganizer
-            .getRunningTasks(context.displayId)
-            .firstOrNull { task -> task.activityType == ACTIVITY_TYPE_HOME }
-            ?.let { homeTask -> wct.reorder(homeTask.getToken(), true /* onTop */) }
-    }
-
-    override fun getContext(): Context {
-        return context
-    }
-
-    override fun getRemoteCallExecutor(): ShellExecutor {
-        return mainExecutor
-    }
-
-    /** Creates a new instance of the external interface to pass to another process. */
-    private fun createExternalInterface(): ExternalInterfaceBinder {
-        return IDesktopModeImpl(this)
-    }
-
-    /** Get connection interface between sysui and shell */
-    fun asDesktopMode(): DesktopMode {
-        return desktopMode
-    }
-
-    /**
-     * Adds a listener to find out about changes in the visibility of freeform tasks.
-     *
-     * @param listener the listener to add.
-     * @param callbackExecutor the executor to call the listener on.
-     */
-    fun addListener(listener: VisibleTasksListener, callbackExecutor: Executor) {
-        desktopModeTaskRepository.addVisibleTasksListener(listener, callbackExecutor)
-    }
-
-    /** The interface for calls from outside the shell, within the host process. */
-    @ExternalThread
-    private inner class DesktopModeImpl : DesktopMode {
-        override fun addListener(listener: VisibleTasksListener, callbackExecutor: Executor) {
-            mainExecutor.execute {
-                this@DesktopTasksController.addListener(listener, callbackExecutor)
-            }
-        }
-    }
-
-    /** The interface for calls from outside the host process. */
-    @BinderThread
-    private class IDesktopModeImpl(private var controller: DesktopTasksController?) :
-        IDesktopMode.Stub(), ExternalInterfaceBinder {
-        /** Invalidates this instance, preventing future calls from updating the controller. */
-        override fun invalidate() {
-            controller = null
-        }
-
-        override fun showDesktopApps() {
-            ExecutorUtils.executeRemoteCallWithTaskPermission(
-                controller,
-                "showDesktopApps",
-                Consumer(DesktopTasksController::showDesktopApps)
-            )
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index 3cb40c5..afefd5d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -52,7 +52,6 @@
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.desktopmode.DesktopModeController;
 import com.android.wm.shell.desktopmode.DesktopModeStatus;
-import com.android.wm.shell.desktopmode.DesktopTasksController;
 import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
 import com.android.wm.shell.transition.Transitions;
 
@@ -77,7 +76,6 @@
     private final SyncTransactionQueue mSyncQueue;
     private FreeformTaskTransitionStarter mTransitionStarter;
     private Optional<DesktopModeController> mDesktopModeController;
-    private Optional<DesktopTasksController> mDesktopTasksController;
     private boolean mTransitionDragActive;
 
     private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
@@ -93,8 +91,7 @@
             ShellTaskOrganizer taskOrganizer,
             DisplayController displayController,
             SyncTransactionQueue syncQueue,
-            Optional<DesktopModeController> desktopModeController,
-            Optional<DesktopTasksController> desktopTasksController) {
+            Optional<DesktopModeController> desktopModeController) {
         this(
                 context,
                 mainHandler,
@@ -103,7 +100,6 @@
                 displayController,
                 syncQueue,
                 desktopModeController,
-                desktopTasksController,
                 new CaptionWindowDecoration.Factory(),
                 InputManager::getInstance);
     }
@@ -116,7 +112,6 @@
             DisplayController displayController,
             SyncTransactionQueue syncQueue,
             Optional<DesktopModeController> desktopModeController,
-            Optional<DesktopTasksController> desktopTasksController,
             CaptionWindowDecoration.Factory captionWindowDecorFactory,
             Supplier<InputManager> inputManagerSupplier) {
 
@@ -128,7 +123,6 @@
         mDisplayController = displayController;
         mSyncQueue = syncQueue;
         mDesktopModeController = desktopModeController;
-        mDesktopTasksController = desktopTasksController;
 
         mCaptionWindowDecorFactory = captionWindowDecorFactory;
         mInputManagerSupplier = inputManagerSupplier;
@@ -254,13 +248,11 @@
                 decoration.createHandleMenu();
             } else if (id == R.id.desktop_button) {
                 mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
-                mDesktopTasksController.ifPresent(c -> c.moveToDesktop(mTaskId));
                 decoration.closeHandleMenu();
             } else if (id == R.id.fullscreen_button) {
                 mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(false));
-                mDesktopTasksController.ifPresent(c -> c.moveToFullscreen(mTaskId));
                 decoration.closeHandleMenu();
-                decoration.setButtonVisibility(false);
+                decoration.setButtonVisibility();
             }
         }
 
@@ -313,13 +305,8 @@
          */
         private void handleEventForMove(MotionEvent e) {
             RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
-            if (DesktopModeStatus.isProto2Enabled()
-                    && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
-                return;
-            }
-            if (DesktopModeStatus.isProto1Enabled() && mDesktopModeController.isPresent()
-                    && mDesktopModeController.get().getDisplayAreaWindowingMode(
-                    taskInfo.displayId)
+            if (mDesktopModeController.isPresent()
+                    && mDesktopModeController.get().getDisplayAreaWindowingMode(taskInfo.displayId)
                     == WINDOWING_MODE_FULLSCREEN) {
                 return;
             }
@@ -343,20 +330,9 @@
                             .stableInsets().top;
                     mDragResizeCallback.onDragResizeEnd(
                             e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
-                    if (e.getRawY(dragPointerIdx) <= statusBarHeight) {
-                        if (DesktopModeStatus.isProto2Enabled()) {
-                            if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
-                                // Switch a single task to fullscreen
-                                mDesktopTasksController.ifPresent(
-                                        c -> c.moveToFullscreen(taskInfo));
-                            }
-                        } else if (DesktopModeStatus.isProto1Enabled()) {
-                            if (DesktopModeStatus.isActive(mContext)) {
-                                // Turn off desktop mode
-                                mDesktopModeController.ifPresent(
-                                        c -> c.setDesktopModeActive(false));
-                            }
-                        }
+                    if (e.getRawY(dragPointerIdx) <= statusBarHeight
+                            && DesktopModeStatus.isActive(mContext)) {
+                        mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(false));
                     }
                     break;
                 }
@@ -444,27 +420,13 @@
      * @param ev the {@link MotionEvent} received by {@link EventReceiver}
      */
     private void handleReceivedMotionEvent(MotionEvent ev, InputMonitor inputMonitor) {
-        if (DesktopModeStatus.isProto2Enabled()) {
-            CaptionWindowDecoration focusedDecor = getFocusedDecor();
-            if (focusedDecor == null
-                    || focusedDecor.mTaskInfo.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
-                handleCaptionThroughStatusBar(ev);
-            }
-        } else if (DesktopModeStatus.isProto1Enabled()) {
-            if (!DesktopModeStatus.isActive(mContext)) {
-                handleCaptionThroughStatusBar(ev);
-            }
+        if (!DesktopModeStatus.isActive(mContext)) {
+            handleCaptionThroughStatusBar(ev);
         }
         handleEventOutsideFocusedCaption(ev);
         // Prevent status bar from reacting to a caption drag.
-        if (DesktopModeStatus.isProto2Enabled()) {
-            if (mTransitionDragActive) {
-                inputMonitor.pilferPointers();
-            }
-        } else if (DesktopModeStatus.isProto1Enabled()) {
-            if (mTransitionDragActive && !DesktopModeStatus.isActive(mContext)) {
-                inputMonitor.pilferPointers();
-            }
+        if (mTransitionDragActive && !DesktopModeStatus.isActive(mContext)) {
+            inputMonitor.pilferPointers();
         }
     }
 
@@ -493,20 +455,9 @@
             case MotionEvent.ACTION_DOWN: {
                 // Begin drag through status bar if applicable.
                 CaptionWindowDecoration focusedDecor = getFocusedDecor();
-                if (focusedDecor != null) {
-                    boolean dragFromStatusBarAllowed = false;
-                    if (DesktopModeStatus.isProto2Enabled()) {
-                        // In proto2 any full screen task can be dragged to freeform
-                        dragFromStatusBarAllowed = focusedDecor.mTaskInfo.getWindowingMode()
-                                == WINDOWING_MODE_FULLSCREEN;
-                    } else if (DesktopModeStatus.isProto1Enabled()) {
-                        // In proto1 task can be dragged to freeform when not in desktop mode
-                        dragFromStatusBarAllowed = !DesktopModeStatus.isActive(mContext);
-                    }
-
-                    if (dragFromStatusBarAllowed && focusedDecor.checkTouchEventInHandle(ev)) {
-                        mTransitionDragActive = true;
-                    }
+                if (focusedDecor != null && !DesktopModeStatus.isActive(mContext)
+                        && focusedDecor.checkTouchEventInHandle(ev)) {
+                    mTransitionDragActive = true;
                 }
                 break;
             }
@@ -521,13 +472,7 @@
                     int statusBarHeight = mDisplayController
                             .getDisplayLayout(focusedDecor.mTaskInfo.displayId).stableInsets().top;
                     if (ev.getY() > statusBarHeight) {
-                        if (DesktopModeStatus.isProto2Enabled()) {
-                            mDesktopTasksController.ifPresent(
-                                    c -> c.moveToDesktop(focusedDecor.mTaskInfo));
-                        } else if (DesktopModeStatus.isProto1Enabled()) {
-                            mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
-                        }
-
+                        mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
                         return;
                     }
                 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index f7c7a87..037ca20 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -16,9 +16,8 @@
 
 package com.android.wm.shell.windowdecor;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-
 import android.app.ActivityManager;
+import android.app.WindowConfiguration;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -118,7 +117,7 @@
                 ? R.dimen.freeform_decor_shadow_focused_thickness
                 : R.dimen.freeform_decor_shadow_unfocused_thickness;
         final boolean isFreeform =
-                taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM;
+                taskInfo.getWindowingMode() == WindowConfiguration.WINDOWING_MODE_FREEFORM;
         final boolean isDragResizeable = isFreeform && taskInfo.isResizeable;
 
         WindowDecorLinearLayout oldRootView = mResult.mRootView;
@@ -168,17 +167,11 @@
         // If this task is not focused, do not show caption.
         setCaptionVisibility(mTaskInfo.isFocused);
 
-        if (mTaskInfo.isFocused) {
-            if (DesktopModeStatus.isProto2Enabled()) {
-                updateButtonVisibility();
-            } else if (DesktopModeStatus.isProto1Enabled()) {
-                // Only handle should show if Desktop Mode is inactive.
-                boolean desktopCurrentStatus = DesktopModeStatus.isActive(mContext);
-                if (mDesktopActive != desktopCurrentStatus) {
-                    mDesktopActive = desktopCurrentStatus;
-                    setButtonVisibility(mDesktopActive);
-                }
-            }
+        // Only handle should show if Desktop Mode is inactive.
+        boolean desktopCurrentStatus = DesktopModeStatus.isActive(mContext);
+        if (mDesktopActive != desktopCurrentStatus && mTaskInfo.isFocused) {
+            mDesktopActive = desktopCurrentStatus;
+            setButtonVisibility();
         }
 
         if (!isDragResizeable) {
@@ -221,7 +214,7 @@
         View handle = caption.findViewById(R.id.caption_handle);
         handle.setOnTouchListener(mOnCaptionTouchListener);
         handle.setOnClickListener(mOnCaptionButtonClickListener);
-        updateButtonVisibility();
+        setButtonVisibility();
     }
 
     private void setupHandleMenu() {
@@ -251,25 +244,14 @@
     /**
      * Sets the visibility of buttons and color of caption based on desktop mode status
      */
-    void updateButtonVisibility() {
-        if (DesktopModeStatus.isProto2Enabled()) {
-            setButtonVisibility(mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM);
-        } else if (DesktopModeStatus.isProto1Enabled()) {
-            mDesktopActive = DesktopModeStatus.isActive(mContext);
-            setButtonVisibility(mDesktopActive);
-        }
-    }
-
-    /**
-     * Show or hide buttons
-     */
-    void setButtonVisibility(boolean visible) {
-        int visibility = visible ? View.VISIBLE : View.GONE;
+    void setButtonVisibility() {
+        mDesktopActive = DesktopModeStatus.isActive(mContext);
+        int v = mDesktopActive ? View.VISIBLE : View.GONE;
         View caption = mResult.mRootView.findViewById(R.id.caption);
         View back = caption.findViewById(R.id.back_button);
         View close = caption.findViewById(R.id.close_window);
-        back.setVisibility(visibility);
-        close.setVisibility(visibility);
+        back.setVisibility(v);
+        close.setVisibility(v);
         int buttonTintColorRes =
                 mDesktopActive ? R.color.decor_button_dark_color
                         : R.color.decor_button_light_color;
@@ -278,7 +260,7 @@
         View handle = caption.findViewById(R.id.caption_handle);
         VectorDrawable handleBackground = (VectorDrawable) handle.getBackground();
         handleBackground.setTintList(buttonTintColor);
-        caption.getBackground().setTint(visible ? Color.WHITE : Color.TRANSPARENT);
+        caption.getBackground().setTint(v == View.VISIBLE ? Color.WHITE : Color.TRANSPARENT);
     }
 
     boolean isHandleMenuActive() {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
index a3ba767..707c049 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell.desktopmode;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
@@ -27,9 +29,6 @@
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-import static com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask;
-import static com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTask;
-import static com.android.wm.shell.desktopmode.DesktopTestHelpers.createHomeTask;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -49,6 +48,7 @@
 import android.testing.AndroidTestingRunner;
 import android.window.DisplayAreaInfo;
 import android.window.TransitionRequestInfo;
+import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 import android.window.WindowContainerTransaction.Change;
 import android.window.WindowContainerTransaction.HierarchyOp;
@@ -59,6 +59,7 @@
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestRunningTaskInfoBuilder;
 import com.android.wm.shell.TestShellExecutor;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.sysui.ShellController;
@@ -354,7 +355,7 @@
     @Test
     public void testHandleTransitionRequest_taskOpen_returnsWct() {
         RunningTaskInfo trigger = new RunningTaskInfo();
-        trigger.token = new MockToken().token();
+        trigger.token = new MockToken().mToken;
         trigger.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
         WindowContainerTransaction wct = mController.handleRequest(
                 mock(IBinder.class),
@@ -380,13 +381,40 @@
     }
 
     private DisplayAreaInfo createMockDisplayArea() {
-        DisplayAreaInfo displayAreaInfo = new DisplayAreaInfo(new MockToken().token(),
+        DisplayAreaInfo displayAreaInfo = new DisplayAreaInfo(new MockToken().mToken,
                 mContext.getDisplayId(), 0);
         when(mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(mContext.getDisplayId()))
                 .thenReturn(displayAreaInfo);
         return displayAreaInfo;
     }
 
+    private RunningTaskInfo createFreeformTask() {
+        return new TestRunningTaskInfoBuilder()
+                .setToken(new MockToken().token())
+                .setActivityType(ACTIVITY_TYPE_STANDARD)
+                .setWindowingMode(WINDOWING_MODE_FREEFORM)
+                .setLastActiveTime(100)
+                .build();
+    }
+
+    private RunningTaskInfo createFullscreenTask() {
+        return new TestRunningTaskInfoBuilder()
+                .setToken(new MockToken().token())
+                .setActivityType(ACTIVITY_TYPE_STANDARD)
+                .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
+                .setLastActiveTime(100)
+                .build();
+    }
+
+    private RunningTaskInfo createHomeTask() {
+        return new TestRunningTaskInfoBuilder()
+                .setToken(new MockToken().token())
+                .setActivityType(ACTIVITY_TYPE_HOME)
+                .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
+                .setLastActiveTime(100)
+                .build();
+    }
+
     private WindowContainerTransaction getDesktopModeSwitchTransaction() {
         ArgumentCaptor<WindowContainerTransaction> arg = ArgumentCaptor.forClass(
                 WindowContainerTransaction.class);
@@ -414,4 +442,18 @@
         assertThat(change.getConfiguration().windowConfiguration.getBounds().isEmpty()).isTrue();
     }
 
+    private static class MockToken {
+        private final WindowContainerToken mToken;
+        private final IBinder mBinder;
+
+        MockToken() {
+            mToken = mock(WindowContainerToken.class);
+            mBinder = mock(IBinder.class);
+            when(mToken.asBinder()).thenReturn(mBinder);
+        }
+
+        WindowContainerToken token() {
+            return mToken;
+        }
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
deleted file mode 100644
index de2473b..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ /dev/null
@@ -1,281 +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.wm.shell.desktopmode
-
-import android.app.ActivityManager.RunningTaskInfo
-import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
-import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
-import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
-import android.testing.AndroidTestingRunner
-import android.window.WindowContainerTransaction
-import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER
-import androidx.test.filters.SmallTest
-import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
-import com.android.dx.mockito.inline.extended.ExtendedMockito.never
-import com.android.dx.mockito.inline.extended.StaticMockitoSession
-import com.android.wm.shell.ShellTaskOrganizer
-import com.android.wm.shell.ShellTestCase
-import com.android.wm.shell.TestShellExecutor
-import com.android.wm.shell.common.ShellExecutor
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createHomeTask
-import com.android.wm.shell.sysui.ShellController
-import com.android.wm.shell.sysui.ShellInit
-import com.android.wm.shell.transition.Transitions
-import com.google.common.truth.Truth.assertThat
-import com.google.common.truth.Truth.assertWithMessage
-import org.junit.After
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers.isNull
-import org.mockito.Mock
-import org.mockito.Mockito
-import org.mockito.Mockito.any
-import org.mockito.Mockito.anyInt
-import org.mockito.Mockito.clearInvocations
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
-
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-class DesktopTasksControllerTest : ShellTestCase() {
-
-    @Mock lateinit var testExecutor: ShellExecutor
-    @Mock lateinit var shellController: ShellController
-    @Mock lateinit var shellTaskOrganizer: ShellTaskOrganizer
-    @Mock lateinit var transitions: Transitions
-
-    lateinit var mockitoSession: StaticMockitoSession
-    lateinit var controller: DesktopTasksController
-    lateinit var shellInit: ShellInit
-    lateinit var desktopModeTaskRepository: DesktopModeTaskRepository
-
-    // Mock running tasks are registered here so we can get the list from mock shell task organizer
-    private val runningTasks = mutableListOf<RunningTaskInfo>()
-
-    @Before
-    fun setUp() {
-        mockitoSession = mockitoSession().mockStatic(DesktopModeStatus::class.java).startMocking()
-        whenever(DesktopModeStatus.isProto2Enabled()).thenReturn(true)
-
-        shellInit = Mockito.spy(ShellInit(testExecutor))
-        desktopModeTaskRepository = DesktopModeTaskRepository()
-
-        whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenAnswer { runningTasks }
-
-        controller = createController()
-
-        shellInit.init()
-    }
-
-    private fun createController(): DesktopTasksController {
-        return DesktopTasksController(
-            context,
-            shellInit,
-            shellController,
-            shellTaskOrganizer,
-            transitions,
-            desktopModeTaskRepository,
-            TestShellExecutor()
-        )
-    }
-
-    @After
-    fun tearDown() {
-        mockitoSession.finishMocking()
-
-        runningTasks.clear()
-    }
-
-    @Test
-    fun instantiate_addInitCallback() {
-        verify(shellInit).addInitCallback(any(), any<DesktopTasksController>())
-    }
-
-    @Test
-    fun instantiate_flagOff_doNotAddInitCallback() {
-        whenever(DesktopModeStatus.isProto2Enabled()).thenReturn(false)
-        clearInvocations(shellInit)
-
-        createController()
-
-        verify(shellInit, never()).addInitCallback(any(), any<DesktopTasksController>())
-    }
-
-    @Test
-    fun showDesktopApps_allAppsInvisible_bringsToFront() {
-        val homeTask = setUpHomeTask()
-        val task1 = setUpFreeformTask()
-        val task2 = setUpFreeformTask()
-        markTaskHidden(task1)
-        markTaskHidden(task2)
-
-        controller.showDesktopApps()
-
-        val wct = getLatestWct()
-        assertThat(wct.hierarchyOps).hasSize(3)
-        // Expect order to be from bottom: home, task1, task2
-        wct.assertReorderAt(index = 0, homeTask)
-        wct.assertReorderAt(index = 1, task1)
-        wct.assertReorderAt(index = 2, task2)
-    }
-
-    @Test
-    fun showDesktopApps_appsAlreadyVisible_doesNothing() {
-        setUpHomeTask()
-        val task1 = setUpFreeformTask()
-        val task2 = setUpFreeformTask()
-        markTaskVisible(task1)
-        markTaskVisible(task2)
-
-        controller.showDesktopApps()
-
-        verifyWCTNotExecuted()
-    }
-
-    @Test
-    fun showDesktopApps_someAppsInvisible_reordersAll() {
-        val homeTask = setUpHomeTask()
-        val task1 = setUpFreeformTask()
-        val task2 = setUpFreeformTask()
-        markTaskHidden(task1)
-        markTaskVisible(task2)
-
-        controller.showDesktopApps()
-
-        val wct = getLatestWct()
-        assertThat(wct.hierarchyOps).hasSize(3)
-        // Expect order to be from bottom: home, task1, task2
-        wct.assertReorderAt(index = 0, homeTask)
-        wct.assertReorderAt(index = 1, task1)
-        wct.assertReorderAt(index = 2, task2)
-    }
-
-    @Test
-    fun showDesktopApps_noActiveTasks_reorderHomeToTop() {
-        val homeTask = setUpHomeTask()
-
-        controller.showDesktopApps()
-
-        val wct = getLatestWct()
-        assertThat(wct.hierarchyOps).hasSize(1)
-        wct.assertReorderAt(index = 0, homeTask)
-    }
-
-    @Test
-    fun moveToDesktop() {
-        val task = setUpFullscreenTask()
-        controller.moveToDesktop(task)
-        val wct = getLatestWct()
-        assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
-            .isEqualTo(WINDOWING_MODE_FREEFORM)
-    }
-
-    @Test
-    fun moveToDesktop_nonExistentTask_doesNothing() {
-        controller.moveToDesktop(999)
-        verifyWCTNotExecuted()
-    }
-
-    @Test
-    fun moveToFullscreen() {
-        val task = setUpFreeformTask()
-        controller.moveToFullscreen(task)
-        val wct = getLatestWct()
-        assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
-            .isEqualTo(WINDOWING_MODE_FULLSCREEN)
-    }
-
-    @Test
-    fun moveToFullscreen_nonExistentTask_doesNothing() {
-        controller.moveToFullscreen(999)
-        verifyWCTNotExecuted()
-    }
-
-    @Test
-    fun getTaskWindowingMode() {
-        val fullscreenTask = setUpFullscreenTask()
-        val freeformTask = setUpFreeformTask()
-
-        assertThat(controller.getTaskWindowingMode(fullscreenTask.taskId))
-            .isEqualTo(WINDOWING_MODE_FULLSCREEN)
-        assertThat(controller.getTaskWindowingMode(freeformTask.taskId))
-            .isEqualTo(WINDOWING_MODE_FREEFORM)
-        assertThat(controller.getTaskWindowingMode(999)).isEqualTo(WINDOWING_MODE_UNDEFINED)
-    }
-
-    private fun setUpFreeformTask(): RunningTaskInfo {
-        val task = createFreeformTask()
-        whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
-        desktopModeTaskRepository.addActiveTask(task.taskId)
-        desktopModeTaskRepository.addOrMoveFreeformTaskToTop(task.taskId)
-        runningTasks.add(task)
-        return task
-    }
-
-    private fun setUpHomeTask(): RunningTaskInfo {
-        val task = createHomeTask()
-        whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
-        runningTasks.add(task)
-        return task
-    }
-
-    private fun setUpFullscreenTask(): RunningTaskInfo {
-        val task = createFullscreenTask()
-        whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
-        runningTasks.add(task)
-        return task
-    }
-
-    private fun markTaskVisible(task: RunningTaskInfo) {
-        desktopModeTaskRepository.updateVisibleFreeformTasks(task.taskId, visible = true)
-    }
-
-    private fun markTaskHidden(task: RunningTaskInfo) {
-        desktopModeTaskRepository.updateVisibleFreeformTasks(task.taskId, visible = false)
-    }
-
-    private fun getLatestWct(): WindowContainerTransaction {
-        val arg = ArgumentCaptor.forClass(WindowContainerTransaction::class.java)
-        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-            verify(transitions).startTransition(anyInt(), arg.capture(), isNull())
-        } else {
-            verify(shellTaskOrganizer).applyTransaction(arg.capture())
-        }
-        return arg.value
-    }
-
-    private fun verifyWCTNotExecuted() {
-        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-            verify(transitions, never()).startTransition(anyInt(), any(), isNull())
-        } else {
-            verify(shellTaskOrganizer, never()).applyTransaction(any())
-        }
-    }
-}
-
-private fun WindowContainerTransaction.assertReorderAt(index: Int, task: RunningTaskInfo) {
-    assertWithMessage("WCT does not have a hierarchy operation at index $index")
-        .that(hierarchyOps.size)
-        .isGreaterThan(index)
-    val op = hierarchyOps[index]
-    assertThat(op.type).isEqualTo(HIERARCHY_OP_TYPE_REORDER)
-    assertThat(op.container).isEqualTo(task.token.asBinder())
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
deleted file mode 100644
index dc91d75..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
+++ /dev/null
@@ -1,61 +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.wm.shell.desktopmode
-
-import android.app.ActivityManager.RunningTaskInfo
-import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
-import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
-import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
-import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
-import com.android.wm.shell.TestRunningTaskInfoBuilder
-
-class DesktopTestHelpers {
-    companion object {
-        /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */
-        @JvmStatic
-        fun createFreeformTask(): RunningTaskInfo {
-            return TestRunningTaskInfoBuilder()
-                    .setToken(MockToken().token())
-                    .setActivityType(ACTIVITY_TYPE_STANDARD)
-                    .setWindowingMode(WINDOWING_MODE_FREEFORM)
-                    .setLastActiveTime(100)
-                    .build()
-        }
-
-        /** Create a task that has windowing mode set to [WINDOWING_MODE_FULLSCREEN] */
-        @JvmStatic
-        fun createFullscreenTask(): RunningTaskInfo {
-            return TestRunningTaskInfoBuilder()
-                    .setToken(MockToken().token())
-                    .setActivityType(ACTIVITY_TYPE_STANDARD)
-                    .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
-                    .setLastActiveTime(100)
-                    .build()
-        }
-
-        /** Create a new home task */
-        @JvmStatic
-        fun createHomeTask(): RunningTaskInfo {
-            return TestRunningTaskInfoBuilder()
-                    .setToken(MockToken().token())
-                    .setActivityType(ACTIVITY_TYPE_HOME)
-                    .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
-                    .setLastActiveTime(100)
-                    .build()
-        }
-    }
-}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/MockToken.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/MockToken.java
deleted file mode 100644
index 09d474d..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/MockToken.java
+++ /dev/null
@@ -1,40 +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.wm.shell.desktopmode;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.os.IBinder;
-import android.window.WindowContainerToken;
-
-/**
- * {@link WindowContainerToken} wrapper that supports a mock binder
- */
-class MockToken {
-    private final WindowContainerToken mToken;
-
-    MockToken() {
-        mToken = mock(WindowContainerToken.class);
-        IBinder binder = mock(IBinder.class);
-        when(mToken.asBinder()).thenReturn(binder);
-    }
-
-    WindowContainerToken token() {
-        return mToken;
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModelTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModelTests.java
index 87f9d21..ad6fced 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModelTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModelTests.java
@@ -47,7 +47,6 @@
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.desktopmode.DesktopModeController;
-import com.android.wm.shell.desktopmode.DesktopTasksController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -77,8 +76,6 @@
 
     @Mock private DesktopModeController mDesktopModeController;
 
-    @Mock private DesktopTasksController mDesktopTasksController;
-
     @Mock private InputMonitor mInputMonitor;
 
     @Mock private InputChannel mInputChannel;
@@ -106,7 +103,6 @@
                 mDisplayController,
                 mSyncQueue,
                 Optional.of(mDesktopModeController),
-                Optional.of(mDesktopTasksController),
                 mCaptionWindowDecorFactory,
                 new MockObjectSupplier<>(mMockInputManagers, () -> mock(InputManager.class)));
         mCaptionWindowDecorViewModel.setEventReceiverFactory(mEventReceiverFactory);
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index acaa008..be56c89 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -23,11 +23,6 @@
         xmlns:tools="http://schemas.android.com/tools"
         coreApp="true">
 
-    <!-- Using OpenGL ES 2.0 -->
-    <uses-feature
-        android:glEsVersion="0x00020000"
-        android:required="true" />
-
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 
     <!-- Used to read wallpaper -->
diff --git a/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl b/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl
deleted file mode 100644
index e4b6e07..0000000
--- a/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl
+++ /dev/null
@@ -1,11 +0,0 @@
-precision mediump float;
-
-// The actual wallpaper texture.
-uniform sampler2D uTexture;
-
-varying vec2 vTextureCoordinates;
-
-void main() {
-    // gets the pixel value of the wallpaper for this uv coordinates on screen.
-    gl_FragColor = texture2D(uTexture, vTextureCoordinates);
-}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/image_wallpaper_vertex_shader.glsl b/packages/SystemUI/res/raw/image_wallpaper_vertex_shader.glsl
deleted file mode 100644
index 4393e2b..0000000
--- a/packages/SystemUI/res/raw/image_wallpaper_vertex_shader.glsl
+++ /dev/null
@@ -1,8 +0,0 @@
-attribute vec4 aPosition;
-attribute vec2 aTextureCoordinates;
-varying vec2 vTextureCoordinates;
-
-void main() {
-    vTextureCoordinates = aTextureCoordinates;
-    gl_Position = aPosition;
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
index 9e58500..886d110 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
@@ -54,35 +54,6 @@
         buffer.log(TAG, INFO, { str1 = arg.toString() }, { "$msg: $str1" })
     }
 
-    // TODO: remove after b/237743330 is fixed
-    fun logStatusBarCalculatedAlpha(alpha: Float) {
-        buffer.log(TAG, DEBUG, { double1 = alpha.toDouble() }, { "Calculated new alpha: $double1" })
-    }
-
-    // TODO: remove after b/237743330 is fixed
-    fun logStatusBarExplicitAlpha(alpha: Float) {
-        buffer.log(
-            TAG,
-            DEBUG,
-            { double1 = alpha.toDouble() },
-            { "new mExplicitAlpha value: $double1" }
-        )
-    }
-
-    // TODO: remove after b/237743330 is fixed
-    fun logStatusBarAlphaVisibility(visibility: Int, alpha: Float, state: String) {
-        buffer.log(
-            TAG,
-            DEBUG,
-            {
-                int1 = visibility
-                double1 = alpha.toDouble()
-                str1 = state
-            },
-            { "changing visibility to $int1 with alpha $double1 in state: $str1" }
-        )
-    }
-
     @JvmOverloads
     fun logBiometricMessage(
         @CompileTimeConstant context: String,
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 8dc0371..1ee51ce 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -254,10 +254,6 @@
     // TODO(b/254512848): Tracking Bug
     val REGION_SAMPLING = unreleasedFlag(801, "region_sampling", teamfood = true)
 
-    // 802 - wallpaper rendering
-    // TODO(b/254512923): Tracking Bug
-    @JvmField val USE_CANVAS_RENDERER = unreleasedFlag(802, "use_canvas_renderer")
-
     // 803 - screen contents translation
     // TODO(b/254513187): Tracking Bug
     val SCREEN_CONTENTS_TRANSLATION = unreleasedFlag(803, "screen_contents_translation")
@@ -291,6 +287,9 @@
 
     @JvmField val MEDIA_FALSING_PENALTY = unreleasedFlag(908, "media_falsing_media")
 
+    // TODO(b/261734857): Tracking Bug
+    @JvmField val UMO_TURBULENCE_NOISE = unreleasedFlag(909, "umo_turbulence_noise")
+
     // 1000 - dock
     val SIMULATE_DOCK_THROUGH_CHARGING = releasedFlag(1000, "simulate_dock_through_charging")
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
index c2442d6..db7a145 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
@@ -224,6 +224,8 @@
     private TurbulenceNoiseController mTurbulenceNoiseController;
     private FeatureFlags mFeatureFlags;
     private TurbulenceNoiseAnimationConfig mTurbulenceNoiseAnimationConfig = null;
+    @VisibleForTesting
+    MultiRippleController.Companion.RipplesFinishedListener mRipplesFinishedListener = null;
 
     /**
      * Initialize a new control panel
@@ -404,15 +406,17 @@
         MultiRippleView multiRippleView = vh.getMultiRippleView();
         mMultiRippleController = new MultiRippleController(multiRippleView);
         mTurbulenceNoiseController = new TurbulenceNoiseController(vh.getTurbulenceNoiseView());
-        mMultiRippleController.addRipplesFinishedListener(
-                () -> {
-                    if (mTurbulenceNoiseAnimationConfig == null) {
-                        mTurbulenceNoiseAnimationConfig = createLingeringNoiseAnimation();
-                    }
-                    // Color will be correctly updated in ColorSchemeTransition.
-                    mTurbulenceNoiseController.play(mTurbulenceNoiseAnimationConfig);
+        if (mFeatureFlags.isEnabled(Flags.UMO_TURBULENCE_NOISE)) {
+            mRipplesFinishedListener = () -> {
+                if (mTurbulenceNoiseAnimationConfig == null) {
+                    mTurbulenceNoiseAnimationConfig = createLingeringNoiseAnimation();
                 }
-        );
+                // Color will be correctly updated in ColorSchemeTransition.
+                mTurbulenceNoiseController.play(mTurbulenceNoiseAnimationConfig);
+            };
+            mMultiRippleController.addRipplesFinishedListener(mRipplesFinishedListener);
+        }
+
         mColorSchemeTransition = new ColorSchemeTransition(
                 mContext, mMediaViewHolder, mMultiRippleController, mTurbulenceNoiseController);
         mMetadataAnimationHandler = new MetadataAnimationHandler(exit, enter);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index c217ab3..69f7c71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -22,6 +22,8 @@
 import android.util.MathUtils;
 import android.view.View;
 
+import androidx.annotation.NonNull;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.widget.ViewClippingUtil;
 import com.android.systemui.R;
@@ -197,6 +199,11 @@
         updateHeadsUpAndPulsingRoundness(entry);
     }
 
+    @Override
+    public void onHeadsUpStateChanged(@NonNull NotificationEntry entry, boolean isHeadsUp) {
+        updateHeadsUpAndPulsingRoundness(entry);
+    }
+
     private void updateTopEntry() {
         NotificationEntry newEntry = null;
         if (shouldBeVisible()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index d4dc1dc..3483574 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -475,9 +475,6 @@
             newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
                     * mKeyguardStatusBarAnimateAlpha
                     * (1.0f - mKeyguardHeadsUpShowingAmount);
-            if (newAlpha != mView.getAlpha() && (newAlpha == 0 || newAlpha == 1)) {
-                mLogger.logStatusBarCalculatedAlpha(newAlpha);
-            }
         }
 
         boolean hideForBypass =
@@ -500,10 +497,6 @@
         if (mDisableStateTracker.isDisabled()) {
             visibility = View.INVISIBLE;
         }
-        if (visibility != mView.getVisibility()) {
-            mLogger.logStatusBarAlphaVisibility(visibility, alpha,
-                    StatusBarState.toString(mStatusBarState));
-        }
         mView.setAlpha(alpha);
         mView.setVisibility(visibility);
     }
@@ -608,10 +601,6 @@
      * @param alpha a value between 0 and 1. -1 if the value is to be reset/ignored.
      */
     public void setAlpha(float alpha) {
-        if (mExplicitAlpha != alpha && (mExplicitAlpha == -1 || alpha == -1)) {
-            // logged if value changed to ignored or from ignored
-            mLogger.logStatusBarExplicitAlpha(alpha);
-        }
         mExplicitAlpha = alpha;
         updateViewState();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
index ef43702..1f1b32c 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.wallpapers;
 
-import static com.android.systemui.flags.Flags.USE_CANVAS_RENDERER;
-
 import android.app.WallpaperColors;
 import android.app.WallpaperManager;
 import android.graphics.Bitmap;
@@ -27,16 +25,10 @@
 import android.graphics.RectF;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.service.wallpaper.WallpaperService;
-import android.util.ArraySet;
 import android.util.Log;
-import android.util.MathUtils;
-import android.util.Size;
 import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.view.WindowManager;
@@ -45,16 +37,10 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.util.concurrency.DelayableExecutor;
-import com.android.systemui.wallpapers.canvas.WallpaperLocalColorExtractor;
-import com.android.systemui.wallpapers.gl.EglHelper;
-import com.android.systemui.wallpapers.gl.ImageWallpaperRenderer;
 
 import java.io.FileDescriptor;
-import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.ArrayList;
 import java.util.List;
 
 import javax.inject.Inject;
@@ -64,455 +50,32 @@
  */
 @SuppressWarnings({"UnusedDeclaration"})
 public class ImageWallpaper extends WallpaperService {
+
     private static final String TAG = ImageWallpaper.class.getSimpleName();
-    // We delayed destroy render context that subsequent render requests have chance to cancel it.
-    // This is to avoid destroying then recreating render context in a very short time.
-    private static final int DELAY_FINISH_RENDERING = 1000;
-    private static final @android.annotation.NonNull RectF LOCAL_COLOR_BOUNDS =
-            new RectF(0, 0, 1, 1);
     private static final boolean DEBUG = false;
 
-    private final ArrayList<RectF> mLocalColorsToAdd = new ArrayList<>();
-    private final ArraySet<RectF> mColorAreas = new ArraySet<>();
+    // keep track of the number of pages of the launcher for local color extraction purposes
     private volatile int mPages = 1;
     private boolean mPagesComputed = false;
-    private HandlerThread mWorker;
-    // scaled down version
-    private Bitmap mMiniBitmap;
-    private final FeatureFlags mFeatureFlags;
 
-    // used in canvasEngine to load/unload the bitmap and extract the colors
+    // used for most tasks (call canvas.drawBitmap, load/unload the bitmap)
     @Background
     private final DelayableExecutor mBackgroundExecutor;
+
+    // wait at least this duration before unloading the bitmap
     private static final int DELAY_UNLOAD_BITMAP = 2000;
 
     @Inject
-    public ImageWallpaper(FeatureFlags featureFlags,
-            @Background DelayableExecutor backgroundExecutor) {
+    public ImageWallpaper(@Background DelayableExecutor backgroundExecutor) {
         super();
-        mFeatureFlags = featureFlags;
         mBackgroundExecutor = backgroundExecutor;
     }
 
     @Override
-    public void onCreate() {
-        super.onCreate();
-        mWorker = new HandlerThread(TAG);
-        mWorker.start();
-    }
-
-    @Override
     public Engine onCreateEngine() {
-        return mFeatureFlags.isEnabled(USE_CANVAS_RENDERER) ? new CanvasEngine() : new GLEngine();
+        return new CanvasEngine();
     }
 
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        mWorker.quitSafely();
-        mWorker = null;
-        mMiniBitmap = null;
-    }
-
-    class GLEngine extends Engine implements DisplayListener {
-        // Surface is rejected if size below a threshold on some devices (ie. 8px on elfin)
-        // set min to 64 px (CTS covers this), please refer to ag/4867989 for detail.
-        @VisibleForTesting
-        static final int MIN_SURFACE_WIDTH = 128;
-        @VisibleForTesting
-        static final int MIN_SURFACE_HEIGHT = 128;
-
-        private ImageWallpaperRenderer mRenderer;
-        private EglHelper mEglHelper;
-        private final Runnable mFinishRenderingTask = this::finishRendering;
-        private boolean mNeedRedraw;
-
-        private boolean mDisplaySizeValid = false;
-        private int mDisplayWidth = 1;
-        private int mDisplayHeight = 1;
-
-        private int mImgWidth = 1;
-        private int mImgHeight = 1;
-
-        GLEngine() { }
-
-        @VisibleForTesting
-        GLEngine(Handler handler) {
-            super(SystemClock::elapsedRealtime, handler);
-        }
-
-        @Override
-        public void onCreate(SurfaceHolder surfaceHolder) {
-            Trace.beginSection("ImageWallpaper.Engine#onCreate");
-            mEglHelper = getEglHelperInstance();
-            // Deferred init renderer because we need to get wallpaper by display context.
-            mRenderer = getRendererInstance();
-            setFixedSizeAllowed(true);
-            updateSurfaceSize();
-            setShowForAllUsers(true);
-
-            mRenderer.setOnBitmapChanged(b -> {
-                mLocalColorsToAdd.addAll(mColorAreas);
-                if (mLocalColorsToAdd.size() > 0) {
-                    updateMiniBitmapAndNotify(b);
-                }
-            });
-            getDisplayContext().getSystemService(DisplayManager.class)
-                    .registerDisplayListener(this, mWorker.getThreadHandler());
-            Trace.endSection();
-        }
-
-        @Override
-        public void onDisplayAdded(int displayId) { }
-
-        @Override
-        public void onDisplayRemoved(int displayId) { }
-
-        @Override
-        public void onDisplayChanged(int displayId) {
-            if (displayId == getDisplayContext().getDisplayId()) {
-                mDisplaySizeValid = false;
-            }
-        }
-
-        EglHelper getEglHelperInstance() {
-            return new EglHelper();
-        }
-
-        ImageWallpaperRenderer getRendererInstance() {
-            return new ImageWallpaperRenderer(getDisplayContext());
-        }
-
-        @Override
-        public void onOffsetsChanged(float xOffset, float yOffset,
-                float xOffsetStep, float yOffsetStep,
-                int xPixelOffset, int yPixelOffset) {
-            final int pages;
-            if (xOffsetStep > 0 && xOffsetStep <= 1) {
-                pages = (int) Math.round(1 / xOffsetStep) + 1;
-            } else {
-                pages = 1;
-            }
-            if (pages == mPages) return;
-            mPages = pages;
-            if (mMiniBitmap == null || mMiniBitmap.isRecycled()) return;
-            mWorker.getThreadHandler().post(() ->
-                    computeAndNotifyLocalColors(new ArrayList<>(mColorAreas), mMiniBitmap));
-        }
-
-        private void updateMiniBitmapAndNotify(Bitmap b) {
-            if (b == null) return;
-            int size = Math.min(b.getWidth(), b.getHeight());
-            float scale = 1.0f;
-            if (size > MIN_SURFACE_WIDTH) {
-                scale = (float) MIN_SURFACE_WIDTH / (float) size;
-            }
-            mImgHeight = b.getHeight();
-            mImgWidth = b.getWidth();
-            mMiniBitmap = Bitmap.createScaledBitmap(b,  (int) Math.max(scale * b.getWidth(), 1),
-                    (int) Math.max(scale * b.getHeight(), 1), false);
-            computeAndNotifyLocalColors(mLocalColorsToAdd, mMiniBitmap);
-            mLocalColorsToAdd.clear();
-        }
-
-        private void updateSurfaceSize() {
-            Trace.beginSection("ImageWallpaper#updateSurfaceSize");
-            SurfaceHolder holder = getSurfaceHolder();
-            Size frameSize = mRenderer.reportSurfaceSize();
-            int width = Math.max(MIN_SURFACE_WIDTH, frameSize.getWidth());
-            int height = Math.max(MIN_SURFACE_HEIGHT, frameSize.getHeight());
-            holder.setFixedSize(width, height);
-            Trace.endSection();
-        }
-
-        @Override
-        public boolean shouldZoomOutWallpaper() {
-            return true;
-        }
-
-        @Override
-        public boolean shouldWaitForEngineShown() {
-            return true;
-        }
-
-        @Override
-        public void onDestroy() {
-            getDisplayContext().getSystemService(DisplayManager.class)
-                    .unregisterDisplayListener(this);
-            mMiniBitmap = null;
-            mWorker.getThreadHandler().post(() -> {
-                mRenderer.finish();
-                mRenderer = null;
-                mEglHelper.finish();
-                mEglHelper = null;
-            });
-        }
-
-        @Override
-        public boolean supportsLocalColorExtraction() {
-            return true;
-        }
-
-        @Override
-        public void addLocalColorsAreas(@NonNull List<RectF> regions) {
-            mWorker.getThreadHandler().post(() -> {
-                if (mColorAreas.size() + mLocalColorsToAdd.size() == 0) {
-                    setOffsetNotificationsEnabled(true);
-                }
-                Bitmap bitmap = mMiniBitmap;
-                if (bitmap == null) {
-                    mLocalColorsToAdd.addAll(regions);
-                    if (mRenderer != null) mRenderer.use(this::updateMiniBitmapAndNotify);
-                } else {
-                    computeAndNotifyLocalColors(regions, bitmap);
-                }
-            });
-        }
-
-        private void computeAndNotifyLocalColors(@NonNull List<RectF> regions, Bitmap b) {
-            List<WallpaperColors> colors = getLocalWallpaperColors(regions, b);
-            mColorAreas.addAll(regions);
-            try {
-                notifyLocalColorsChanged(regions, colors);
-            } catch (RuntimeException e) {
-                Log.e(TAG, e.getMessage(), e);
-            }
-        }
-
-        @Override
-        public void removeLocalColorsAreas(@NonNull List<RectF> regions) {
-            mWorker.getThreadHandler().post(() -> {
-                mColorAreas.removeAll(regions);
-                mLocalColorsToAdd.removeAll(regions);
-                if (mColorAreas.size() + mLocalColorsToAdd.size() == 0) {
-                    setOffsetNotificationsEnabled(false);
-                }
-            });
-        }
-
-        /**
-         * Transform the logical coordinates into wallpaper coordinates.
-         *
-         * Logical coordinates are organised such that the various pages are non-overlapping. So,
-         * if there are n pages, the first page will have its X coordinate on the range [0-1/n].
-         *
-         * The real pages are overlapping. If the Wallpaper are a width Ww and the screen a width
-         * Ws, the relative width of a page Wr is Ws/Ww. This does not change if the number of
-         * pages increase.
-         * If there are n pages, the page k starts at the offset k * (1 - Wr) / (n - 1), as the
-         * last page is at position (1-Wr) and the others are regularly spread on the range [0-
-         * (1-Wr)].
-         */
-        private RectF pageToImgRect(RectF area) {
-            if (!mDisplaySizeValid) {
-                Rect window = getDisplayContext()
-                        .getSystemService(WindowManager.class)
-                        .getCurrentWindowMetrics()
-                        .getBounds();
-                mDisplayWidth = window.width();
-                mDisplayHeight = window.height();
-                mDisplaySizeValid = true;
-            }
-
-            // Width of a page for the caller of this API.
-            float virtualPageWidth = 1f / (float) mPages;
-            float leftPosOnPage = (area.left % virtualPageWidth) / virtualPageWidth;
-            float rightPosOnPage = (area.right % virtualPageWidth) / virtualPageWidth;
-            int currentPage = (int) Math.floor(area.centerX() / virtualPageWidth);
-
-            RectF imgArea = new RectF();
-
-            if (mImgWidth == 0 || mImgHeight == 0 || mDisplayWidth <= 0 || mDisplayHeight <= 0) {
-                return imgArea;
-            }
-
-            imgArea.bottom = area.bottom;
-            imgArea.top = area.top;
-
-            float imageScale = Math.min(((float) mImgHeight) / mDisplayHeight, 1);
-            float mappedScreenWidth = mDisplayWidth * imageScale;
-            float pageWidth = Math.min(1.0f,
-                    mImgWidth > 0 ? mappedScreenWidth / (float) mImgWidth : 1.f);
-            float pageOffset = (1 - pageWidth) / (float) (mPages - 1);
-
-            imgArea.left = MathUtils.constrain(
-                    leftPosOnPage * pageWidth + currentPage * pageOffset, 0, 1);
-            imgArea.right = MathUtils.constrain(
-                    rightPosOnPage * pageWidth + currentPage * pageOffset, 0, 1);
-            if (imgArea.left > imgArea.right) {
-                // take full page
-                imgArea.left = 0;
-                imgArea.right = 1;
-            }
-            return imgArea;
-        }
-
-        private List<WallpaperColors> getLocalWallpaperColors(@NonNull List<RectF> areas,
-                Bitmap b) {
-            List<WallpaperColors> colors = new ArrayList<>(areas.size());
-            for (int i = 0; i < areas.size(); i++) {
-                RectF area = pageToImgRect(areas.get(i));
-                if (area == null || !LOCAL_COLOR_BOUNDS.contains(area)) {
-                    colors.add(null);
-                    continue;
-                }
-                Rect subImage = new Rect(
-                        (int) Math.floor(area.left * b.getWidth()),
-                        (int) Math.floor(area.top * b.getHeight()),
-                        (int) Math.ceil(area.right * b.getWidth()),
-                        (int) Math.ceil(area.bottom * b.getHeight()));
-                if (subImage.isEmpty()) {
-                    // Do not notify client. treat it as too small to sample
-                    colors.add(null);
-                    continue;
-                }
-                Bitmap colorImg = Bitmap.createBitmap(b,
-                        subImage.left, subImage.top, subImage.width(), subImage.height());
-                WallpaperColors color = WallpaperColors.fromBitmap(colorImg);
-                colors.add(color);
-            }
-            return colors;
-        }
-
-        @Override
-        public void onSurfaceCreated(SurfaceHolder holder) {
-            if (mWorker == null) return;
-            mWorker.getThreadHandler().post(() -> {
-                Trace.beginSection("ImageWallpaper#onSurfaceCreated");
-                mEglHelper.init(holder, needSupportWideColorGamut());
-                mRenderer.onSurfaceCreated();
-                Trace.endSection();
-            });
-        }
-
-        @Override
-        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-            if (mWorker == null) return;
-            mWorker.getThreadHandler().post(() -> mRenderer.onSurfaceChanged(width, height));
-        }
-
-        @Override
-        public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
-            if (mWorker == null) return;
-            mWorker.getThreadHandler().post(this::drawFrame);
-        }
-
-        private void drawFrame() {
-            Trace.beginSection("ImageWallpaper#drawFrame");
-            preRender();
-            requestRender();
-            postRender();
-            Trace.endSection();
-        }
-
-        public void preRender() {
-            // This method should only be invoked from worker thread.
-            Trace.beginSection("ImageWallpaper#preRender");
-            preRenderInternal();
-            Trace.endSection();
-        }
-
-        private void preRenderInternal() {
-            boolean contextRecreated = false;
-            Rect frame = getSurfaceHolder().getSurfaceFrame();
-            cancelFinishRenderingTask();
-
-            // Check if we need to recreate egl context.
-            if (!mEglHelper.hasEglContext()) {
-                mEglHelper.destroyEglSurface();
-                if (!mEglHelper.createEglContext()) {
-                    Log.w(TAG, "recreate egl context failed!");
-                } else {
-                    contextRecreated = true;
-                }
-            }
-
-            // Check if we need to recreate egl surface.
-            if (mEglHelper.hasEglContext() && !mEglHelper.hasEglSurface()) {
-                if (!mEglHelper.createEglSurface(getSurfaceHolder(), needSupportWideColorGamut())) {
-                    Log.w(TAG, "recreate egl surface failed!");
-                }
-            }
-
-            // If we recreate egl context, notify renderer to setup again.
-            if (mEglHelper.hasEglContext() && mEglHelper.hasEglSurface() && contextRecreated) {
-                mRenderer.onSurfaceCreated();
-                mRenderer.onSurfaceChanged(frame.width(), frame.height());
-            }
-        }
-
-        public void requestRender() {
-            // This method should only be invoked from worker thread.
-            Trace.beginSection("ImageWallpaper#requestRender");
-            requestRenderInternal();
-            Trace.endSection();
-        }
-
-        private void requestRenderInternal() {
-            Rect frame = getSurfaceHolder().getSurfaceFrame();
-            boolean readyToRender = mEglHelper.hasEglContext() && mEglHelper.hasEglSurface()
-                    && frame.width() > 0 && frame.height() > 0;
-
-            if (readyToRender) {
-                mRenderer.onDrawFrame();
-                if (!mEglHelper.swapBuffer()) {
-                    Log.e(TAG, "drawFrame failed!");
-                }
-            } else {
-                Log.e(TAG, "requestRender: not ready, has context=" + mEglHelper.hasEglContext()
-                        + ", has surface=" + mEglHelper.hasEglSurface()
-                        + ", frame=" + frame);
-            }
-        }
-
-        public void postRender() {
-            // This method should only be invoked from worker thread.
-            scheduleFinishRendering();
-            reportEngineShown(false /* waitForEngineShown */);
-        }
-
-        private void cancelFinishRenderingTask() {
-            if (mWorker == null) return;
-            mWorker.getThreadHandler().removeCallbacks(mFinishRenderingTask);
-        }
-
-        private void scheduleFinishRendering() {
-            if (mWorker == null) return;
-            cancelFinishRenderingTask();
-            mWorker.getThreadHandler().postDelayed(mFinishRenderingTask, DELAY_FINISH_RENDERING);
-        }
-
-        private void finishRendering() {
-            Trace.beginSection("ImageWallpaper#finishRendering");
-            if (mEglHelper != null) {
-                mEglHelper.destroyEglSurface();
-                mEglHelper.destroyEglContext();
-            }
-            Trace.endSection();
-        }
-
-        private boolean needSupportWideColorGamut() {
-            return mRenderer.isWcgContent();
-        }
-
-        @Override
-        protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
-            super.dump(prefix, fd, out, args);
-            out.print(prefix); out.print("Engine="); out.println(this);
-            out.print(prefix); out.print("valid surface=");
-            out.println(getSurfaceHolder() != null && getSurfaceHolder().getSurface() != null
-                    ? getSurfaceHolder().getSurface().isValid()
-                    : "null");
-
-            out.print(prefix); out.print("surface frame=");
-            out.println(getSurfaceHolder() != null ? getSurfaceHolder().getSurfaceFrame() : "null");
-
-            mEglHelper.dump(prefix, fd, out, args);
-            mRenderer.dump(prefix, fd, out, args);
-        }
-    }
-
-
     class CanvasEngine extends WallpaperService.Engine implements DisplayListener {
         private WallpaperManager mWallpaperManager;
         private final WallpaperLocalColorExtractor mWallpaperLocalColorExtractor;
@@ -736,13 +299,8 @@
                 // be loaded, we will go into a cycle. Don't do a build where the
                 // default wallpaper can't be loaded.
                 Log.w(TAG, "Unable to load wallpaper!", exception);
-                try {
-                    mWallpaperManager.clear(WallpaperManager.FLAG_SYSTEM);
-                } catch (IOException ex) {
-                    // now we're really screwed.
-                    Log.w(TAG, "Unable reset to default wallpaper!", ex);
-                }
-
+                mWallpaperManager.clearWallpaper(
+                        WallpaperManager.FLAG_SYSTEM, UserHandle.USER_CURRENT);
                 try {
                     bitmap = mWallpaperManager.getBitmapAsUser(UserHandle.USER_CURRENT, false);
                 } catch (RuntimeException | OutOfMemoryError e) {
@@ -868,7 +426,6 @@
             mWallpaperLocalColorExtractor.setDisplayDimensions(window.width(), window.height());
         }
 
-
         @Override
         protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
             super.dump(prefix, fd, out, args);
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/canvas/WallpaperLocalColorExtractor.java b/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/wallpapers/canvas/WallpaperLocalColorExtractor.java
rename to packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
index 6cac5c9..988fd71 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/canvas/WallpaperLocalColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
@@ -15,7 +15,7 @@
  */
 
 
-package com.android.systemui.wallpapers.canvas;
+package com.android.systemui.wallpapers;
 
 import android.app.WallpaperColors;
 import android.graphics.Bitmap;
@@ -31,7 +31,6 @@
 
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.util.Assert;
-import com.android.systemui.wallpapers.ImageWallpaper;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/gl/EglHelper.java b/packages/SystemUI/src/com/android/systemui/wallpapers/gl/EglHelper.java
deleted file mode 100644
index f9ddce8..0000000
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/gl/EglHelper.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2019 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.systemui.wallpapers.gl;
-
-import static android.opengl.EGL14.EGL_ALPHA_SIZE;
-import static android.opengl.EGL14.EGL_BLUE_SIZE;
-import static android.opengl.EGL14.EGL_CONFIG_CAVEAT;
-import static android.opengl.EGL14.EGL_CONTEXT_CLIENT_VERSION;
-import static android.opengl.EGL14.EGL_DEFAULT_DISPLAY;
-import static android.opengl.EGL14.EGL_DEPTH_SIZE;
-import static android.opengl.EGL14.EGL_EXTENSIONS;
-import static android.opengl.EGL14.EGL_GREEN_SIZE;
-import static android.opengl.EGL14.EGL_NONE;
-import static android.opengl.EGL14.EGL_NO_CONTEXT;
-import static android.opengl.EGL14.EGL_NO_DISPLAY;
-import static android.opengl.EGL14.EGL_NO_SURFACE;
-import static android.opengl.EGL14.EGL_OPENGL_ES2_BIT;
-import static android.opengl.EGL14.EGL_RED_SIZE;
-import static android.opengl.EGL14.EGL_RENDERABLE_TYPE;
-import static android.opengl.EGL14.EGL_STENCIL_SIZE;
-import static android.opengl.EGL14.EGL_SUCCESS;
-import static android.opengl.EGL14.eglChooseConfig;
-import static android.opengl.EGL14.eglCreateContext;
-import static android.opengl.EGL14.eglCreateWindowSurface;
-import static android.opengl.EGL14.eglDestroyContext;
-import static android.opengl.EGL14.eglDestroySurface;
-import static android.opengl.EGL14.eglGetDisplay;
-import static android.opengl.EGL14.eglGetError;
-import static android.opengl.EGL14.eglInitialize;
-import static android.opengl.EGL14.eglMakeCurrent;
-import static android.opengl.EGL14.eglQueryString;
-import static android.opengl.EGL14.eglSwapBuffers;
-import static android.opengl.EGL14.eglTerminate;
-
-import android.opengl.EGLConfig;
-import android.opengl.EGLContext;
-import android.opengl.EGLDisplay;
-import android.opengl.EGLSurface;
-import android.opengl.GLUtils;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.SurfaceHolder;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A helper class to handle EGL management.
- */
-public class EglHelper {
-    private static final String TAG = EglHelper.class.getSimpleName();
-    private static final int OPENGLES_VERSION = 2;
-    // Below two constants make drawing at low priority, so other things can preempt our drawing.
-    private static final int EGL_CONTEXT_PRIORITY_LEVEL_IMG = 0x3100;
-    private static final int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103;
-    private static final boolean DEBUG = true;
-
-    private static final int EGL_GL_COLORSPACE_KHR = 0x309D;
-    private static final int EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT = 0x3490;
-
-    private static final String EGL_IMG_CONTEXT_PRIORITY = "EGL_IMG_context_priority";
-
-    /**
-     * https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_gl_colorspace.txt
-     */
-    private static final String KHR_GL_COLOR_SPACE = "EGL_KHR_gl_colorspace";
-
-    /**
-     * https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_gl_colorspace_display_p3_passthrough.txt
-     */
-    private static final String EXT_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH =
-            "EGL_EXT_gl_colorspace_display_p3_passthrough";
-
-    private EGLDisplay mEglDisplay;
-    private EGLConfig mEglConfig;
-    private EGLContext mEglContext;
-    private EGLSurface mEglSurface;
-    private final int[] mEglVersion = new int[2];
-    private boolean mEglReady;
-    private final Set<String> mExts;
-
-    public EglHelper() {
-        mExts = new HashSet<>();
-        connectDisplay();
-    }
-
-    /**
-     * Initialize render context.
-     * @param surfaceHolder surface holder.
-     * @param wideColorGamut claim if a wcg surface is necessary.
-     * @return true if the render context is ready.
-     */
-    public boolean init(SurfaceHolder surfaceHolder, boolean wideColorGamut) {
-        if (!hasEglDisplay() && !connectDisplay()) {
-            Log.w(TAG, "Can not connect display, abort!");
-            return false;
-        }
-
-        if (!eglInitialize(mEglDisplay, mEglVersion, 0 /* majorOffset */,
-                    mEglVersion, 1 /* minorOffset */)) {
-            Log.w(TAG, "eglInitialize failed: " + GLUtils.getEGLErrorString(eglGetError()));
-            return false;
-        }
-
-        mEglConfig = chooseEglConfig();
-        if (mEglConfig == null) {
-            Log.w(TAG, "eglConfig not initialized!");
-            return false;
-        }
-
-        if (!createEglContext()) {
-            Log.w(TAG, "Can't create EGLContext!");
-            return false;
-        }
-
-        if (!createEglSurface(surfaceHolder, wideColorGamut)) {
-            Log.w(TAG, "Can't create EGLSurface!");
-            return false;
-        }
-
-        mEglReady = true;
-        return true;
-    }
-
-    private boolean connectDisplay() {
-        mExts.clear();
-        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-        if (!hasEglDisplay()) {
-            Log.w(TAG, "eglGetDisplay failed: " + GLUtils.getEGLErrorString(eglGetError()));
-            return false;
-        }
-        String queryString = eglQueryString(mEglDisplay, EGL_EXTENSIONS);
-        if (!TextUtils.isEmpty(queryString)) {
-            Collections.addAll(mExts, queryString.split(" "));
-        }
-        return true;
-    }
-
-    boolean checkExtensionCapability(String extName) {
-        return mExts.contains(extName);
-    }
-
-    int getWcgCapability() {
-        if (checkExtensionCapability(EXT_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH)) {
-            return EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT;
-        }
-        return 0;
-    }
-
-    private EGLConfig chooseEglConfig() {
-        int[] configsCount = new int[1];
-        EGLConfig[] configs = new EGLConfig[1];
-        int[] configSpec = getConfig();
-        if (!eglChooseConfig(mEglDisplay, configSpec, 0, configs, 0, 1, configsCount, 0)) {
-            Log.w(TAG, "eglChooseConfig failed: " + GLUtils.getEGLErrorString(eglGetError()));
-            return null;
-        } else {
-            if (configsCount[0] <= 0) {
-                Log.w(TAG, "eglChooseConfig failed, invalid configs count: " + configsCount[0]);
-                return null;
-            } else {
-                return configs[0];
-            }
-        }
-    }
-
-    private int[] getConfig() {
-        return new int[] {
-            EGL_RED_SIZE, 8,
-            EGL_GREEN_SIZE, 8,
-            EGL_BLUE_SIZE, 8,
-            EGL_ALPHA_SIZE, 0,
-            EGL_DEPTH_SIZE, 0,
-            EGL_STENCIL_SIZE, 0,
-            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-            EGL_CONFIG_CAVEAT, EGL_NONE,
-            EGL_NONE
-        };
-    }
-
-    /**
-     * Prepare an EglSurface.
-     * @param surfaceHolder surface holder.
-     * @param wcg if need to support wcg.
-     * @return true if EglSurface is ready.
-     */
-    public boolean createEglSurface(SurfaceHolder surfaceHolder, boolean wcg) {
-        if (DEBUG) {
-            Log.d(TAG, "createEglSurface start");
-        }
-
-        if (hasEglDisplay() && surfaceHolder.getSurface().isValid()) {
-            int[] attrs = null;
-            int wcgCapability = getWcgCapability();
-            if (wcg && checkExtensionCapability(KHR_GL_COLOR_SPACE) && wcgCapability > 0) {
-                attrs = new int[] {EGL_GL_COLORSPACE_KHR, wcgCapability, EGL_NONE};
-            }
-            mEglSurface = askCreatingEglWindowSurface(surfaceHolder, attrs, 0 /* offset */);
-        } else {
-            Log.w(TAG, "Create EglSurface failed: hasEglDisplay=" + hasEglDisplay()
-                    + ", has valid surface=" + surfaceHolder.getSurface().isValid());
-            return false;
-        }
-
-        if (!hasEglSurface()) {
-            Log.w(TAG, "createWindowSurface failed: " + GLUtils.getEGLErrorString(eglGetError()));
-            return false;
-        }
-
-        if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
-            Log.w(TAG, "eglMakeCurrent failed: " + GLUtils.getEGLErrorString(eglGetError()));
-            return false;
-        }
-
-        if (DEBUG) {
-            Log.d(TAG, "createEglSurface done");
-        }
-        return true;
-    }
-
-    EGLSurface askCreatingEglWindowSurface(SurfaceHolder holder, int[] attrs, int offset) {
-        return eglCreateWindowSurface(mEglDisplay, mEglConfig, holder, attrs, offset);
-    }
-
-    /**
-     * Destroy EglSurface.
-     */
-    public void destroyEglSurface() {
-        if (hasEglSurface()) {
-            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-            eglDestroySurface(mEglDisplay, mEglSurface);
-            mEglSurface = EGL_NO_SURFACE;
-        }
-    }
-
-    /**
-     * Check if we have a valid EglSurface.
-     * @return true if EglSurface is ready.
-     */
-    public boolean hasEglSurface() {
-        return mEglSurface != null && mEglSurface != EGL_NO_SURFACE;
-    }
-
-    /**
-     * Prepare EglContext.
-     * @return true if EglContext is ready.
-     */
-    public boolean createEglContext() {
-        if (DEBUG) {
-            Log.d(TAG, "createEglContext start");
-        }
-
-        int[] attrib_list = new int[5];
-        int idx = 0;
-        attrib_list[idx++] = EGL_CONTEXT_CLIENT_VERSION;
-        attrib_list[idx++] = OPENGLES_VERSION;
-        if (checkExtensionCapability(EGL_IMG_CONTEXT_PRIORITY)) {
-            attrib_list[idx++] = EGL_CONTEXT_PRIORITY_LEVEL_IMG;
-            attrib_list[idx++] = EGL_CONTEXT_PRIORITY_LOW_IMG;
-        }
-        attrib_list[idx] = EGL_NONE;
-        if (hasEglDisplay()) {
-            mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attrib_list, 0);
-        } else {
-            Log.w(TAG, "mEglDisplay is null");
-            return false;
-        }
-
-        if (!hasEglContext()) {
-            Log.w(TAG, "eglCreateContext failed: " + GLUtils.getEGLErrorString(eglGetError()));
-            return false;
-        }
-
-        if (DEBUG) {
-            Log.d(TAG, "createEglContext done");
-        }
-        return true;
-    }
-
-    /**
-     * Destroy EglContext.
-     */
-    public void destroyEglContext() {
-        if (hasEglContext()) {
-            eglDestroyContext(mEglDisplay, mEglContext);
-            mEglContext = EGL_NO_CONTEXT;
-        }
-    }
-
-    /**
-     * Check if we have EglContext.
-     * @return true if EglContext is ready.
-     */
-    public boolean hasEglContext() {
-        return mEglContext != null && mEglContext != EGL_NO_CONTEXT;
-    }
-
-    /**
-     * Check if we have EglDisplay.
-     * @return true if EglDisplay is ready.
-     */
-    public boolean hasEglDisplay() {
-        return mEglDisplay != null && mEglDisplay != EGL_NO_DISPLAY;
-    }
-
-    /**
-     * Swap buffer to display.
-     * @return true if swap successfully.
-     */
-    public boolean swapBuffer() {
-        boolean status = eglSwapBuffers(mEglDisplay, mEglSurface);
-        int error = eglGetError();
-        if (error != EGL_SUCCESS) {
-            Log.w(TAG, "eglSwapBuffers failed: " + GLUtils.getEGLErrorString(error));
-        }
-        return status;
-    }
-
-    /**
-     * Destroy EglSurface and EglContext, then terminate EGL.
-     */
-    public void finish() {
-        if (hasEglSurface()) {
-            destroyEglSurface();
-        }
-        if (hasEglContext()) {
-            destroyEglContext();
-        }
-        if (hasEglDisplay()) {
-            terminateEglDisplay();
-        }
-        mEglReady = false;
-    }
-
-    void terminateEglDisplay() {
-        eglTerminate(mEglDisplay);
-        mEglDisplay = EGL_NO_DISPLAY;
-    }
-
-    /**
-     * Called to dump current state.
-     * @param prefix prefix.
-     * @param fd fd.
-     * @param out out.
-     * @param args args.
-     */
-    public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
-        String eglVersion = mEglVersion[0] + "." + mEglVersion[1];
-        out.print(prefix); out.print("EGL version="); out.print(eglVersion);
-        out.print(", "); out.print("EGL ready="); out.print(mEglReady);
-        out.print(", "); out.print("has EglContext="); out.print(hasEglContext());
-        out.print(", "); out.print("has EglSurface="); out.println(hasEglSurface());
-
-        int[] configs = getConfig();
-        StringBuilder sb = new StringBuilder();
-        sb.append('{');
-        for (int egl : configs) {
-            sb.append("0x").append(Integer.toHexString(egl)).append(",");
-        }
-        sb.setCharAt(sb.length() - 1, '}');
-        out.print(prefix); out.print("EglConfig="); out.println(sb.toString());
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/gl/GLWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/wallpapers/gl/GLWallpaperRenderer.java
deleted file mode 100644
index 692ced0..0000000
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/gl/GLWallpaperRenderer.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2019 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.systemui.wallpapers.gl;
-
-import android.util.Size;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * A renderer which is responsible for making OpenGL calls to render a frame.
- */
-public interface GLWallpaperRenderer {
-
-    /**
-     * Check if the content to render is a WCG content.
-     */
-    boolean isWcgContent();
-
-    /**
-     * Called when the surface is created or recreated.
-     */
-    void onSurfaceCreated();
-
-    /**
-     * Called when the surface changed size.
-     * @param width surface width.
-     * @param height surface height.
-     */
-    void onSurfaceChanged(int width, int height);
-
-    /**
-     * Called to draw the current frame.
-     */
-    void onDrawFrame();
-
-    /**
-     * Ask renderer to report the surface size it needs.
-     */
-    Size reportSurfaceSize();
-
-    /**
-     * Called when no need to render any more.
-     */
-    void finish();
-
-    /**
-     * Called to dump current state.
-     * @param prefix prefix.
-     * @param fd fd.
-     * @param out out.
-     * @param args args.
-     */
-    void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args);
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/gl/ImageGLProgram.java b/packages/SystemUI/src/com/android/systemui/wallpapers/gl/ImageGLProgram.java
deleted file mode 100644
index d34eca4..0000000
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/gl/ImageGLProgram.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2019 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.systemui.wallpapers.gl;
-
-import static android.opengl.GLES20.GL_FRAGMENT_SHADER;
-import static android.opengl.GLES20.GL_VERTEX_SHADER;
-import static android.opengl.GLES20.glAttachShader;
-import static android.opengl.GLES20.glCompileShader;
-import static android.opengl.GLES20.glCreateProgram;
-import static android.opengl.GLES20.glCreateShader;
-import static android.opengl.GLES20.glGetAttribLocation;
-import static android.opengl.GLES20.glGetUniformLocation;
-import static android.opengl.GLES20.glLinkProgram;
-import static android.opengl.GLES20.glShaderSource;
-import static android.opengl.GLES20.glUseProgram;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-/**
- * This class takes charge of linking shader codes and then return a handle for OpenGL ES program.
- */
-class ImageGLProgram {
-    private static final String TAG = ImageGLProgram.class.getSimpleName();
-
-    private Context mContext;
-    private int mProgramHandle;
-
-    ImageGLProgram(Context context) {
-        mContext = context.getApplicationContext();
-    }
-
-    private int loadShaderProgram(int vertexId, int fragmentId) {
-        final String vertexSrc = getShaderResource(vertexId);
-        final String fragmentSrc = getShaderResource(fragmentId);
-        final int vertexHandle = getShaderHandle(GL_VERTEX_SHADER, vertexSrc);
-        final int fragmentHandle = getShaderHandle(GL_FRAGMENT_SHADER, fragmentSrc);
-        return getProgramHandle(vertexHandle, fragmentHandle);
-    }
-
-    private String getShaderResource(int shaderId) {
-        Resources res = mContext.getResources();
-        StringBuilder code = new StringBuilder();
-
-        try (BufferedReader reader = new BufferedReader(
-                new InputStreamReader(res.openRawResource(shaderId)))) {
-            String nextLine;
-            while ((nextLine = reader.readLine()) != null) {
-                code.append(nextLine).append("\n");
-            }
-        } catch (IOException | Resources.NotFoundException ex) {
-            Log.d(TAG, "Can not read the shader source", ex);
-            code = null;
-        }
-
-        return code == null ? "" : code.toString();
-    }
-
-    private int getShaderHandle(int type, String src) {
-        final int shader = glCreateShader(type);
-        if (shader == 0) {
-            Log.d(TAG, "Create shader failed, type=" + type);
-            return 0;
-        }
-        glShaderSource(shader, src);
-        glCompileShader(shader);
-        return shader;
-    }
-
-    private int getProgramHandle(int vertexHandle, int fragmentHandle) {
-        final int program = glCreateProgram();
-        if (program == 0) {
-            Log.d(TAG, "Can not create OpenGL ES program");
-            return 0;
-        }
-
-        glAttachShader(program, vertexHandle);
-        glAttachShader(program, fragmentHandle);
-        glLinkProgram(program);
-        return program;
-    }
-
-    boolean useGLProgram(int vertexResId, int fragmentResId) {
-        mProgramHandle = loadShaderProgram(vertexResId, fragmentResId);
-        glUseProgram(mProgramHandle);
-        return true;
-    }
-
-    int getAttributeHandle(String name) {
-        return glGetAttribLocation(mProgramHandle, name);
-    }
-
-    int getUniformHandle(String name) {
-        return glGetUniformLocation(mProgramHandle, name);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/gl/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/wallpapers/gl/ImageGLWallpaper.java
deleted file mode 100644
index f1659b9..0000000
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/gl/ImageGLWallpaper.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2019 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.systemui.wallpapers.gl;
-
-import static android.opengl.GLES20.GL_FLOAT;
-import static android.opengl.GLES20.GL_LINEAR;
-import static android.opengl.GLES20.GL_TEXTURE0;
-import static android.opengl.GLES20.GL_TEXTURE_2D;
-import static android.opengl.GLES20.GL_TEXTURE_MAG_FILTER;
-import static android.opengl.GLES20.GL_TEXTURE_MIN_FILTER;
-import static android.opengl.GLES20.GL_TRIANGLES;
-import static android.opengl.GLES20.glActiveTexture;
-import static android.opengl.GLES20.glBindTexture;
-import static android.opengl.GLES20.glDrawArrays;
-import static android.opengl.GLES20.glEnableVertexAttribArray;
-import static android.opengl.GLES20.glGenTextures;
-import static android.opengl.GLES20.glTexParameteri;
-import static android.opengl.GLES20.glUniform1i;
-import static android.opengl.GLES20.glVertexAttribPointer;
-
-import android.graphics.Bitmap;
-import android.opengl.GLUtils;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-
-/**
- * This class takes charge of the geometry data like vertices and texture coordinates.
- * It delivers these data to opengl runtime and triggers draw calls if necessary.
- */
-class ImageGLWallpaper {
-    private static final String TAG = ImageGLWallpaper.class.getSimpleName();
-
-    private static final String A_POSITION = "aPosition";
-    private static final String A_TEXTURE_COORDINATES = "aTextureCoordinates";
-    private static final String U_TEXTURE = "uTexture";
-    private static final int POSITION_COMPONENT_COUNT = 2;
-    private static final int TEXTURE_COMPONENT_COUNT = 2;
-    private static final int BYTES_PER_FLOAT = 4;
-
-    // Vertices to define the square with 2 triangles.
-    private static final float[] VERTICES = {
-            -1.0f,  -1.0f,
-            +1.0f,  -1.0f,
-            +1.0f,  +1.0f,
-            +1.0f,  +1.0f,
-            -1.0f,  +1.0f,
-            -1.0f,  -1.0f
-    };
-
-    // Texture coordinates that maps to vertices.
-    private static final float[] TEXTURES = {
-            0f, 1f,
-            1f, 1f,
-            1f, 0f,
-            1f, 0f,
-            0f, 0f,
-            0f, 1f
-    };
-
-    private final FloatBuffer mVertexBuffer;
-    private final FloatBuffer mTextureBuffer;
-    private final ImageGLProgram mProgram;
-
-    private int mAttrPosition;
-    private int mAttrTextureCoordinates;
-    private int mUniTexture;
-    private int mTextureId;
-
-    ImageGLWallpaper(ImageGLProgram program) {
-        mProgram = program;
-
-        // Create an float array in opengles runtime (native) and put vertex data.
-        mVertexBuffer = ByteBuffer.allocateDirect(VERTICES.length * BYTES_PER_FLOAT)
-            .order(ByteOrder.nativeOrder())
-            .asFloatBuffer();
-        mVertexBuffer.put(VERTICES);
-        mVertexBuffer.position(0);
-
-        // Create an float array in opengles runtime (native) and put texture data.
-        mTextureBuffer = ByteBuffer.allocateDirect(TEXTURES.length * BYTES_PER_FLOAT)
-            .order(ByteOrder.nativeOrder())
-            .asFloatBuffer();
-        mTextureBuffer.put(TEXTURES);
-        mTextureBuffer.position(0);
-    }
-
-    void setup(Bitmap bitmap) {
-        setupAttributes();
-        setupUniforms();
-        setupTexture(bitmap);
-    }
-
-    private void setupAttributes() {
-        mAttrPosition = mProgram.getAttributeHandle(A_POSITION);
-        mVertexBuffer.position(0);
-        glVertexAttribPointer(mAttrPosition, POSITION_COMPONENT_COUNT, GL_FLOAT,
-                false, 0, mVertexBuffer);
-        glEnableVertexAttribArray(mAttrPosition);
-
-        mAttrTextureCoordinates = mProgram.getAttributeHandle(A_TEXTURE_COORDINATES);
-        mTextureBuffer.position(0);
-        glVertexAttribPointer(mAttrTextureCoordinates, TEXTURE_COMPONENT_COUNT, GL_FLOAT,
-                false, 0, mTextureBuffer);
-        glEnableVertexAttribArray(mAttrTextureCoordinates);
-    }
-
-    private void setupUniforms() {
-        mUniTexture = mProgram.getUniformHandle(U_TEXTURE);
-    }
-
-    void draw() {
-        glDrawArrays(GL_TRIANGLES, 0, VERTICES.length / 2);
-    }
-
-    private void setupTexture(Bitmap bitmap) {
-        final int[] tids = new int[1];
-
-        if (bitmap == null || bitmap.isRecycled()) {
-            Log.w(TAG, "setupTexture: invalid bitmap");
-            return;
-        }
-
-        // Generate one texture object and store the id in tids[0].
-        glGenTextures(1, tids, 0);
-        if (tids[0] == 0) {
-            Log.w(TAG, "setupTexture: glGenTextures() failed");
-            return;
-        }
-
-        try {
-            // Bind a named texture to a target.
-            glBindTexture(GL_TEXTURE_2D, tids[0]);
-            // Load the bitmap data and copy it over into the texture object
-            // that is currently bound.
-            GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
-            // Use bilinear texture filtering when minification.
-            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-            // Use bilinear texture filtering when magnification.
-            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-            mTextureId = tids[0];
-        } catch (IllegalArgumentException e) {
-            Log.w(TAG, "Failed uploading texture: " + e.getLocalizedMessage());
-        }
-    }
-
-    void useTexture() {
-        // Set the active texture unit to texture unit 0.
-        glActiveTexture(GL_TEXTURE0);
-        // Bind the texture to this unit.
-        glBindTexture(GL_TEXTURE_2D, mTextureId);
-        // Let the texture sampler in fragment shader to read form this texture unit.
-        glUniform1i(mUniTexture, 0);
-    }
-
-    /**
-     * Called to dump current state.
-     * @param prefix prefix.
-     * @param fd fd.
-     * @param out out.
-     * @param args args.
-     */
-    public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/gl/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/wallpapers/gl/ImageWallpaperRenderer.java
deleted file mode 100644
index e393786..0000000
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/gl/ImageWallpaperRenderer.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2019 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.systemui.wallpapers.gl;
-
-import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
-import static android.opengl.GLES20.glClear;
-import static android.opengl.GLES20.glClearColor;
-import static android.opengl.GLES20.glViewport;
-
-import android.app.WallpaperManager;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.os.UserHandle;
-import android.util.Log;
-import android.util.Size;
-
-import com.android.systemui.R;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Consumer;
-
-/**
- * A GL renderer for image wallpaper.
- */
-public class ImageWallpaperRenderer implements GLWallpaperRenderer {
-    private static final String TAG = ImageWallpaperRenderer.class.getSimpleName();
-    private static final boolean DEBUG = false;
-
-    private final ImageGLProgram mProgram;
-    private final ImageGLWallpaper mWallpaper;
-    private final Rect mSurfaceSize = new Rect();
-    private final WallpaperTexture mTexture;
-    private Consumer<Bitmap> mOnBitmapUpdated;
-
-    public ImageWallpaperRenderer(Context context) {
-        final WallpaperManager wpm = context.getSystemService(WallpaperManager.class);
-        if (wpm == null) {
-            Log.w(TAG, "WallpaperManager not available");
-        }
-
-        mTexture = new WallpaperTexture(wpm);
-        mProgram = new ImageGLProgram(context);
-        mWallpaper = new ImageGLWallpaper(mProgram);
-    }
-
-    /**
-     * @hide
-     */
-    public void setOnBitmapChanged(Consumer<Bitmap> c) {
-        mOnBitmapUpdated = c;
-    }
-
-    /**
-     * @hide
-     */
-    public void use(Consumer<Bitmap> c) {
-        mTexture.use(c);
-    }
-
-    @Override
-    public boolean isWcgContent() {
-        return mTexture.isWcgContent();
-    }
-
-    @Override
-    public void onSurfaceCreated() {
-        glClearColor(0f, 0f, 0f, 1.0f);
-        mProgram.useGLProgram(
-                R.raw.image_wallpaper_vertex_shader, R.raw.image_wallpaper_fragment_shader);
-
-        mTexture.use(bitmap -> {
-            if (bitmap == null) {
-                Log.w(TAG, "reload texture failed!");
-            } else if (mOnBitmapUpdated != null) {
-                mOnBitmapUpdated.accept(bitmap);
-            }
-            mWallpaper.setup(bitmap);
-        });
-    }
-
-    @Override
-    public void onSurfaceChanged(int width, int height) {
-        glViewport(0, 0, width, height);
-    }
-
-    @Override
-    public void onDrawFrame() {
-        glClear(GL_COLOR_BUFFER_BIT);
-        glViewport(0, 0, mSurfaceSize.width(), mSurfaceSize.height());
-        mWallpaper.useTexture();
-        mWallpaper.draw();
-    }
-
-    @Override
-    public Size reportSurfaceSize() {
-        mSurfaceSize.set(mTexture.getTextureDimensions());
-        return new Size(mSurfaceSize.width(), mSurfaceSize.height());
-    }
-
-    @Override
-    public void finish() {
-    }
-
-    @Override
-    public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
-        out.print(prefix); out.print("mSurfaceSize="); out.print(mSurfaceSize);
-        out.print(prefix); out.print("mWcgContent="); out.print(isWcgContent());
-        mWallpaper.dump(prefix, fd, out, args);
-    }
-
-    static class WallpaperTexture {
-        private final AtomicInteger mRefCount;
-        private final Rect mDimensions;
-        private final WallpaperManager mWallpaperManager;
-        private Bitmap mBitmap;
-        private boolean mWcgContent;
-        private boolean mTextureUsed;
-
-        private WallpaperTexture(WallpaperManager wallpaperManager) {
-            mWallpaperManager = wallpaperManager;
-            mRefCount = new AtomicInteger();
-            mDimensions = new Rect();
-        }
-
-        public void use(Consumer<Bitmap> consumer) {
-            mRefCount.incrementAndGet();
-            synchronized (mRefCount) {
-                if (mBitmap == null) {
-                    mBitmap = mWallpaperManager.getBitmapAsUser(UserHandle.USER_CURRENT,
-                            false /* hardware */);
-                    mWcgContent = mWallpaperManager.wallpaperSupportsWcg(
-                            WallpaperManager.FLAG_SYSTEM);
-                    mWallpaperManager.forgetLoadedWallpaper();
-                    if (mBitmap != null) {
-                        mDimensions.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
-                        mTextureUsed = true;
-                    } else {
-                        Log.w(TAG, "Can't get bitmap");
-                    }
-                }
-            }
-            if (consumer != null) {
-                consumer.accept(mBitmap);
-            }
-            synchronized (mRefCount) {
-                final int count = mRefCount.decrementAndGet();
-                if (count == 0 && mBitmap != null) {
-                    if (DEBUG) {
-                        Log.v(TAG, "WallpaperTexture: release 0x" + getHash()
-                                + ", refCount=" + count);
-                    }
-                    mBitmap.recycle();
-                    mBitmap = null;
-                }
-            }
-        }
-
-        private boolean isWcgContent() {
-            return mWcgContent;
-        }
-
-        private String getHash() {
-            return mBitmap != null ? Integer.toHexString(mBitmap.hashCode()) : "null";
-        }
-
-        private Rect getTextureDimensions() {
-            if (!mTextureUsed) {
-                mDimensions.set(mWallpaperManager.peekBitmapDimensions());
-            }
-            return mDimensions;
-        }
-
-        @Override
-        public String toString() {
-            return "{" + getHash() + ", " + mRefCount.get() + "}";
-        }
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
index fdef344..b65f5cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
@@ -214,6 +214,7 @@
     private val fakeFeatureFlag =
         FakeFeatureFlags().apply {
             this.set(Flags.UMO_SURFACE_RIPPLE, false)
+            this.set(Flags.UMO_TURBULENCE_NOISE, false)
             this.set(Flags.MEDIA_FALSING_PENALTY, true)
         }
 
@@ -2062,6 +2063,26 @@
         assertThat(viewHolder.multiRippleView.ripples.size).isEqualTo(0)
     }
 
+    @Test
+    fun onButtonClick_turbulenceNoiseFlagEnabled_createsRipplesFinishedListener() {
+        fakeFeatureFlag.set(Flags.UMO_SURFACE_RIPPLE, true)
+        fakeFeatureFlag.set(Flags.UMO_TURBULENCE_NOISE, true)
+
+        player.attachPlayer(viewHolder)
+
+        assertThat(player.mRipplesFinishedListener).isNotNull()
+    }
+
+    @Test
+    fun onButtonClick_turbulenceNoiseFlagDisabled_doesNotCreateRipplesFinishedListener() {
+        fakeFeatureFlag.set(Flags.UMO_SURFACE_RIPPLE, true)
+        fakeFeatureFlag.set(Flags.UMO_TURBULENCE_NOISE, false)
+
+        player.attachPlayer(viewHolder)
+
+        assertThat(player.mRipplesFinishedListener).isNull()
+    }
+
     private fun getScrubbingChangeListener(): SeekBarViewModel.ScrubbingChangeListener =
         withArgCaptor {
             verify(seekBarViewModel).setScrubbingChangeListener(capture())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index 9727b6c5..e5e5d94 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.mock;
@@ -33,12 +35,14 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.HeadsUpStatusBarView;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
@@ -64,7 +68,9 @@
             mock(NotificationPanelViewController.class);
     private final DarkIconDispatcher mDarkIconDispatcher = mock(DarkIconDispatcher.class);
     private HeadsUpAppearanceController mHeadsUpAppearanceController;
-    private ExpandableNotificationRow mFirst;
+    private NotificationTestHelper mTestHelper;
+    private ExpandableNotificationRow mRow;
+    private NotificationEntry mEntry;
     private HeadsUpStatusBarView mHeadsUpStatusBarView;
     private HeadsUpManagerPhone mHeadsUpManager;
     private View mOperatorNameView;
@@ -79,11 +85,12 @@
     @Before
     public void setUp() throws Exception {
         allowTestableLooperAsMainThread();
-        NotificationTestHelper testHelper = new NotificationTestHelper(
+        mTestHelper = new NotificationTestHelper(
                 mContext,
                 mDependency,
                 TestableLooper.get(this));
-        mFirst = testHelper.createRow();
+        mRow = mTestHelper.createRow();
+        mEntry = mRow.getEntry();
         mHeadsUpStatusBarView = new HeadsUpStatusBarView(mContext, mock(View.class),
                 mock(TextView.class));
         mHeadsUpManager = mock(HeadsUpManagerPhone.class);
@@ -95,6 +102,7 @@
         mCommandQueue = mock(CommandQueue.class);
         mNotificationRoundnessManager = mock(NotificationRoundnessManager.class);
         mFeatureFlag = mock(FeatureFlags.class);
+        when(mFeatureFlag.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES)).thenReturn(true);
         mHeadsUpAppearanceController = new HeadsUpAppearanceController(
                 mock(NotificationIconAreaController.class),
                 mHeadsUpManager,
@@ -116,60 +124,60 @@
 
     @Test
     public void testShowinEntryUpdated() {
-        mFirst.setPinned(true);
+        mRow.setPinned(true);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
-        when(mHeadsUpManager.getTopEntry()).thenReturn(mFirst.getEntry());
-        mHeadsUpAppearanceController.onHeadsUpPinned(mFirst.getEntry());
-        Assert.assertEquals(mFirst.getEntry(), mHeadsUpStatusBarView.getShowingEntry());
+        when(mHeadsUpManager.getTopEntry()).thenReturn(mEntry);
+        mHeadsUpAppearanceController.onHeadsUpPinned(mEntry);
+        assertEquals(mRow.getEntry(), mHeadsUpStatusBarView.getShowingEntry());
 
-        mFirst.setPinned(false);
+        mRow.setPinned(false);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
-        mHeadsUpAppearanceController.onHeadsUpUnPinned(mFirst.getEntry());
-        Assert.assertEquals(null, mHeadsUpStatusBarView.getShowingEntry());
+        mHeadsUpAppearanceController.onHeadsUpUnPinned(mEntry);
+        assertEquals(null, mHeadsUpStatusBarView.getShowingEntry());
     }
 
     @Test
     public void testShownUpdated() {
-        mFirst.setPinned(true);
+        mRow.setPinned(true);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
-        when(mHeadsUpManager.getTopEntry()).thenReturn(mFirst.getEntry());
-        mHeadsUpAppearanceController.onHeadsUpPinned(mFirst.getEntry());
-        Assert.assertTrue(mHeadsUpAppearanceController.isShown());
+        when(mHeadsUpManager.getTopEntry()).thenReturn(mEntry);
+        mHeadsUpAppearanceController.onHeadsUpPinned(mEntry);
+        assertTrue(mHeadsUpAppearanceController.isShown());
 
-        mFirst.setPinned(false);
+        mRow.setPinned(false);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
-        mHeadsUpAppearanceController.onHeadsUpUnPinned(mFirst.getEntry());
+        mHeadsUpAppearanceController.onHeadsUpUnPinned(mEntry);
         Assert.assertFalse(mHeadsUpAppearanceController.isShown());
     }
 
     @Test
     public void testHeaderUpdated() {
-        mFirst.setPinned(true);
+        mRow.setPinned(true);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
-        when(mHeadsUpManager.getTopEntry()).thenReturn(mFirst.getEntry());
-        mHeadsUpAppearanceController.onHeadsUpPinned(mFirst.getEntry());
-        Assert.assertEquals(mFirst.getHeaderVisibleAmount(), 0.0f, 0.0f);
+        when(mHeadsUpManager.getTopEntry()).thenReturn(mEntry);
+        mHeadsUpAppearanceController.onHeadsUpPinned(mEntry);
+        assertEquals(mRow.getHeaderVisibleAmount(), 0.0f, 0.0f);
 
-        mFirst.setPinned(false);
+        mRow.setPinned(false);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
-        mHeadsUpAppearanceController.onHeadsUpUnPinned(mFirst.getEntry());
-        Assert.assertEquals(mFirst.getHeaderVisibleAmount(), 1.0f, 0.0f);
+        mHeadsUpAppearanceController.onHeadsUpUnPinned(mEntry);
+        assertEquals(mRow.getHeaderVisibleAmount(), 1.0f, 0.0f);
     }
 
     @Test
     public void testOperatorNameViewUpdated() {
         mHeadsUpAppearanceController.setAnimationsEnabled(false);
 
-        mFirst.setPinned(true);
+        mRow.setPinned(true);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
-        when(mHeadsUpManager.getTopEntry()).thenReturn(mFirst.getEntry());
-        mHeadsUpAppearanceController.onHeadsUpPinned(mFirst.getEntry());
-        Assert.assertEquals(View.INVISIBLE, mOperatorNameView.getVisibility());
+        when(mHeadsUpManager.getTopEntry()).thenReturn(mEntry);
+        mHeadsUpAppearanceController.onHeadsUpPinned(mEntry);
+        assertEquals(View.INVISIBLE, mOperatorNameView.getVisibility());
 
-        mFirst.setPinned(false);
+        mRow.setPinned(false);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
-        mHeadsUpAppearanceController.onHeadsUpUnPinned(mFirst.getEntry());
-        Assert.assertEquals(View.VISIBLE, mOperatorNameView.getVisibility());
+        mHeadsUpAppearanceController.onHeadsUpUnPinned(mEntry);
+        assertEquals(View.VISIBLE, mOperatorNameView.getVisibility());
     }
 
     @Test
@@ -196,8 +204,8 @@
                 new Clock(mContext, null),
                 Optional.empty());
 
-        Assert.assertEquals(expandedHeight, newController.mExpandedHeight, 0.0f);
-        Assert.assertEquals(appearFraction, newController.mAppearFraction, 0.0f);
+        assertEquals(expandedHeight, newController.mExpandedHeight, 0.0f);
+        assertEquals(appearFraction, newController.mAppearFraction, 0.0f);
     }
 
     @Test
@@ -215,4 +223,68 @@
         verify(mPanelView).setHeadsUpAppearanceController(isNull());
         verify(mStackScrollerController).removeOnExpandedHeightChangedListener(any());
     }
+
+    @Test
+    public void testPulsingRoundness_onUpdateHeadsUpAndPulsingRoundness() {
+        // Pulsing: Enable flag and dozing
+        when(mNotificationRoundnessManager.shouldRoundNotificationPulsing()).thenReturn(true);
+        when(mTestHelper.getStatusBarStateController().isDozing()).thenReturn(true);
+
+        // Pulsing: Enabled
+        mRow.setHeadsUp(true);
+        mHeadsUpAppearanceController.updateHeadsUpAndPulsingRoundness(mEntry);
+
+        String debugString = mRow.getRoundableState().debugString();
+        assertEquals(
+                "If Pulsing is enabled, roundness should be set to 1. Value: " + debugString,
+                /* expected = */ 1,
+                /* actual = */ mRow.getTopRoundness(),
+                /* delta = */ 0.001
+        );
+        assertTrue(debugString.contains("Pulsing"));
+
+        // Pulsing: Disabled
+        mRow.setHeadsUp(false);
+        mHeadsUpAppearanceController.updateHeadsUpAndPulsingRoundness(mEntry);
+
+        assertEquals(
+                "If Pulsing is disabled, roundness should be set to 0. Value: "
+                        + mRow.getRoundableState().debugString(),
+                /* expected = */ 0,
+                /* actual = */ mRow.getTopRoundness(),
+                /* delta = */ 0.001
+        );
+    }
+
+    @Test
+    public void testPulsingRoundness_onHeadsUpStateChanged() {
+        // Pulsing: Enable flag and dozing
+        when(mNotificationRoundnessManager.shouldRoundNotificationPulsing()).thenReturn(true);
+        when(mTestHelper.getStatusBarStateController().isDozing()).thenReturn(true);
+
+        // Pulsing: Enabled
+        mEntry.setHeadsUp(true);
+        mHeadsUpAppearanceController.onHeadsUpStateChanged(mEntry, true);
+
+        String debugString = mRow.getRoundableState().debugString();
+        assertEquals(
+                "If Pulsing is enabled, roundness should be set to 1. Value: " + debugString,
+                /* expected = */ 1,
+                /* actual = */ mRow.getTopRoundness(),
+                /* delta = */ 0.001
+        );
+        assertTrue(debugString.contains("Pulsing"));
+
+        // Pulsing: Disabled
+        mEntry.setHeadsUp(false);
+        mHeadsUpAppearanceController.onHeadsUpStateChanged(mEntry, false);
+
+        assertEquals(
+                "If Pulsing is disabled, roundness should be set to 0. Value: "
+                        + mRow.getRoundableState().debugString(),
+                /* expected = */ 0,
+                /* actual = */ mRow.getTopRoundness(),
+                /* delta = */ 0.001
+        );
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java
index 30dc0d2..0fdcb95 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java
@@ -19,15 +19,13 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
-import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.hamcrest.Matchers.equalTo;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -36,19 +34,13 @@
 
 import android.app.WallpaperManager;
 import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.ColorSpace;
 import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManagerGlobal;
-import android.os.Handler;
 import android.os.UserHandle;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
-import android.view.Display;
-import android.view.DisplayInfo;
 import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.view.WindowManager;
@@ -57,28 +49,21 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
-import com.android.systemui.wallpapers.gl.ImageWallpaperRenderer;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.util.concurrent.CountDownLatch;
-
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class ImageWallpaperTest extends SysuiTestCase {
     private static final int LOW_BMP_WIDTH = 128;
     private static final int LOW_BMP_HEIGHT = 128;
-    private static final int INVALID_BMP_WIDTH = 1;
-    private static final int INVALID_BMP_HEIGHT = 1;
     private static final int DISPLAY_WIDTH = 1920;
     private static final int DISPLAY_HEIGHT = 1080;
 
@@ -99,19 +84,9 @@
 
     @Mock
     private Bitmap mWallpaperBitmap;
-    private int mBitmapWidth = 1;
-    private int mBitmapHeight = 1;
-
-    @Mock
-    private Handler mHandler;
-    @Mock
-    private FeatureFlags mFeatureFlags;
-
     FakeSystemClock mFakeSystemClock = new FakeSystemClock();
     FakeExecutor mFakeBackgroundExecutor = new FakeExecutor(mFakeSystemClock);
 
-    private CountDownLatch mEventCountdown;
-
     @Before
     public void setUp() throws Exception {
         allowTestableLooperAsMainThread();
@@ -131,12 +106,8 @@
         // set up bitmap
         when(mWallpaperBitmap.getColorSpace()).thenReturn(ColorSpace.get(ColorSpace.Named.SRGB));
         when(mWallpaperBitmap.getConfig()).thenReturn(Bitmap.Config.ARGB_8888);
-        when(mWallpaperBitmap.getWidth()).thenReturn(mBitmapWidth);
-        when(mWallpaperBitmap.getHeight()).thenReturn(mBitmapHeight);
 
         // set up wallpaper manager
-        when(mWallpaperManager.peekBitmapDimensions())
-                .thenReturn(new Rect(0, 0, mBitmapWidth, mBitmapHeight));
         when(mWallpaperManager.getBitmapAsUser(eq(UserHandle.USER_CURRENT), anyBoolean()))
                 .thenReturn(mWallpaperBitmap);
         when(mMockContext.getSystemService(WallpaperManager.class)).thenReturn(mWallpaperManager);
@@ -144,104 +115,62 @@
         // set up surface
         when(mSurfaceHolder.getSurface()).thenReturn(mSurface);
         doNothing().when(mSurface).hwuiDestroy();
-
-        // TODO remove code below. Outdated, used in only in old GL tests (that are ignored)
-        Resources resources = mock(Resources.class);
-        when(resources.getConfiguration()).thenReturn(mock(Configuration.class));
-        when(mMockContext.getResources()).thenReturn(resources);
-        DisplayInfo displayInfo = new DisplayInfo();
-        displayInfo.logicalWidth = DISPLAY_WIDTH;
-        displayInfo.logicalHeight = DISPLAY_HEIGHT;
-        when(mMockContext.getDisplay()).thenReturn(
-                new Display(mock(DisplayManagerGlobal.class), 0, displayInfo, (Resources) null));
-    }
-
-    private void setBitmapDimensions(int bitmapWidth, int bitmapHeight) {
-        mBitmapWidth = bitmapWidth;
-        mBitmapHeight = bitmapHeight;
-    }
-
-    private ImageWallpaper createImageWallpaper() {
-        return new ImageWallpaper(mFeatureFlags, mFakeBackgroundExecutor) {
-            @Override
-            public Engine onCreateEngine() {
-                return new GLEngine(mHandler) {
-                    @Override
-                    public Context getDisplayContext() {
-                        return mMockContext;
-                    }
-
-                    @Override
-                    public SurfaceHolder getSurfaceHolder() {
-                        return mSurfaceHolder;
-                    }
-
-                    @Override
-                    public void setFixedSizeAllowed(boolean allowed) {
-                        super.setFixedSizeAllowed(allowed);
-                        assertWithMessage("mFixedSizeAllowed should be true").that(
-                                allowed).isTrue();
-                        mEventCountdown.countDown();
-                    }
-                };
-            }
-        };
     }
 
     @Test
-    @Ignore
     public void testBitmapWallpaper_normal() {
         // Will use a image wallpaper with dimensions DISPLAY_WIDTH x DISPLAY_WIDTH.
         // Then we expect the surface size will be also DISPLAY_WIDTH x DISPLAY_WIDTH.
-        verifySurfaceSize(DISPLAY_WIDTH /* bmpWidth */,
-                DISPLAY_WIDTH /* bmpHeight */,
-                DISPLAY_WIDTH /* surfaceWidth */,
-                DISPLAY_WIDTH /* surfaceHeight */);
+        int bitmapSide = DISPLAY_WIDTH;
+        testSurfaceHelper(
+                bitmapSide /* bitmapWidth */,
+                bitmapSide /* bitmapHeight */,
+                bitmapSide /* expectedSurfaceWidth */,
+                bitmapSide /* expectedSurfaceHeight */);
     }
 
     @Test
-    @Ignore
     public void testBitmapWallpaper_low_resolution() {
         // Will use a image wallpaper with dimensions BMP_WIDTH x BMP_HEIGHT.
         // Then we expect the surface size will be also BMP_WIDTH x BMP_HEIGHT.
-        verifySurfaceSize(LOW_BMP_WIDTH /* bmpWidth */,
-                LOW_BMP_HEIGHT /* bmpHeight */,
-                LOW_BMP_WIDTH /* surfaceWidth */,
-                LOW_BMP_HEIGHT /* surfaceHeight */);
+        testSurfaceHelper(LOW_BMP_WIDTH /* bitmapWidth */,
+                LOW_BMP_HEIGHT /* bitmapHeight */,
+                LOW_BMP_WIDTH /* expectedSurfaceWidth */,
+                LOW_BMP_HEIGHT /* expectedSurfaceHeight */);
     }
 
     @Test
-    @Ignore
     public void testBitmapWallpaper_too_small() {
-        // Will use a image wallpaper with dimensions INVALID_BMP_WIDTH x INVALID_BMP_HEIGHT.
-        // Then we expect the surface size will be also MIN_SURFACE_WIDTH x MIN_SURFACE_HEIGHT.
-        verifySurfaceSize(INVALID_BMP_WIDTH /* bmpWidth */,
-                INVALID_BMP_HEIGHT /* bmpHeight */,
-                ImageWallpaper.GLEngine.MIN_SURFACE_WIDTH /* surfaceWidth */,
-                ImageWallpaper.GLEngine.MIN_SURFACE_HEIGHT /* surfaceHeight */);
+
+        // test that the surface is always at least MIN_SURFACE_WIDTH x MIN_SURFACE_HEIGHT
+        testMinSurfaceHelper(8, 8);
+        testMinSurfaceHelper(100, 2000);
+        testMinSurfaceHelper(200, 1);
     }
 
-    private void verifySurfaceSize(int bmpWidth, int bmpHeight,
-            int surfaceWidth, int surfaceHeight) {
-        ImageWallpaper.GLEngine wallpaperEngine =
-                (ImageWallpaper.GLEngine) createImageWallpaper().onCreateEngine();
+    @Test
+    public void testLoadDrawAndUnloadBitmap() {
+        setBitmapDimensions(LOW_BMP_WIDTH, LOW_BMP_HEIGHT);
 
-        ImageWallpaper.GLEngine engineSpy = spy(wallpaperEngine);
+        ImageWallpaper.CanvasEngine spyEngine = getSpyEngine();
+        spyEngine.onCreate(mSurfaceHolder);
+        spyEngine.onSurfaceRedrawNeeded(mSurfaceHolder);
+        assertThat(mFakeBackgroundExecutor.numPending()).isAtLeast(1);
 
-        setBitmapDimensions(bmpWidth, bmpHeight);
+        int n = 0;
+        while (mFakeBackgroundExecutor.numPending() >= 1) {
+            n++;
+            assertThat(n).isAtMost(10);
+            mFakeBackgroundExecutor.runNextReady();
+            mFakeSystemClock.advanceTime(1000);
+        }
 
-        ImageWallpaperRenderer renderer = new ImageWallpaperRenderer(mMockContext);
-        doReturn(renderer).when(engineSpy).getRendererInstance();
-        engineSpy.onCreate(engineSpy.getSurfaceHolder());
-
-        verify(mSurfaceHolder, times(1)).setFixedSize(surfaceWidth, surfaceHeight);
-        assertWithMessage("setFixedSizeAllowed should have been called.").that(
-                mEventCountdown.getCount()).isEqualTo(0);
+        verify(spyEngine, times(1)).drawFrameOnCanvas(mWallpaperBitmap);
+        assertThat(spyEngine.isBitmapLoaded()).isFalse();
     }
 
-
-    private ImageWallpaper createImageWallpaperCanvas() {
-        return new ImageWallpaper(mFeatureFlags, mFakeBackgroundExecutor) {
+    private ImageWallpaper createImageWallpaper() {
+        return new ImageWallpaper(mFakeBackgroundExecutor) {
             @Override
             public Engine onCreateEngine() {
                 return new CanvasEngine() {
@@ -267,7 +196,7 @@
     }
 
     private ImageWallpaper.CanvasEngine getSpyEngine() {
-        ImageWallpaper imageWallpaper = createImageWallpaperCanvas();
+        ImageWallpaper imageWallpaper = createImageWallpaper();
         ImageWallpaper.CanvasEngine engine =
                 (ImageWallpaper.CanvasEngine) imageWallpaper.onCreateEngine();
         ImageWallpaper.CanvasEngine spyEngine = spy(engine);
@@ -280,48 +209,32 @@
         return spyEngine;
     }
 
-    @Test
-    public void testMinSurface() {
-
-        // test that the surface is always at least MIN_SURFACE_WIDTH x MIN_SURFACE_HEIGHT
-        testMinSurfaceHelper(8, 8);
-        testMinSurfaceHelper(100, 2000);
-        testMinSurfaceHelper(200, 1);
+    private void setBitmapDimensions(int bitmapWidth, int bitmapHeight) {
+        when(mWallpaperManager.peekBitmapDimensions())
+                .thenReturn(new Rect(0, 0, bitmapWidth, bitmapHeight));
+        when(mWallpaperBitmap.getWidth()).thenReturn(bitmapWidth);
+        when(mWallpaperBitmap.getHeight()).thenReturn(bitmapHeight);
     }
 
     private void testMinSurfaceHelper(int bitmapWidth, int bitmapHeight) {
+        testSurfaceHelper(bitmapWidth, bitmapHeight,
+                Math.max(ImageWallpaper.CanvasEngine.MIN_SURFACE_WIDTH, bitmapWidth),
+                Math.max(ImageWallpaper.CanvasEngine.MIN_SURFACE_HEIGHT, bitmapHeight));
+    }
+
+    private void testSurfaceHelper(int bitmapWidth, int bitmapHeight,
+            int expectedSurfaceWidth, int expectedSurfaceHeight) {
 
         clearInvocations(mSurfaceHolder);
         setBitmapDimensions(bitmapWidth, bitmapHeight);
 
-        ImageWallpaper imageWallpaper = createImageWallpaperCanvas();
+        ImageWallpaper imageWallpaper = createImageWallpaper();
         ImageWallpaper.CanvasEngine engine =
                 (ImageWallpaper.CanvasEngine) imageWallpaper.onCreateEngine();
         engine.onCreate(mSurfaceHolder);
 
         verify(mSurfaceHolder, times(1)).setFixedSize(
-                intThat(greaterThanOrEqualTo(ImageWallpaper.CanvasEngine.MIN_SURFACE_WIDTH)),
-                intThat(greaterThanOrEqualTo(ImageWallpaper.CanvasEngine.MIN_SURFACE_HEIGHT)));
-    }
-
-    @Test
-    public void testLoadDrawAndUnloadBitmap() {
-        setBitmapDimensions(LOW_BMP_WIDTH, LOW_BMP_HEIGHT);
-
-        ImageWallpaper.CanvasEngine spyEngine = getSpyEngine();
-        spyEngine.onCreate(mSurfaceHolder);
-        spyEngine.onSurfaceRedrawNeeded(mSurfaceHolder);
-        assertThat(mFakeBackgroundExecutor.numPending()).isAtLeast(1);
-
-        int n = 0;
-        while (mFakeBackgroundExecutor.numPending() >= 1) {
-            n++;
-            assertThat(n).isAtMost(10);
-            mFakeBackgroundExecutor.runNextReady();
-            mFakeSystemClock.advanceTime(1000);
-        }
-
-        verify(spyEngine, times(1)).drawFrameOnCanvas(mWallpaperBitmap);
-        assertThat(spyEngine.isBitmapLoaded()).isFalse();
+                intThat(equalTo(expectedSurfaceWidth)),
+                intThat(equalTo(expectedSurfaceHeight)));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/canvas/WallpaperLocalColorExtractorTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java
similarity index 99%
rename from packages/SystemUI/tests/src/com/android/systemui/wallpapers/canvas/WallpaperLocalColorExtractorTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java
index 7e8ffeb..fc5f782 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/canvas/WallpaperLocalColorExtractorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.wallpapers.canvas;
+package com.android.systemui.wallpapers;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/gl/EglHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/gl/EglHelperTest.java
deleted file mode 100644
index a42bade..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/gl/EglHelperTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2019 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.systemui.wallpapers.gl;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atMost;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.graphics.PixelFormat;
-import android.testing.AndroidTestingRunner;
-import android.view.Surface;
-import android.view.SurfaceControl;
-import android.view.SurfaceHolder;
-import android.view.SurfaceSession;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@Ignore
-public class EglHelperTest extends SysuiTestCase {
-
-    @Spy
-    private EglHelper mEglHelper;
-
-    @Mock
-    private SurfaceHolder mSurfaceHolder;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        prepareSurface();
-    }
-
-    @After
-    public void tearDown() {
-        mSurfaceHolder.getSurface().destroy();
-        mSurfaceHolder = null;
-    }
-
-    private void prepareSurface() {
-        final SurfaceSession session = new SurfaceSession();
-        final SurfaceControl control = new SurfaceControl.Builder(session)
-                .setName("Test")
-                .setBufferSize(100, 100)
-                .setFormat(PixelFormat.RGB_888)
-                .build();
-        final Surface surface = new Surface();
-        surface.copyFrom(control);
-        when(mSurfaceHolder.getSurface()).thenReturn(surface);
-        assertThat(mSurfaceHolder.getSurface()).isNotNull();
-        assertThat(mSurfaceHolder.getSurface().isValid()).isTrue();
-    }
-
-    @Test
-    public void testInit_normal() {
-        mEglHelper.init(mSurfaceHolder, false /* wideColorGamut */);
-        assertThat(mEglHelper.hasEglDisplay()).isTrue();
-        assertThat(mEglHelper.hasEglContext()).isTrue();
-        assertThat(mEglHelper.hasEglSurface()).isTrue();
-        verify(mEglHelper).askCreatingEglWindowSurface(
-                any(SurfaceHolder.class), eq(null), anyInt());
-    }
-
-    @Test
-    public void testInit_wide_gamut() {
-        // In EglHelper, EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT = 0x3490;
-        doReturn(0x3490).when(mEglHelper).getWcgCapability();
-        // In EglHelper, KHR_GL_COLOR_SPACE = "EGL_KHR_gl_colorspace";
-        doReturn(true).when(mEglHelper).checkExtensionCapability("EGL_KHR_gl_colorspace");
-        ArgumentCaptor<int[]> ac = ArgumentCaptor.forClass(int[].class);
-        // {EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT, EGL_NONE}
-        final int[] expectedArgument = new int[] {0x309D, 0x3490, 0x3038};
-
-        mEglHelper.init(mSurfaceHolder, true /* wideColorGamut */);
-        verify(mEglHelper)
-                .askCreatingEglWindowSurface(any(SurfaceHolder.class), ac.capture(), anyInt());
-        assertThat(ac.getValue()).isNotNull();
-        assertThat(ac.getValue()).isEqualTo(expectedArgument);
-    }
-
-    @Test
-    @Ignore
-    public void testFinish_shouldNotCrash() {
-        mEglHelper.terminateEglDisplay();
-        assertThat(mEglHelper.hasEglDisplay()).isFalse();
-        assertThat(mEglHelper.hasEglSurface()).isFalse();
-        assertThat(mEglHelper.hasEglContext()).isFalse();
-
-        mEglHelper.finish();
-        verify(mEglHelper, never()).destroyEglContext();
-        verify(mEglHelper, never()).destroyEglSurface();
-        verify(mEglHelper, atMost(1)).terminateEglDisplay();
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/gl/ImageWallpaperRendererTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/gl/ImageWallpaperRendererTest.java
deleted file mode 100644
index 89b2222..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/gl/ImageWallpaperRendererTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2020 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.systemui.wallpapers.gl;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-
-import android.app.WallpaperManager;
-import android.app.WallpaperManager.ColorManagementProxy;
-import android.graphics.Bitmap;
-import android.graphics.ColorSpace;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper(setAsMainLooper = true)
-@Ignore
-public class ImageWallpaperRendererTest extends SysuiTestCase {
-
-    private WallpaperManager mWpmSpy;
-
-    @Before
-    public void setUp() throws Exception {
-        final WallpaperManager wpm = mContext.getSystemService(WallpaperManager.class);
-        mWpmSpy = spy(wpm);
-        mContext.addMockSystemService(WallpaperManager.class, mWpmSpy);
-    }
-
-    @Test
-    public void testWcgContent() throws IOException {
-        final Bitmap srgbBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
-        final Bitmap p3Bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888,
-                false /* hasAlpha */, ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
-
-        final ColorManagementProxy proxy = new ColorManagementProxy(mContext);
-        final ColorManagementProxy cmProxySpy = spy(proxy);
-        final Set<ColorSpace> supportedWideGamuts = new HashSet<>();
-        supportedWideGamuts.add(ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
-
-        try {
-            doReturn(true).when(mWpmSpy).shouldEnableWideColorGamut();
-            doReturn(cmProxySpy).when(mWpmSpy).getColorManagementProxy();
-            doReturn(supportedWideGamuts).when(cmProxySpy).getSupportedColorSpaces();
-
-            mWpmSpy.setBitmap(p3Bitmap);
-            ImageWallpaperRenderer rendererP3 = new ImageWallpaperRenderer(mContext);
-            rendererP3.reportSurfaceSize();
-            assertThat(rendererP3.isWcgContent()).isTrue();
-
-            mWpmSpy.setBitmap(srgbBitmap);
-            ImageWallpaperRenderer renderer = new ImageWallpaperRenderer(mContext);
-            assertThat(renderer.isWcgContent()).isFalse();
-        } finally {
-            srgbBitmap.recycle();
-            p3Bitmap.recycle();
-        }
-    }
-
-}