diff options
189 files changed, 1923 insertions, 1109 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index f9cc1259a375..b9537b357517 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -50,6 +50,7 @@ aconfig_declarations_group { "android.hardware.devicestate.feature.flags-aconfig-java", "android.hardware.flags-aconfig-java", "android.hardware.radio.flags-aconfig-java", + "android.hardware.serial.flags-aconfig-java", "android.hardware.usb.flags-aconfig-java", "android.location.flags-aconfig-java", "android.media.codec-aconfig-java", @@ -1962,3 +1963,18 @@ java_aconfig_library { aconfig_declarations: "android.service.selinux.flags-aconfig", defaults: ["framework-minus-apex-aconfig-java-defaults"], } + +// Serial +aconfig_declarations { + name: "android.hardware.serial.flags-aconfig", + exportable: true, + package: "android.hardware.serial.flags", + container: "system", + srcs: ["core/java/android/hardware/serial/flags/*.aconfig"], +} + +java_aconfig_library { + name: "android.hardware.serial.flags-aconfig-java", + aconfig_declarations: "android.hardware.serial.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} diff --git a/cmds/uinput/src/com/android/commands/uinput/EvemuParser.java b/cmds/uinput/src/com/android/commands/uinput/EvemuParser.java index da991624e685..d3e62d5351f0 100644 --- a/cmds/uinput/src/com/android/commands/uinput/EvemuParser.java +++ b/cmds/uinput/src/com/android/commands/uinput/EvemuParser.java @@ -48,12 +48,17 @@ public class EvemuParser implements EventParser { private static class CommentAwareReader { private final LineNumberReader mReader; - private String mPreviousLine; - private String mNextLine; + /** The previous line of the file, or {@code null} if we're at the start of the file. */ + private @Nullable String mPreviousLine; + /** + * The next line of the file to be returned from {@link #peekLine()}, or {@code null} if we + * haven't peeked since the last {@link #advance()} or are at the end of the file. + */ + private @Nullable String mNextLine; + private boolean mAtEndOfFile = false; - CommentAwareReader(LineNumberReader in) throws IOException { + CommentAwareReader(LineNumberReader in) { mReader = in; - mNextLine = findNextLine(); } private @Nullable String findNextLine() throws IOException { @@ -61,7 +66,7 @@ public class EvemuParser implements EventParser { while (line != null && line.length() == 0) { String unstrippedLine = mReader.readLine(); if (unstrippedLine == null) { - // End of file. + mAtEndOfFile = true; return null; } line = stripComments(unstrippedLine); @@ -85,22 +90,28 @@ public class EvemuParser implements EventParser { * {@code null} if the end of the file is reached. However, it does not advance to the * next line of the file. */ - public @Nullable String peekLine() { + public @Nullable String peekLine() throws IOException { + if (mNextLine == null && !mAtEndOfFile) { + mNextLine = findNextLine(); + } return mNextLine; } /** Moves to the next line of the file. */ - public void advance() throws IOException { + public void advance() { mPreviousLine = mNextLine; - mNextLine = findNextLine(); + mNextLine = null; } public boolean isAtEndOfFile() { - return mNextLine == null; + return mAtEndOfFile; } - /** Returns the previous line, for error messages. */ - public String getPreviousLine() { + /** + * Returns the previous line, for error messages. Will be {@code null} if we're at the start + * of the file. + */ + public @Nullable String getPreviousLine() { return mPreviousLine; } diff --git a/core/java/android/app/ApplicationStartInfo.java b/core/java/android/app/ApplicationStartInfo.java index 2559bd036039..e2af7c03b5fa 100644 --- a/core/java/android/app/ApplicationStartInfo.java +++ b/core/java/android/app/ApplicationStartInfo.java @@ -1082,6 +1082,15 @@ public final class ApplicationStartInfo implements Parcelable { final ApplicationStartInfo o = (ApplicationStartInfo) other; + boolean intentEquals = true; + if (android.content.flags.Flags.intentSaveToXmlPackage()) { + if (mStartIntent == null) { + intentEquals = o.mStartIntent == null; + } else { + intentEquals = mStartIntent.filterEquals(o.mStartIntent); + } + } + return mPid == o.mPid && mRealUid == o.mRealUid && mPackageUid == o.mPackageUid @@ -1095,14 +1104,16 @@ public final class ApplicationStartInfo implements Parcelable { && timestampsEquals(o) && mWasForceStopped == o.mWasForceStopped && mMonotonicCreationTimeMs == o.mMonotonicCreationTimeMs - && mStartComponent == o.mStartComponent; + && mStartComponent == o.mStartComponent + && intentEquals; } @Override public int hashCode() { return Objects.hash(mPid, mRealUid, mPackageUid, mDefiningUid, mReason, mStartupState, mStartType, mLaunchMode, mPackageName, mProcessName, mStartupTimestampsNs, - mMonotonicCreationTimeMs, mStartComponent); + mMonotonicCreationTimeMs, mStartComponent, + android.content.flags.Flags.intentSaveToXmlPackage() ? mStartIntent : null); } private boolean timestampsEquals(@NonNull ApplicationStartInfo other) { diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index 6e9dcf5a83a1..335448bf131e 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -79,6 +79,7 @@ import android.util.Log; import android.util.Pair; import android.util.Size; import android.view.Display; +import android.window.DesktopModeFlags; import com.android.internal.camera.flags.Flags; import com.android.internal.util.ArrayUtils; @@ -1685,7 +1686,7 @@ public final class CameraManager { */ public static int getRotationOverride(@Nullable Context context, @Nullable PackageManager packageManager, @Nullable String packageName) { - if (com.android.window.flags.Flags.enableCameraCompatForDesktopWindowing()) { + if (DesktopModeFlags.ENABLE_CAMERA_COMPAT_SIMULATE_REQUESTED_ORIENTATION.isTrue()) { return getRotationOverrideInternal(context, packageManager, packageName); } else { return shouldOverrideToPortrait(packageManager, packageName) diff --git a/core/java/android/hardware/serial/flags/flags.aconfig b/core/java/android/hardware/serial/flags/flags.aconfig index d8244ba55fcc..bdb8b40af2bf 100644 --- a/core/java/android/hardware/serial/flags/flags.aconfig +++ b/core/java/android/hardware/serial/flags/flags.aconfig @@ -1,4 +1,4 @@ -package: "android.hardware.serial" +package: "android.hardware.serial.flags" container: "system" flag { diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java index c21959b16fbb..c3c28b20d649 100644 --- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java +++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java @@ -34,8 +34,6 @@ import android.util.Printer; import android.util.SparseArray; import android.util.proto.ProtoOutputStream; -import com.android.internal.ravenwood.RavenwoodEnvironment; - import dalvik.annotation.optimization.NeverCompile; import java.io.FileDescriptor; @@ -1121,7 +1119,6 @@ public final class MessageQueue { msg.markInUse(); msg.arg1 = token; - incAndTraceMessageCount(msg, when); if (!enqueueMessageUnchecked(msg, when)) { Log.wtf(TAG_C, "Unexpected error while adding sync barrier!"); @@ -1137,7 +1134,6 @@ public final class MessageQueue { msg.markInUse(); msg.when = when; msg.arg1 = token; - incAndTraceMessageCount(msg, when); if (Flags.messageQueueTailTracking() && mLast != null && mLast.when <= when) { /* Message goes to tail of list */ diff --git a/core/java/android/view/OrientationEventListener.java b/core/java/android/view/OrientationEventListener.java index 2feb44ffc3ae..892b80bd0213 100644 --- a/core/java/android/view/OrientationEventListener.java +++ b/core/java/android/view/OrientationEventListener.java @@ -26,8 +26,7 @@ import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.util.Log; - -import com.android.window.flags.Flags; +import android.window.DesktopModeFlags; /** * Helper class for receiving notifications from the SensorManager when @@ -77,9 +76,10 @@ public abstract class OrientationEventListener { mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); if (mSensor != null) { // Create listener only if sensors do exist. - mSensorEventListener = Flags.enableCameraCompatForDesktopWindowing() - ? new CompatSensorEventListenerImpl(new SensorEventListenerImpl()) - : new SensorEventListenerImpl(); + mSensorEventListener = + DesktopModeFlags.ENABLE_CAMERA_COMPAT_SIMULATE_REQUESTED_ORIENTATION.isTrue() + ? new CompatSensorEventListenerImpl(new SensorEventListenerImpl()) + : new SensorEventListenerImpl(); } } diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index 97cf8fc748e8..8944c3fa0b19 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -120,7 +120,7 @@ public class WindowManagerImpl implements WindowManager { this(context, null /* parentWindow */, null /* clientToken */); } - private WindowManagerImpl(Context context, Window parentWindow, + public WindowManagerImpl(Context context, Window parentWindow, @Nullable IBinder windowContextToken) { mContext = context; mParentWindow = parentWindow; diff --git a/core/java/android/window/DesktopModeFlags.java b/core/java/android/window/DesktopModeFlags.java index 4bd0d97a54b0..d2893a46d3f3 100644 --- a/core/java/android/window/DesktopModeFlags.java +++ b/core/java/android/window/DesktopModeFlags.java @@ -48,6 +48,8 @@ public enum DesktopModeFlags { DISABLE_NON_RESIZABLE_APP_SNAP_RESIZE(Flags::disableNonResizableAppSnapResizing, true), ENABLE_ACCESSIBLE_CUSTOM_HEADERS(Flags::enableAccessibleCustomHeaders, true), ENABLE_APP_HEADER_WITH_TASK_DENSITY(Flags::enableAppHeaderWithTaskDensity, true), + ENABLE_CAMERA_COMPAT_SIMULATE_REQUESTED_ORIENTATION( + Flags::enableCameraCompatForDesktopWindowing, true), ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION(Flags::enableCaptionCompatInsetForceConsumption, true), ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION_ALWAYS( diff --git a/core/java/com/android/internal/jank/DisplayResolutionTracker.java b/core/java/com/android/internal/jank/DisplayResolutionTracker.java index 5d66b3c10197..74153157df4d 100644 --- a/core/java/com/android/internal/jank/DisplayResolutionTracker.java +++ b/core/java/com/android/internal/jank/DisplayResolutionTracker.java @@ -142,14 +142,23 @@ public class DisplayResolutionTracker { public interface DisplayInterface { /** Reurns an implementation wrapping {@link DisplayManagerGlobal}. */ static DisplayInterface getDefault(@Nullable Handler handler) { + long displayEventsToBeSubscribed; + if (com.android.server.display.feature.flags.Flags + .displayListenerPerformanceImprovements() + && com.android.server.display.feature.flags.Flags + .delayImplicitRrRegistrationUntilRrAccessed()) { + displayEventsToBeSubscribed = DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED + | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_BASIC_CHANGED; + } else { + displayEventsToBeSubscribed = DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED + | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_BASIC_CHANGED + | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE; + } DisplayManagerGlobal manager = DisplayManagerGlobal.getInstance(); return new DisplayInterface() { @Override public void registerDisplayListener(DisplayManager.DisplayListener listener) { - manager.registerDisplayListener(listener, handler, - DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED - | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_BASIC_CHANGED - | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE, + manager.registerDisplayListener(listener, handler, displayEventsToBeSubscribed, ActivityThread.currentPackageName()); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java index 97184c859d4d..46f6e40ec5e8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java @@ -287,7 +287,13 @@ public class DisplayController { ? mContext : mContext.createDisplayContext(display); final Context context = perDisplayContext.createConfigurationContext(newConfig); - dr.setDisplayLayout(context, new DisplayLayout(context, display)); + final DisplayLayout displayLayout = new DisplayLayout(context, display); + if (mDisplayTopology != null) { + displayLayout.setGlobalBoundsDp( + mDisplayTopology.getAbsoluteBounds().get( + displayId, displayLayout.globalBoundsDp())); + } + dr.setDisplayLayout(context, displayLayout); for (int i = 0; i < mDisplayChangedListeners.size(); ++i) { mDisplayChangedListeners.get(i).onDisplayConfigurationChanged( displayId, newConfig); 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 0edab006cb66..5fbbb0bf1e78 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 @@ -90,6 +90,7 @@ import com.android.wm.shell.desktopmode.DefaultDragToDesktopTransitionHandler; import com.android.wm.shell.desktopmode.DesktopActivityOrientationChangeHandler; import com.android.wm.shell.desktopmode.DesktopDisplayEventHandler; import com.android.wm.shell.desktopmode.DesktopDisplayModeController; +import com.android.wm.shell.desktopmode.DesktopImeHandler; import com.android.wm.shell.desktopmode.DesktopImmersiveController; import com.android.wm.shell.desktopmode.DesktopMinimizationTransitionHandler; import com.android.wm.shell.desktopmode.DesktopMixedTransitionHandler; @@ -1526,6 +1527,18 @@ public abstract class WMShellModule { mainHandler)); } + @WMSingleton + @Provides + static Optional<DesktopImeHandler> provideDesktopImeHandler( + DisplayImeController displayImeController, + Context context, + ShellInit shellInit) { + if (!DesktopModeStatus.canEnterDesktopMode(context)) { + return Optional.empty(); + } + return Optional.of(new DesktopImeHandler(displayImeController, shellInit)); + } + // // App zoom out // diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImeHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImeHandler.kt new file mode 100644 index 000000000000..93ba71a17937 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImeHandler.kt @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024 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.view.SurfaceControl +import com.android.window.flags.Flags +import com.android.wm.shell.common.DisplayImeController +import com.android.wm.shell.common.DisplayImeController.ImePositionProcessor.IME_ANIMATION_DEFAULT +import com.android.wm.shell.sysui.ShellInit + +/** Handles the interactions between IME and desktop tasks */ +class DesktopImeHandler( + private val displayImeController: DisplayImeController, + shellInit: ShellInit, +) : DisplayImeController.ImePositionProcessor { + + init { + shellInit.addInitCallback(::onInit, this) + } + + private fun onInit() { + if (Flags.enableDesktopImeBugfix()) { + displayImeController.addPositionProcessor(this) + } + } + + override fun onImeStartPositioning( + displayId: Int, + hiddenTop: Int, + shownTop: Int, + showing: Boolean, + isFloating: Boolean, + t: SurfaceControl.Transaction?, + ): Int { + return IME_ANIMATION_DEFAULT + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt index b9cb32d8a14f..e0300d688379 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt @@ -167,7 +167,35 @@ class DesktopModeUiEventLogger( @UiEvent(doc = "Exit desktop mode education tooltip on the app header menu is clicked") EXIT_DESKTOP_MODE_EDUCATION_TOOLTIP_CLICKED(2104), @UiEvent(doc = "Exit desktop mode education tooltip is dismissed by the user") - EXIT_DESKTOP_MODE_EDUCATION_TOOLTIP_DISMISSED(2105); + EXIT_DESKTOP_MODE_EDUCATION_TOOLTIP_DISMISSED(2105), + @UiEvent(doc = "A11y service opened app handle menu by selecting handle from fullscreen") + A11Y_APP_HANDLE_MENU_OPENED(2156), + @UiEvent(doc = "A11y service opened app handle menu through Switch Access actions menu ") + A11Y_SYSTEM_ACTION_APP_HANDLE_MENU(2157), + @UiEvent(doc = "A11y service selected desktop mode from app handle menu") + A11Y_APP_HANDLE_MENU_DESKTOP_VIEW(2158), + @UiEvent(doc = "A11y service selected fullscreen mode from app handle menu") + A11Y_APP_HANDLE_MENU_FULLSCREEN(2159), + @UiEvent(doc = "A11y service selected split screen mode from app handle menu") + A11Y_APP_HANDLE_MENU_SPLIT_SCREEN(2160), + @UiEvent(doc = "A11y service selected maximize/restore button from app header") + A11Y_APP_WINDOW_MAXIMIZE_RESTORE_BUTTON(2161), + @UiEvent(doc = "A11y service selected minimize button from app header") + A11Y_APP_WINDOW_MINIMIZE_BUTTON(2162), + @UiEvent(doc = "A11y service selected close button from app header") + A11Y_APP_WINDOW_CLOSE_BUTTON(2163), + @UiEvent(doc = "A11y service selected maximize button from app header maximize menu") + A11Y_MAXIMIZE_MENU_MAXIMIZE(2164), + @UiEvent(doc = "A11y service selected resize left button from app header maximize menu") + A11Y_MAXIMIZE_MENU_RESIZE_LEFT(2165), + @UiEvent(doc = "A11y service selected resize right button from app header maximize menu") + A11Y_MAXIMIZE_MENU_RESIZE_RIGHT(2166), + @UiEvent(doc = "A11y service triggered a11y action to maximize/restore app window") + A11Y_ACTION_MAXIMIZE_RESTORE(2167), + @UiEvent(doc = "A11y service triggered a11y action to resize app window left") + A11Y_ACTION_RESIZE_LEFT(2168), + @UiEvent(doc = "A11y service triggered a11y action to resize app window right") + A11Y_ACTION_RESIZE_RIGHT(2169); override fun getId(): Int = mId } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt index e77acfb805a6..8495f71ccba8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt @@ -1112,6 +1112,7 @@ class DesktopRepository( internal fun dump(pw: PrintWriter, prefix: String) { val innerPrefix = "$prefix " pw.println("${prefix}DesktopRepository") + pw.println("${innerPrefix}userId=$userId") dumpDesktopTaskData(pw, innerPrefix) pw.println("${innerPrefix}activeTasksListeners=${activeTasksListeners.size}") pw.println("${innerPrefix}visibleTasksListeners=${visibleTasksListeners.size}") diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt index c10752d36bf9..72758bd538d6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt @@ -21,6 +21,7 @@ import android.content.Context import android.content.pm.UserInfo import android.os.UserManager import android.util.SparseArray +import android.window.DesktopExperienceFlags import android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_HSUM import androidx.core.util.forEach import com.android.internal.protolog.ProtoLog @@ -68,7 +69,10 @@ class DesktopUserRepositories( if (DesktopModeStatus.canEnterDesktopMode(context)) { shellInit.addInitCallback(::onInit, this) } - if (ENABLE_DESKTOP_WINDOWING_HSUM.isTrue()) { + if ( + ENABLE_DESKTOP_WINDOWING_HSUM.isTrue() && + !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue + ) { userIdToProfileIdsMap[userId] = userManager.getProfiles(userId).map { it.id } } } @@ -76,6 +80,13 @@ class DesktopUserRepositories( private fun onInit() { repositoryInitializer.initialize(this) shellController.addUserChangeListener(this) + if ( + ENABLE_DESKTOP_WINDOWING_HSUM.isTrue() && + DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue + ) { + userId = ActivityManager.getCurrentUser() + userIdToProfileIdsMap[userId] = userManager.getProfiles(userId).map { it.id } + } } /** Returns [DesktopRepository] for the parent user id. */ @@ -97,10 +108,10 @@ class DesktopUserRepositories( /** Dumps [DesktopRepository] for each user. */ fun dump(pw: PrintWriter, prefix: String) { - desktopRepoByUserId.forEach { key, value -> - pw.println("${prefix}userId=$key") - value.dump(pw, prefix) - } + val innerPrefix = "$prefix " + pw.println("${prefix}DesktopUserRepositories:") + pw.println("${innerPrefix}currentUserId=$userId") + desktopRepoByUserId.forEach { key, value -> value.dump(pw, innerPrefix) } } override fun onUserChanged(newUserId: Int, userContext: Context) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/DefaultHomePackageSupplier.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/DefaultHomePackageSupplier.kt index 8ce624e103ef..bf687f2e4f3a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/DefaultHomePackageSupplier.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/DefaultHomePackageSupplier.kt @@ -20,6 +20,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter +import android.content.pm.PackageManager import android.os.Handler import com.android.wm.shell.shared.annotations.ShellMainThread import com.android.wm.shell.sysui.ShellInit @@ -28,6 +29,7 @@ import java.util.function.Supplier /** * This supplies the package name of default home in an efficient way. The query to package manager * only executes on initialization and when the preferred activity (e.g. default home) is changed. + * Note that this returns null package name if the default home is setup wizard. */ class DefaultHomePackageSupplier( private val context: Context, @@ -36,6 +38,7 @@ class DefaultHomePackageSupplier( ) : BroadcastReceiver(), Supplier<String?> { private var defaultHomePackage: String? = null + private var isSetupWizard: Boolean = false init { shellInit.addInitCallback({ onInit() }, this) @@ -52,6 +55,14 @@ class DefaultHomePackageSupplier( private fun updateDefaultHomePackage(): String? { defaultHomePackage = context.packageManager.getHomeActivities(ArrayList())?.packageName + isSetupWizard = + defaultHomePackage != null && + context.packageManager.resolveActivity( + Intent() + .setPackage(defaultHomePackage) + .addCategory(Intent.CATEGORY_SETUP_WIZARD), + PackageManager.MATCH_SYSTEM_ONLY, + ) != null return defaultHomePackage } @@ -60,6 +71,7 @@ class DefaultHomePackageSupplier( } override fun get(): String? { + if (isSetupWizard) return null return defaultHomePackage ?: updateDefaultHomePackage() } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java index 07b385bdb045..69e1f36dec0b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java @@ -1802,6 +1802,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, mMultiInstanceHelper, mWindowDecorCaptionHandleRepository, mDesktopModeEventLogger, + mDesktopModeUiEventLogger, mDesktopModeCompatPolicy); mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index 49c380a1a736..50bc7b5e865b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -93,6 +93,7 @@ import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.CaptionState; import com.android.wm.shell.desktopmode.DesktopModeEventLogger; +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger; import com.android.wm.shell.desktopmode.DesktopModeUtils; import com.android.wm.shell.desktopmode.DesktopUserRepositories; import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository; @@ -211,6 +212,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private final MultiInstanceHelper mMultiInstanceHelper; private final WindowDecorCaptionHandleRepository mWindowDecorCaptionHandleRepository; private final DesktopUserRepositories mDesktopUserRepositories; + private final DesktopModeUiEventLogger mDesktopModeUiEventLogger; private boolean mIsRecentsTransitionRunning = false; private boolean mIsDragging = false; private Runnable mLoadAppInfoRunnable; @@ -243,6 +245,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin MultiInstanceHelper multiInstanceHelper, WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository, DesktopModeEventLogger desktopModeEventLogger, + DesktopModeUiEventLogger desktopModeUiEventLogger, DesktopModeCompatPolicy desktopModeCompatPolicy) { this (context, userContext, displayController, taskResourceLoader, splitScreenController, desktopUserRepositories, taskOrganizer, taskInfo, taskSurface, handler, @@ -257,7 +260,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin DefaultMaximizeMenuFactory.INSTANCE, DefaultHandleMenuFactory.INSTANCE, multiInstanceHelper, windowDecorCaptionHandleRepository, desktopModeEventLogger, - desktopModeCompatPolicy); + desktopModeUiEventLogger, desktopModeCompatPolicy); } DesktopModeWindowDecoration( @@ -294,6 +297,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin MultiInstanceHelper multiInstanceHelper, WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository, DesktopModeEventLogger desktopModeEventLogger, + DesktopModeUiEventLogger desktopModeUiEventLogger, DesktopModeCompatPolicy desktopModeCompatPolicy) { super(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface, surfaceControlBuilderSupplier, surfaceControlTransactionSupplier, @@ -321,6 +325,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mTaskResourceLoader = taskResourceLoader; mTaskResourceLoader.onWindowDecorCreated(taskInfo); mDesktopModeCompatPolicy = desktopModeCompatPolicy; + mDesktopModeUiEventLogger = desktopModeUiEventLogger; } /** @@ -895,10 +900,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mOnCaptionTouchListener, mOnCaptionButtonClickListener, mWindowManagerWrapper, - mHandler + mHandler, + mDesktopModeUiEventLogger ); - } else if (mRelayoutParams.mLayoutResId - == R.layout.desktop_mode_app_header) { + } else if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_app_header) { return mAppHeaderViewHolderFactory.create( mResult.mRootView, mOnCaptionTouchListener, @@ -908,7 +913,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mOnLeftSnapClickListener, mOnRightSnapClickListener, mOnMaximizeOrRestoreClickListener, - mOnMaximizeHoverListener); + mOnMaximizeHoverListener, + mDesktopModeUiEventLogger); } throw new IllegalArgumentException("Unexpected layout resource id"); } @@ -1372,7 +1378,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mMaximizeMenu = mMaximizeMenuFactory.create(mSyncQueue, mRootTaskDisplayAreaOrganizer, mDisplayController, mTaskInfo, mContext, (width, height) -> calculateMaximizeMenuPosition(width, height), - mSurfaceControlTransactionSupplier); + mSurfaceControlTransactionSupplier, mDesktopModeUiEventLogger); mMaximizeMenu.show( /* isTaskInImmersiveMode= */ @@ -1488,6 +1494,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin shouldShowRestartButton, isBrowserApp, isBrowserApp ? getAppLink() : getBrowserLink(), + mDesktopModeUiEventLogger, mResult.mCaptionWidth, mResult.mCaptionHeight, mResult.mCaptionX, @@ -1973,6 +1980,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin MultiInstanceHelper multiInstanceHelper, WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository, DesktopModeEventLogger desktopModeEventLogger, + DesktopModeUiEventLogger desktopModeUiEventLogger, DesktopModeCompatPolicy desktopModeCompatPolicy) { return new DesktopModeWindowDecoration( context, @@ -2000,6 +2008,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin multiInstanceHelper, windowDecorCaptionHandleRepository, desktopModeEventLogger, + desktopModeUiEventLogger, desktopModeCompatPolicy); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt index f64b0d8695d2..25cf06b4247c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt @@ -28,6 +28,7 @@ import android.graphics.Bitmap import android.graphics.Point import android.graphics.PointF import android.graphics.Rect +import android.os.Bundle import android.view.LayoutInflater import android.view.MotionEvent import android.view.MotionEvent.ACTION_OUTSIDE @@ -35,6 +36,7 @@ import android.view.SurfaceControl import android.view.View import android.view.WindowInsets.Type.systemBars import android.view.WindowManager +import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction import android.widget.ImageButton import android.widget.ImageView import android.widget.Space @@ -49,6 +51,10 @@ import androidx.core.view.isGone import com.android.window.flags.Flags import com.android.wm.shell.R import com.android.wm.shell.bubbles.ContextUtils.isRtl +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_HANDLE_MENU_DESKTOP_VIEW +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_HANDLE_MENU_FULLSCREEN +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_HANDLE_MENU_SPLIT_SCREEN import com.android.wm.shell.shared.annotations.ShellBackgroundThread import com.android.wm.shell.shared.annotations.ShellMainThread import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper @@ -97,6 +103,7 @@ class HandleMenu( private val shouldShowRestartButton: Boolean, private val isBrowserApp: Boolean, private val openInAppOrBrowserIntent: Intent?, + private val desktopModeUiEventLogger: DesktopModeUiEventLogger, private val captionWidth: Int, private val captionHeight: Int, captionX: Int, @@ -208,6 +215,7 @@ class HandleMenu( ) { val handleMenuView = HandleMenuView( context = context, + desktopModeUiEventLogger = desktopModeUiEventLogger, menuWidth = menuWidth, captionHeight = captionHeight, shouldShowWindowingPill = shouldShowWindowingPill, @@ -475,6 +483,7 @@ class HandleMenu( @SuppressLint("ClickableViewAccessibility") class HandleMenuView( private val context: Context, + private val desktopModeUiEventLogger: DesktopModeUiEventLogger, menuWidth: Int, captionHeight: Int, private val shouldShowWindowingPill: Boolean, @@ -615,6 +624,45 @@ class HandleMenu( return@setOnTouchListener true } + desktopBtn.accessibilityDelegate = object : View.AccessibilityDelegate() { + override fun performAccessibilityAction( + host: View, + action: Int, + args: Bundle? + ): Boolean { + if (action == AccessibilityAction.ACTION_CLICK.id) { + desktopModeUiEventLogger.log(taskInfo, A11Y_APP_HANDLE_MENU_DESKTOP_VIEW) + } + return super.performAccessibilityAction(host, action, args) + } + } + + fullscreenBtn.accessibilityDelegate = object : View.AccessibilityDelegate() { + override fun performAccessibilityAction( + host: View, + action: Int, + args: Bundle? + ): Boolean { + if (action == AccessibilityAction.ACTION_CLICK.id) { + desktopModeUiEventLogger.log(taskInfo, A11Y_APP_HANDLE_MENU_FULLSCREEN) + } + return super.performAccessibilityAction(host, action, args) + } + } + + splitscreenBtn.accessibilityDelegate = object : View.AccessibilityDelegate() { + override fun performAccessibilityAction( + host: View, + action: Int, + args: Bundle? + ): Boolean { + if (action == AccessibilityAction.ACTION_CLICK.id) { + desktopModeUiEventLogger.log(taskInfo, A11Y_APP_HANDLE_MENU_SPLIT_SCREEN) + } + return super.performAccessibilityAction(host, action, args) + } + } + with(context) { // Update a11y announcement out to say "double tap to enter Fullscreen" ViewCompat.replaceAccessibilityAction( @@ -917,6 +965,7 @@ interface HandleMenuFactory { shouldShowRestartButton: Boolean, isBrowserApp: Boolean, openInAppOrBrowserIntent: Intent?, + desktopModeUiEventLogger: DesktopModeUiEventLogger, captionWidth: Int, captionHeight: Int, captionX: Int, @@ -942,6 +991,7 @@ object DefaultHandleMenuFactory : HandleMenuFactory { shouldShowRestartButton: Boolean, isBrowserApp: Boolean, openInAppOrBrowserIntent: Intent?, + desktopModeUiEventLogger: DesktopModeUiEventLogger, captionWidth: Int, captionHeight: Int, captionX: Int, @@ -963,6 +1013,7 @@ object DefaultHandleMenuFactory : HandleMenuFactory { shouldShowRestartButton, isBrowserApp, openInAppOrBrowserIntent, + desktopModeUiEventLogger, captionWidth, captionHeight, captionX, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt index 5d1a7a0cc3a2..a10826fca3e2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt @@ -60,14 +60,16 @@ import android.window.TaskConstants import androidx.compose.material3.ColorScheme import androidx.compose.ui.graphics.toArgb import androidx.core.animation.addListener -import androidx.core.view.ViewCompat -import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat import androidx.core.view.isGone import androidx.core.view.isVisible import com.android.wm.shell.R import com.android.wm.shell.RootTaskDisplayAreaOrganizer import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.SyncTransactionQueue +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_MAXIMIZE_MENU_MAXIMIZE +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_MAXIMIZE_MENU_RESIZE_LEFT +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_MAXIMIZE_MENU_RESIZE_RIGHT import com.android.wm.shell.desktopmode.isTaskMaximized import com.android.wm.shell.shared.animation.Interpolators.EMPHASIZED_DECELERATE import com.android.wm.shell.shared.animation.Interpolators.FAST_OUT_LINEAR_IN @@ -85,13 +87,14 @@ import java.util.function.Supplier * to the right or left half of the screen. */ class MaximizeMenu( - private val syncQueue: SyncTransactionQueue, - private val rootTdaOrganizer: RootTaskDisplayAreaOrganizer, - private val displayController: DisplayController, - private val taskInfo: RunningTaskInfo, - private val decorWindowContext: Context, - private val positionSupplier: (Int, Int) -> Point, - private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() } + private val syncQueue: SyncTransactionQueue, + private val rootTdaOrganizer: RootTaskDisplayAreaOrganizer, + private val displayController: DisplayController, + private val taskInfo: RunningTaskInfo, + private val decorWindowContext: Context, + private val positionSupplier: (Int, Int) -> Point, + private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() }, + private val desktopModeUiEventLogger: DesktopModeUiEventLogger ) { private var maximizeMenu: AdditionalViewHostViewContainer? = null private var maximizeMenuView: MaximizeMenuView? = null @@ -132,7 +135,7 @@ class MaximizeMenu( onLeftSnapClickListener = onLeftSnapClickListener, onRightSnapClickListener = onRightSnapClickListener, onHoverListener = onHoverListener, - onOutsideTouchListener = onOutsideTouchListener + onOutsideTouchListener = onOutsideTouchListener, ) maximizeMenuView?.let { view -> view.animateOpenMenu(onEnd = { @@ -167,7 +170,7 @@ class MaximizeMenu( onLeftSnapClickListener: () -> Unit, onRightSnapClickListener: () -> Unit, onHoverListener: (Boolean) -> Unit, - onOutsideTouchListener: () -> Unit + onOutsideTouchListener: () -> Unit, ) { val t = transactionSupplier.get() val builder = SurfaceControl.Builder() @@ -186,6 +189,7 @@ class MaximizeMenu( "MaximizeMenu") maximizeMenuView = MaximizeMenuView( context = decorWindowContext, + desktopModeUiEventLogger = desktopModeUiEventLogger, sizeToggleDirection = getSizeToggleDirection(), immersiveConfig = if (showImmersiveOption) { MaximizeMenuView.ImmersiveConfig.Visible( @@ -265,6 +269,7 @@ class MaximizeMenu( */ class MaximizeMenuView( context: Context, + private val desktopModeUiEventLogger: DesktopModeUiEventLogger, private val sizeToggleDirection: SizeToggleDirection, immersiveConfig: ImmersiveConfig, showSnapOptions: Boolean, @@ -425,7 +430,10 @@ class MaximizeMenu( ) { super.onInitializeAccessibilityNodeInfo(host, info) - info.addAction(AccessibilityAction.ACTION_CLICK) + info.addAction(AccessibilityAction( + AccessibilityAction.ACTION_CLICK.id, + context.getString(R.string.maximize_menu_talkback_action_maximize_restore_text) + )) host.isClickable = true } @@ -435,6 +443,7 @@ class MaximizeMenu( args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { + desktopModeUiEventLogger.log(taskInfo, A11Y_MAXIMIZE_MENU_MAXIMIZE) onMaximizeClickListener?.invoke() } return super.performAccessibilityAction(host, action, args) @@ -447,7 +456,10 @@ class MaximizeMenu( info: AccessibilityNodeInfo ) { super.onInitializeAccessibilityNodeInfo(host, info) - info.addAction(AccessibilityAction.ACTION_CLICK) + info.addAction(AccessibilityAction( + AccessibilityAction.ACTION_CLICK.id, + context.getString(R.string.maximize_menu_talkback_action_snap_left_text) + )) host.isClickable = true } @@ -457,6 +469,7 @@ class MaximizeMenu( args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { + desktopModeUiEventLogger.log(taskInfo, A11Y_MAXIMIZE_MENU_RESIZE_LEFT) onLeftSnapClickListener?.invoke() } return super.performAccessibilityAction(host, action, args) @@ -469,7 +482,10 @@ class MaximizeMenu( info: AccessibilityNodeInfo ) { super.onInitializeAccessibilityNodeInfo(host, info) - info.addAction(AccessibilityAction.ACTION_CLICK) + info.addAction(AccessibilityAction( + AccessibilityAction.ACTION_CLICK.id, + context.getString(R.string.maximize_menu_talkback_action_snap_right_text) + )) host.isClickable = true } @@ -479,35 +495,13 @@ class MaximizeMenu( args: Bundle? ): Boolean { if (action == AccessibilityAction.ACTION_CLICK.id) { + desktopModeUiEventLogger.log(taskInfo, A11Y_MAXIMIZE_MENU_RESIZE_RIGHT) onRightSnapClickListener?.invoke() } return super.performAccessibilityAction(host, action, args) } } - with(context.resources) { - ViewCompat.replaceAccessibilityAction( - snapLeftButton, - AccessibilityActionCompat.ACTION_CLICK, - getString(R.string.maximize_menu_talkback_action_snap_left_text), - null - ) - - ViewCompat.replaceAccessibilityAction( - snapRightButton, - AccessibilityActionCompat.ACTION_CLICK, - getString(R.string.maximize_menu_talkback_action_snap_right_text), - null - ) - - ViewCompat.replaceAccessibilityAction( - sizeToggleButton, - AccessibilityActionCompat.ACTION_CLICK, - getString(R.string.maximize_menu_talkback_action_maximize_restore_text), - null - ) - } - // Maximize/restore button. val sizeToggleBtnTextId = if (sizeToggleDirection == SizeToggleDirection.RESTORE) R.string.desktop_mode_maximize_menu_restore_button_text @@ -792,15 +786,15 @@ class MaximizeMenu( } /** Measure width of the root view of this menu. */ - fun measureWidth() : Int { - rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - return rootView.getMeasuredWidth() + fun measureWidth(): Int { + rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED) + return rootView.measuredWidth } /** Measure height of the root view of this menu. */ - fun measureHeight() : Int { - rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - return rootView.getMeasuredHeight() + fun measureHeight(): Int { + rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED) + return rootView.measuredHeight } private fun deactivateSnapOptions() { @@ -1048,7 +1042,8 @@ interface MaximizeMenuFactory { taskInfo: RunningTaskInfo, decorWindowContext: Context, positionSupplier: (Int, Int) -> Point, - transactionSupplier: Supplier<Transaction> + transactionSupplier: Supplier<Transaction>, + desktopModeUiEventLogger: DesktopModeUiEventLogger, ): MaximizeMenu } @@ -1061,7 +1056,8 @@ object DefaultMaximizeMenuFactory : MaximizeMenuFactory { taskInfo: RunningTaskInfo, decorWindowContext: Context, positionSupplier: (Int, Int) -> Point, - transactionSupplier: Supplier<Transaction> + transactionSupplier: Supplier<Transaction>, + desktopModeUiEventLogger: DesktopModeUiEventLogger, ): MaximizeMenu { return MaximizeMenu( syncQueue, @@ -1070,7 +1066,8 @@ object DefaultMaximizeMenuFactory : MaximizeMenuFactory { taskInfo, decorWindowContext, positionSupplier, - transactionSupplier + transactionSupplier, + desktopModeUiEventLogger ) } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt index 854d9e1deef1..b57931121881 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt @@ -432,15 +432,38 @@ class DesktopTilingWindowDecoration( startTransaction: Transaction, finishTransaction: Transaction, ) { + var leftTaskBroughtToFront = false + var rightTaskBroughtToFront = false + for (change in info.changes) { change.taskInfo?.let { if (it.isFullscreen || isMinimized(change.mode, info.type)) { removeTaskIfTiled(it.taskId, /* taskVanished= */ false, it.isFullscreen) } else if (isEnteringPip(change, info.type)) { removeTaskIfTiled(it.taskId, /* taskVanished= */ true, it.isFullscreen) + } else if (isTransitionToFront(change.mode, info.type)) { + handleTaskBroughtToFront(it.taskId) + leftTaskBroughtToFront = + leftTaskBroughtToFront || + it.taskId == leftTaskResizingHelper?.taskInfo?.taskId + rightTaskBroughtToFront = + rightTaskBroughtToFront || + it.taskId == rightTaskResizingHelper?.taskInfo?.taskId } } } + + if (leftTaskBroughtToFront && rightTaskBroughtToFront) { + desktopTilingDividerWindowManager?.showDividerBar() + } + } + + private fun handleTaskBroughtToFront(taskId: Int) { + if (taskId == leftTaskResizingHelper?.taskInfo?.taskId) { + leftTaskResizingHelper?.onAppBecomingVisible() + } else if (taskId == rightTaskResizingHelper?.taskInfo?.taskId) { + rightTaskResizingHelper?.onAppBecomingVisible() + } } private fun isMinimized(changeMode: Int, infoType: Int): Boolean { @@ -471,6 +494,9 @@ class DesktopTilingWindowDecoration( return false } + private fun isTransitionToFront(changeMode: Int, transitionType: Int): Boolean = + changeMode == TRANSIT_TO_FRONT && transitionType == TRANSIT_TO_FRONT + class AppResizingHelper( val taskInfo: RunningTaskInfo, val desktopModeWindowDecoration: DesktopModeWindowDecoration, @@ -484,6 +510,7 @@ class DesktopTilingWindowDecoration( ) { var isInitialised = false var newBounds = Rect(bounds) + var visibilityCallback: (() -> Unit)? = null private lateinit var resizeVeil: ResizeVeil private val displayContext = displayController.getDisplayContext(taskInfo.displayId) private val userContext = @@ -521,6 +548,11 @@ class DesktopTilingWindowDecoration( fun updateVeil(t: Transaction) = resizeVeil.updateTransactionWithResizeVeil(t, newBounds) + fun onAppBecomingVisible() { + visibilityCallback?.invoke() + visibilityCallback = null + } + fun hideVeil() = resizeVeil.hideVeil() private fun createIconFactory(context: Context, dimensions: Int): BaseIconFactory { @@ -593,11 +625,16 @@ class DesktopTilingWindowDecoration( removeTask(leftTaskResizingHelper, taskVanished, shouldDelayUpdate) leftTaskResizingHelper = null val taskId = rightTaskResizingHelper?.taskInfo?.taskId - if (taskId != null && taskRepository.isVisibleTask(taskId)) { + val callback: (() -> Unit)? = { rightTaskResizingHelper ?.desktopModeWindowDecoration ?.updateDisabledResizingEdge(NONE, shouldDelayUpdate) } + if (taskId != null && taskRepository.isVisibleTask(taskId)) { + callback?.invoke() + } else if (rightTaskResizingHelper != null) { + rightTaskResizingHelper?.visibilityCallback = callback + } tearDownTiling() return } @@ -607,11 +644,17 @@ class DesktopTilingWindowDecoration( removeTask(rightTaskResizingHelper, taskVanished, shouldDelayUpdate) rightTaskResizingHelper = null val taskId = leftTaskResizingHelper?.taskInfo?.taskId - if (taskId != null && taskRepository.isVisibleTask(taskId)) { + val callback: (() -> Unit)? = { leftTaskResizingHelper ?.desktopModeWindowDecoration ?.updateDisabledResizingEdge(NONE, shouldDelayUpdate) } + if (taskId != null && taskRepository.isVisibleTask(taskId)) { + callback?.invoke() + } else if (leftTaskResizingHelper != null) { + leftTaskResizingHelper?.visibilityCallback = callback + } + tearDownTiling() } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt index 9d16be59ba34..f09c500dcdd0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt @@ -39,6 +39,8 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.Accessibilit import com.android.internal.policy.SystemBarUtils import com.android.window.flags.Flags import com.android.wm.shell.R +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_HANDLE_MENU_OPENED import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper import com.android.wm.shell.windowdecor.AppHandleAnimator import com.android.wm.shell.windowdecor.WindowManagerWrapper @@ -53,7 +55,8 @@ class AppHandleViewHolder( onCaptionTouchListener: View.OnTouchListener, onCaptionButtonClickListener: OnClickListener, private val windowManagerWrapper: WindowManagerWrapper, - private val handler: Handler + private val handler: Handler, + private val desktopModeUiEventLogger: DesktopModeUiEventLogger, ) : WindowDecorationViewHolder<AppHandleViewHolder.HandleData>(rootView) { data class HandleData( @@ -201,6 +204,7 @@ class AppHandleViewHolder( // Passthrough the a11y click action so the caption handle, so that app handle menu // is opened on a11y click, similar to a real click if (action == AccessibilityAction.ACTION_CLICK.id) { + desktopModeUiEventLogger.log(taskInfo, A11Y_APP_HANDLE_MENU_OPENED) captionHandle.performClick() } return super.performAccessibilityAction(host, action, args) @@ -216,10 +220,13 @@ class AppHandleViewHolder( } } - // Update a11y action text so that Talkback announces "Press double tap to open app handle - // menu" while focused on status bar input layer + // Update a11y action text so that Talkback announces "Press double tap to open menu" + // while focused on status bar input layer ViewCompat.replaceAccessibilityAction( - view, AccessibilityActionCompat.ACTION_CLICK, "Open app handle menu", null + view, + AccessibilityActionCompat.ACTION_CLICK, + context.getString(R.string.app_handle_chip_accessibility_announce), + null ) } @@ -297,12 +304,14 @@ class AppHandleViewHolder( onCaptionButtonClickListener: OnClickListener, windowManagerWrapper: WindowManagerWrapper, handler: Handler, + desktopModeUiEventLogger: DesktopModeUiEventLogger, ): AppHandleViewHolder = AppHandleViewHolder( rootView, onCaptionTouchListener, onCaptionButtonClickListener, windowManagerWrapper, handler, + desktopModeUiEventLogger, ) } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt index 0e2698d0b6fa..d2e3a07f4651 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt @@ -49,6 +49,13 @@ import com.android.internal.R.color.materialColorSurfaceContainerHigh import com.android.internal.R.color.materialColorSurfaceContainerLow import com.android.internal.R.color.materialColorSurfaceDim import com.android.wm.shell.R +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_ACTION_MAXIMIZE_RESTORE +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_ACTION_RESIZE_LEFT +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_ACTION_RESIZE_RIGHT +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_WINDOW_CLOSE_BUTTON +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_WINDOW_MAXIMIZE_RESTORE_BUTTON +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_WINDOW_MINIMIZE_BUTTON import com.android.wm.shell.windowdecor.MaximizeButtonView import com.android.wm.shell.windowdecor.common.DecorThemeUtil import com.android.wm.shell.windowdecor.common.DrawableInsets @@ -75,6 +82,7 @@ class AppHeaderViewHolder( mOnRightSnapClickListener: () -> Unit, mOnMaximizeOrRestoreClickListener: () -> Unit, onMaximizeHoverAnimationFinishedListener: () -> Unit, + private val desktopModeUiEventLogger: DesktopModeUiEventLogger, ) : WindowDecorationViewHolder<AppHeaderViewHolder.HeaderData>(rootView) { data class HeaderData( @@ -151,6 +159,8 @@ class AppHeaderViewHolder( private lateinit var a11yTextMaximize: String private lateinit var a11yTextRestore: String + private lateinit var currentTaskInfo: RunningTaskInfo + init { captionView.setOnTouchListener(onCaptionTouchListener) captionHandle.setOnTouchListener(onCaptionTouchListener) @@ -197,9 +207,18 @@ class AppHeaderViewHolder( args: Bundle? ): Boolean { when (action) { - R.id.action_snap_left -> mOnLeftSnapClickListener.invoke() - R.id.action_snap_right -> mOnRightSnapClickListener.invoke() - R.id.action_maximize_restore -> mOnMaximizeOrRestoreClickListener.invoke() + R.id.action_snap_left -> { + desktopModeUiEventLogger.log(currentTaskInfo, A11Y_ACTION_RESIZE_LEFT) + mOnLeftSnapClickListener.invoke() + } + R.id.action_snap_right -> { + desktopModeUiEventLogger.log(currentTaskInfo, A11Y_ACTION_RESIZE_RIGHT) + mOnRightSnapClickListener.invoke() + } + R.id.action_maximize_restore -> { + desktopModeUiEventLogger.log(currentTaskInfo, A11Y_ACTION_MAXIMIZE_RESTORE) + mOnMaximizeOrRestoreClickListener.invoke() + } } return super.performAccessibilityAction(host, action, args) @@ -224,10 +243,56 @@ class AppHeaderViewHolder( args: Bundle? ): Boolean { when (action) { - AccessibilityAction.ACTION_CLICK.id -> host.performClick() - R.id.action_snap_left -> mOnLeftSnapClickListener.invoke() - R.id.action_snap_right -> mOnRightSnapClickListener.invoke() - R.id.action_maximize_restore -> mOnMaximizeOrRestoreClickListener.invoke() + AccessibilityAction.ACTION_CLICK.id -> { + desktopModeUiEventLogger.log( + currentTaskInfo, A11Y_APP_WINDOW_MAXIMIZE_RESTORE_BUTTON + ) + host.performClick() + } + R.id.action_snap_left -> { + desktopModeUiEventLogger.log(currentTaskInfo, A11Y_ACTION_RESIZE_LEFT) + mOnLeftSnapClickListener.invoke() + } + R.id.action_snap_right -> { + desktopModeUiEventLogger.log(currentTaskInfo, A11Y_ACTION_RESIZE_RIGHT) + mOnRightSnapClickListener.invoke() + } + R.id.action_maximize_restore -> { + desktopModeUiEventLogger.log(currentTaskInfo, A11Y_ACTION_MAXIMIZE_RESTORE) + mOnMaximizeOrRestoreClickListener.invoke() + } + } + + return super.performAccessibilityAction(host, action, args) + } + } + + closeWindowButton.accessibilityDelegate = object : View.AccessibilityDelegate() { + override fun performAccessibilityAction( + host: View, + action: Int, + args: Bundle? + ): Boolean { + when (action) { + AccessibilityAction.ACTION_CLICK.id -> desktopModeUiEventLogger.log( + currentTaskInfo, A11Y_APP_WINDOW_CLOSE_BUTTON + ) + } + + return super.performAccessibilityAction(host, action, args) + } + } + + minimizeWindowButton.accessibilityDelegate = object : View.AccessibilityDelegate() { + override fun performAccessibilityAction( + host: View, + action: Int, + args: Bundle? + ): Boolean { + when (action) { + AccessibilityAction.ACTION_CLICK.id -> desktopModeUiEventLogger.log( + currentTaskInfo, A11Y_APP_WINDOW_MINIMIZE_BUTTON + ) } return super.performAccessibilityAction(host, action, args) @@ -310,7 +375,8 @@ class AppHeaderViewHolder( enableMaximizeLongClick: Boolean, isCaptionVisible: Boolean, ) { - if (DesktopModeFlags.ENABLE_THEMED_APP_HEADERS.isTrue()) { + currentTaskInfo = taskInfo + if (DesktopModeFlags.ENABLE_THEMED_APP_HEADERS.isTrue) { bindDataWithThemedHeaders( taskInfo, isTaskMaximized, @@ -361,7 +427,7 @@ class AppHeaderViewHolder( minimizeWindowButton.background = getDrawable(1) } maximizeButtonView.setAnimationTints(isDarkMode()) - minimizeWindowButton.isGone = !DesktopModeFlags.ENABLE_MINIMIZE_BUTTON.isTrue() + minimizeWindowButton.isGone = !DesktopModeFlags.ENABLE_MINIMIZE_BUTTON.isTrue } private fun bindDataWithThemedHeaders( @@ -417,7 +483,7 @@ class AppHeaderViewHolder( drawableInsets = minimizeDrawableInsets ) } - minimizeWindowButton.isGone = !DesktopModeFlags.ENABLE_MINIMIZE_BUTTON.isTrue() + minimizeWindowButton.isGone = !DesktopModeFlags.ENABLE_MINIMIZE_BUTTON.isTrue // Maximize button. maximizeButtonView.apply { setAnimationTints( @@ -761,6 +827,7 @@ class AppHeaderViewHolder( mOnRightSnapClickListener: () -> Unit, mOnMaximizeOrRestoreClickListener: () -> Unit, onMaximizeHoverAnimationFinishedListener: () -> Unit, + desktopModeUiEventLogger: DesktopModeUiEventLogger ): AppHeaderViewHolder = AppHeaderViewHolder( rootView, onCaptionTouchListener, @@ -771,6 +838,7 @@ class AppHeaderViewHolder( mOnRightSnapClickListener, mOnMaximizeOrRestoreClickListener, onMaximizeHoverAnimationFinishedListener, + desktopModeUiEventLogger, ) } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java index 3d5e9495e29d..1e459d55ed77 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java @@ -18,6 +18,7 @@ package com.android.wm.shell.common; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -231,4 +232,24 @@ public class DisplayControllerTests extends ShellTestCase { assertEquals(DISPLAY_ABS_BOUNDS_1, mController.getDisplayLayout(DISPLAY_ID_1).globalBoundsDp()); } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG) + public void onDisplayConfigurationChanged_reInitDisplayLayout() + throws RemoteException { + ExtendedMockito.doReturn(true) + .when(() -> DesktopModeStatus.canEnterDesktopMode(any())); + mController.onInit(); + mController.addDisplayWindowListener(mListener); + + mCapturedTopologyListener.accept(mMockTopology); + + DisplayLayout displayLayoutBefore = mController.getDisplayLayout(DISPLAY_ID_0); + mDisplayContainerListener.onDisplayConfigurationChanged(DISPLAY_ID_0, new Configuration()); + DisplayLayout displayLayoutAfter = mController.getDisplayLayout(DISPLAY_ID_0); + + assertNotSame(displayLayoutBefore, displayLayoutAfter); + assertEquals(DISPLAY_ABS_BOUNDS_0, + mController.getDisplayLayout(DISPLAY_ID_0).globalBoundsDp()); + } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt index ed69d912c4ef..2126d1d9b986 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt @@ -337,7 +337,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { mockDesktopModeWindowDecorFactory.create( any(), any(), any(), any(), any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), - any(), any(), any(), any()) + any(), any(), any(), any(), any()) ).thenReturn(decoration) decoration.mTaskInfo = task whenever(decoration.user).thenReturn(mockUserHandle) diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java index 77513adf0088..0908f56e1cfb 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java @@ -106,6 +106,7 @@ import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.CaptionState; import com.android.wm.shell.desktopmode.DesktopModeEventLogger; +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger; import com.android.wm.shell.desktopmode.DesktopRepository; import com.android.wm.shell.desktopmode.DesktopUserRepositories; import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository; @@ -246,6 +247,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { @Mock private DesktopModeEventLogger mDesktopModeEventLogger; @Mock + private DesktopModeUiEventLogger mDesktopModeUiEventLogger; + @Mock private DesktopRepository mDesktopRepository; @Mock private WindowDecorTaskResourceLoader mMockTaskResourceLoader; @@ -303,15 +306,15 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { doReturn(mInsetsState).when(mMockDisplayController).getInsetsState(anyInt()); when(mMockHandleMenuFactory.create(any(), any(), any(), any(), any(), anyInt(), any(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), - anyBoolean(), any(), anyInt(), anyInt(), anyInt(), anyInt())) + anyBoolean(), any(), any(), anyInt(), anyInt(), anyInt(), anyInt())) .thenReturn(mMockHandleMenu); when(mMockMultiInstanceHelper.supportsMultiInstanceSplit(any(), anyInt())) .thenReturn(false); when(mMockAppHeaderViewHolderFactory - .create(any(), any(), any(), any(), any(), any(), any(), any(), any())) + .create(any(), any(), any(), any(), any(), any(), any(), any(), any(), any())) .thenReturn(mMockAppHeaderViewHolder); when(mMockAppHandleViewHolderFactory - .create(any(), any(), any(), any(), any())) + .create(any(), any(), any(), any(), any(), any())) .thenReturn(mMockAppHandleViewHolder); when(mMockDesktopUserRepositories.getCurrent()).thenReturn(mDesktopRepository); when(mMockDesktopUserRepositories.getProfile(anyInt())).thenReturn(mDesktopRepository); @@ -1797,7 +1800,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { any(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), argThat(intent -> (uri == null && intent == null) || intent.getData().equals(uri)), - anyInt(), anyInt(), anyInt(), anyInt()); + any(), anyInt(), anyInt(), anyInt(), anyInt()); } private void createMaximizeMenu(DesktopModeWindowDecoration decoration) { @@ -1894,7 +1897,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { new WindowManagerWrapper(mMockWindowManager), mMockSurfaceControlViewHostFactory, mMockWindowDecorViewHostSupplier, maximizeMenuFactory, mMockHandleMenuFactory, mMockMultiInstanceHelper, mMockCaptionHandleRepository, mDesktopModeEventLogger, - mDesktopModeCompatPolicy); + mDesktopModeUiEventLogger, mDesktopModeCompatPolicy); windowDecor.setCaptionListeners(mMockTouchEventListener, mMockTouchEventListener, mMockTouchEventListener, mMockTouchEventListener); windowDecor.setExclusionRegionListener(mMockExclusionRegionListener); @@ -2020,7 +2023,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { @NonNull Context decorWindowContext, @NonNull Function2<? super Integer,? super Integer,? extends Point> positionSupplier, - @NonNull Supplier<SurfaceControl.Transaction> transactionSupplier) { + @NonNull Supplier<SurfaceControl.Transaction> transactionSupplier, + @NonNull DesktopModeUiEventLogger desktopModeUiEventLogger) { return mMaximizeMenu; } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt index e4b897264883..b0b95c97ae18 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt @@ -43,6 +43,7 @@ import com.android.wm.shell.ShellTestCase import com.android.wm.shell.TestRunningTaskInfoBuilder import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.DisplayLayout +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED @@ -95,6 +96,8 @@ class HandleMenuTest : ShellTestCase() { private lateinit var mockTaskResourceLoader: WindowDecorTaskResourceLoader @Mock private lateinit var mockAppIcon: Bitmap + @Mock + private lateinit var mockDesktopModeUiEventLogger: DesktopModeUiEventLogger private lateinit var handleMenu: HandleMenu @@ -290,6 +293,7 @@ class HandleMenuTest : ShellTestCase() { shouldShowRestartButton = true, isBrowserApp = false, null /* openInAppOrBrowserIntent */, + mockDesktopModeUiEventLogger, captionWidth = HANDLE_WIDTH, captionHeight = 50, captionX = captionX, diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt index e5f8d7d34a47..0adca5e864bf 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt @@ -587,6 +587,31 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() { } @Test + fun tilingDivider_shouldBeShown_whenTiledTasksBecomeVisible() { + val task1 = createVisibleTask() + val task2 = createVisibleTask() + val additionalTaskHelper: DesktopTilingWindowDecoration.AppResizingHelper = mock() + whenever(tiledTaskHelper.taskInfo).thenReturn(task1) + whenever(tiledTaskHelper.desktopModeWindowDecoration).thenReturn(desktopWindowDecoration) + whenever(additionalTaskHelper.taskInfo).thenReturn(task2) + whenever(additionalTaskHelper.desktopModeWindowDecoration) + .thenReturn(desktopWindowDecoration) + + tilingDecoration.leftTaskResizingHelper = tiledTaskHelper + tilingDecoration.rightTaskResizingHelper = additionalTaskHelper + tilingDecoration.desktopTilingDividerWindowManager = desktopTilingDividerWindowManager + val changeInfo = createTransitFrontTransition(task1, task2) + tilingDecoration.onTransitionReady( + transition = mock(), + info = changeInfo, + startTransaction = mock(), + finishTransaction = mock(), + ) + + verify(desktopTilingDividerWindowManager, times(1)).showDividerBar() + } + + @Test fun taskNotTiled_shouldNotBeRemoved_whenNotTiled() { val task1 = createVisibleTask() val task2 = createVisibleTask() @@ -762,6 +787,30 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() { ) } + private fun createTransitFrontTransition( + task1: RunningTaskInfo?, + task2: RunningTaskInfo?, + type: Int = TRANSIT_TO_FRONT, + ) = + TransitionInfo(type, /* flags= */ 0).apply { + addChange( + Change(mock(), mock()).apply { + mode = TRANSIT_TO_FRONT + parent = null + taskInfo = task1 + flags = flags + } + ) + addChange( + Change(mock(), mock()).apply { + mode = TRANSIT_TO_FRONT + parent = null + taskInfo = task2 + flags = flags + } + ) + } + companion object { private val NON_STABLE_BOUNDS_MOCK = Rect(50, 55, 100, 100) private val STABLE_BOUNDS_MOCK = Rect(0, 0, 100, 100) diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt index 2c3009cb8dc4..e23019a59307 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt @@ -26,6 +26,7 @@ import androidx.test.filters.SmallTest import com.android.internal.policy.SystemBarUtils import com.android.wm.shell.R import com.android.wm.shell.ShellTestCase +import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger import com.android.wm.shell.windowdecor.WindowManagerWrapper import org.junit.Before import org.junit.runner.RunWith @@ -57,6 +58,7 @@ class AppHandleViewHolderTest : ShellTestCase() { private val mockWindowManagerWrapper = mock<WindowManagerWrapper>() private val mockHandler = mock<Handler>() private val mockTaskInfo = mock<RunningTaskInfo>() + private val mockDesktopModeUiEventLogger = mock<DesktopModeUiEventLogger>() @Before fun setup() { @@ -92,7 +94,8 @@ class AppHandleViewHolderTest : ShellTestCase() { mockOnTouchListener, mockOnClickListener, mockWindowManagerWrapper, - mockHandler + mockHandler, + mockDesktopModeUiEventLogger, ) } } diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp index 104ece6582f5..b6a2ad7064a9 100644 --- a/libs/hwui/jni/Bitmap.cpp +++ b/libs/hwui/jni/Bitmap.cpp @@ -28,7 +28,9 @@ #include "SkRefCnt.h" #include "SkStream.h" #include "SkTypes.h" +#ifdef __linux__ // Only Linux support parcel #include "android/binder_parcel.h" +#endif #include "android_nio_utils.h" #ifdef __ANDROID__ @@ -851,6 +853,7 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { #endif } +#ifdef __linux__ // Only Linux support parcel // Returns whether this bitmap should be written to the parcel as mutable. static bool shouldParcelAsMutable(SkBitmap& bitmap, AParcel* parcel) { // If the bitmap is immutable, then parcel as immutable. @@ -867,6 +870,7 @@ static bool shouldParcelAsMutable(SkBitmap& bitmap, AParcel* parcel) { // writing it to the parcel. return !shouldUseAshmem(parcel, bitmap.computeByteSize()); } +#endif static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, jlong bitmapHandle, jint density, jobject parcel) { diff --git a/media/java/android/media/projection/TEST_MAPPING b/media/java/android/media/projection/TEST_MAPPING index b33097c50002..ea62287b7411 100644 --- a/media/java/android/media/projection/TEST_MAPPING +++ b/media/java/android/media/projection/TEST_MAPPING @@ -1,7 +1,7 @@ { - "presubmit": [ + "imports": [ { - "name": "MediaProjectionTests" + "path": "frameworks/base/services/core/java/com/android/server/media/projection" } ] -} +}
\ No newline at end of file diff --git a/media/tests/projection/TEST_MAPPING b/media/tests/projection/TEST_MAPPING new file mode 100644 index 000000000000..b33097c50002 --- /dev/null +++ b/media/tests/projection/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "MediaProjectionTests" + } + ] +} diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/AndroidSecureSettings.java b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/AndroidSecureSettings.java index 8aee576c3d04..a06d8829e331 100644 --- a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/AndroidSecureSettings.java +++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/AndroidSecureSettings.java @@ -24,11 +24,11 @@ import android.provider.Settings; * Implementation of {@link SecureSettings} that uses Android's {@link Settings.Secure} * implementation. */ -class AndroidSecureSettings implements SecureSettings { +public class AndroidSecureSettings implements SecureSettings { private final ContentResolver mContentResolver; - AndroidSecureSettings(ContentResolver contentResolver) { + public AndroidSecureSettings(ContentResolver contentResolver) { mContentResolver = contentResolver; } diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManager.kt b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManager.kt index fdde3d3f5669..1da17756fae6 100644 --- a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManager.kt +++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManager.kt @@ -17,6 +17,7 @@ package com.android.settingslib.devicestate import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK +import android.util.Dumpable /** * Interface for managing [DEVICE_STATE_ROTATION_LOCK] setting. @@ -25,7 +26,7 @@ import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK * specific device states, retrieve the setting value, and check if rotation is locked for specific * or all device states. */ -interface DeviceStateAutoRotateSettingManager { +interface DeviceStateAutoRotateSettingManager : Dumpable { // TODO: b/397928958 - Rename all terms from rotationLock to autoRotate in all apis. /** Listener for changes in device-state based auto rotate setting. */ @@ -65,5 +66,3 @@ data class SettableDeviceState( /** Returns whether there is an auto-rotation setting for this device state. */ val isSettable: Boolean ) - - diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManagerImpl.kt b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManagerImpl.kt index 0b6c6e238956..a9f9eda07118 100644 --- a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManagerImpl.kt +++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManagerImpl.kt @@ -22,11 +22,13 @@ import android.os.UserHandle import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_IGNORED import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_LOCKED +import android.util.IndentingPrintWriter import android.util.Log import android.util.SparseIntArray import com.android.internal.R import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManager.DeviceStateAutoRotateSettingListener import com.android.window.flags.Flags +import java.io.PrintWriter import java.util.concurrent.Executor /** @@ -104,6 +106,15 @@ class DeviceStateAutoRotateSettingManagerImpl( throw UnsupportedOperationException("API updateSetting is not implemented yet") } + override fun dump(writer: PrintWriter, args: Array<out String>?) { + val indentingWriter = IndentingPrintWriter(writer) + indentingWriter.println("DeviceStateAutoRotateSettingManagerImpl") + indentingWriter.increaseIndent() + indentingWriter.println("fallbackPostureMap: $fallbackPostureMap") + indentingWriter.println("settableDeviceState: $settableDeviceState") + indentingWriter.decreaseIndent() + } + private fun notifyListeners() = settingListeners.forEach { listener -> listener.onSettingsChanged() } diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManagerProvider.kt b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManagerProvider.kt new file mode 100644 index 000000000000..2db8e6f97498 --- /dev/null +++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManagerProvider.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2025 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.settingslib.devicestate + +import android.content.Context +import android.os.Handler +import com.android.window.flags.Flags +import java.util.concurrent.Executor + +/** + * Provides appropriate instance of [DeviceStateAutoRotateSettingManager], based on the value of + * [Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_REFACTOR]. + */ +object DeviceStateAutoRotateSettingManagerProvider { + /** + * Provides an instance of [DeviceStateAutoRotateSettingManager], based on the value of + * [Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_REFACTOR]. It is supposed to be used + * by apps that supports dagger. + */ + @JvmStatic + fun createInstance( + context: Context, + backgroundExecutor: Executor, + secureSettings: SecureSettings, + mainHandler: Handler, + posturesHelper: PosturesHelper, + ): DeviceStateAutoRotateSettingManager = + if (Flags.enableDeviceStateAutoRotateSettingRefactor()) { + DeviceStateAutoRotateSettingManagerImpl( + context, + backgroundExecutor, + secureSettings, + mainHandler, + posturesHelper, + ) + } else { + DeviceStateRotationLockSettingsManager(context, secureSettings) + } +} diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java index deeba574f2ad..6d180b63cd08 100644 --- a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java +++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java @@ -20,10 +20,8 @@ import static android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_IGNORE import static android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_LOCKED; import static android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_UNLOCKED; -import static com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManager.DeviceStateAutoRotateSettingListener; - +import android.annotation.NonNull; import android.annotation.Nullable; -import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; import android.database.ContentObserver; @@ -41,6 +39,7 @@ import android.util.SparseIntArray; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -51,7 +50,8 @@ import java.util.Set; * Manages device-state based rotation lock settings. Handles reading, writing, and listening for * changes. */ -public final class DeviceStateRotationLockSettingsManager { +public final class DeviceStateRotationLockSettingsManager implements + DeviceStateAutoRotateSettingManager { private static final String TAG = "DSRotLockSettingsMngr"; private static final String SEPARATOR_REGEX = ":"; @@ -68,8 +68,7 @@ public final class DeviceStateRotationLockSettingsManager { private SparseIntArray mPostureRotationLockFallbackSettings; private List<SettableDeviceState> mSettableDeviceStates; - @VisibleForTesting - DeviceStateRotationLockSettingsManager(Context context, SecureSettings secureSettings) { + public DeviceStateRotationLockSettingsManager(Context context, SecureSettings secureSettings) { mSecureSettings = secureSettings; mPosturesHelper = new PosturesHelper(context, getDeviceStateManager(context)); @@ -89,30 +88,6 @@ public final class DeviceStateRotationLockSettingsManager { return null; } - /** Returns a singleton instance of this class */ - public static synchronized DeviceStateRotationLockSettingsManager getInstance(Context context) { - if (sSingleton == null) { - Context applicationContext = context.getApplicationContext(); - ContentResolver contentResolver = applicationContext.getContentResolver(); - SecureSettings secureSettings = new AndroidSecureSettings(contentResolver); - sSingleton = - new DeviceStateRotationLockSettingsManager(applicationContext, secureSettings); - } - return sSingleton; - } - - /** Resets the singleton instance of this class. Only used for testing. */ - @VisibleForTesting - public static synchronized void resetInstance() { - sSingleton = null; - } - - /** Returns true if device-state based rotation lock settings are enabled. */ - public static boolean isDeviceStateRotationLockEnabled(Context context) { - return context.getResources() - .getStringArray(R.array.config_perDeviceStateRotationLockDefaults).length > 0; - } - private void listenForSettingsChange() { mSecureSettings .registerContentObserver( @@ -131,7 +106,8 @@ public final class DeviceStateRotationLockSettingsManager { * Registers a {@link DeviceStateAutoRotateSettingListener} to be notified when the settings * change. Can be called multiple times with different listeners. */ - public void registerListener(DeviceStateAutoRotateSettingListener runnable) { + @Override + public void registerListener(@NonNull DeviceStateAutoRotateSettingListener runnable) { mListeners.add(runnable); } @@ -139,14 +115,16 @@ public final class DeviceStateRotationLockSettingsManager { * Unregisters a {@link DeviceStateAutoRotateSettingListener}. No-op if the given instance * was never registered. */ + @Override public void unregisterListener( - DeviceStateAutoRotateSettingListener deviceStateAutoRotateSettingListener) { + @NonNull DeviceStateAutoRotateSettingListener deviceStateAutoRotateSettingListener) { if (!mListeners.remove(deviceStateAutoRotateSettingListener)) { Log.w(TAG, "Attempting to unregister a listener hadn't been registered"); } } /** Updates the rotation lock setting for a specified device state. */ + @Override public void updateSetting(int deviceState, boolean rotationLocked) { int posture = mPosturesHelper.deviceStateToPosture(deviceState); if (mPostureRotationLockFallbackSettings.indexOfKey(posture) >= 0) { @@ -173,6 +151,7 @@ public final class DeviceStateRotationLockSettingsManager { * DEVICE_STATE_ROTATION_LOCK_IGNORED}. */ @Settings.Secure.DeviceStateRotationLockSetting + @Override public int getRotationLockSetting(int deviceState) { int devicePosture = mPosturesHelper.deviceStateToPosture(deviceState); int rotationLockSetting = mPostureRotationLockSettings.get( @@ -196,6 +175,7 @@ public final class DeviceStateRotationLockSettingsManager { /** Returns true if the rotation is locked for the current device state */ + @Override public boolean isRotationLocked(int deviceState) { return getRotationLockSetting(deviceState) == DEVICE_STATE_ROTATION_LOCK_LOCKED; } @@ -204,6 +184,7 @@ public final class DeviceStateRotationLockSettingsManager { * Returns true if there is no device state for which the current setting is {@link * DEVICE_STATE_ROTATION_LOCK_UNLOCKED}. */ + @Override public boolean isRotationLockedForAllStates() { for (int i = 0; i < mPostureRotationLockSettings.size(); i++) { if (mPostureRotationLockSettings.valueAt(i) @@ -215,6 +196,8 @@ public final class DeviceStateRotationLockSettingsManager { } /** Returns a list of device states and their respective auto-rotation setting availability. */ + @Override + @NonNull public List<SettableDeviceState> getSettableDeviceStates() { // Returning a copy to make sure that nothing outside can mutate our internal list. return new ArrayList<>(mSettableDeviceStates); @@ -356,17 +339,21 @@ public final class DeviceStateRotationLockSettingsManager { } } - /** Dumps internal state. */ - public void dump(IndentingPrintWriter pw) { - pw.println("DeviceStateRotationLockSettingsManager"); - pw.increaseIndent(); - pw.println("mPostureRotationLockDefaults: " + @Override + public void dump(@NonNull PrintWriter writer, String[] args) { + IndentingPrintWriter indentingWriter = new IndentingPrintWriter(writer); + indentingWriter.println("DeviceStateRotationLockSettingsManager"); + indentingWriter.increaseIndent(); + indentingWriter.println("mPostureRotationLockDefaults: " + Arrays.toString(mPostureRotationLockDefaults)); - pw.println("mPostureDefaultRotationLockSettings: " + mPostureDefaultRotationLockSettings); - pw.println("mDeviceStateRotationLockSettings: " + mPostureRotationLockSettings); - pw.println("mPostureRotationLockFallbackSettings: " + mPostureRotationLockFallbackSettings); - pw.println("mSettableDeviceStates: " + mSettableDeviceStates); - pw.decreaseIndent(); + indentingWriter.println( + "mPostureDefaultRotationLockSettings: " + mPostureDefaultRotationLockSettings); + indentingWriter.println( + "mDeviceStateRotationLockSettings: " + mPostureRotationLockSettings); + indentingWriter.println( + "mPostureRotationLockFallbackSettings: " + mPostureRotationLockFallbackSettings); + indentingWriter.println("mSettableDeviceStates: " + mSettableDeviceStates); + indentingWriter.decreaseIndent(); } /** diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateAutoRotateSettingManagerImplTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateAutoRotateSettingManagerImplTest.kt index 78dba57028ba..a9329ba3c76c 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateAutoRotateSettingManagerImplTest.kt +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateAutoRotateSettingManagerImplTest.kt @@ -181,8 +181,10 @@ class DeviceStateAutoRotateSettingManagerImplTest { @Test fun getAutoRotateSetting_forInvalidPosture_returnsSettingForFallbackPosture() { - persistSettings(DEVICE_STATE_ROTATION_KEY_UNFOLDED, DEVICE_STATE_ROTATION_LOCK_UNLOCKED) - persistSettings(DEVICE_STATE_ROTATION_KEY_FOLDED, DEVICE_STATE_ROTATION_LOCK_LOCKED) + persistSettings( + "$DEVICE_STATE_ROTATION_KEY_FOLDED:$DEVICE_STATE_ROTATION_LOCK_LOCKED:" + + "$DEVICE_STATE_ROTATION_KEY_UNFOLDED:$DEVICE_STATE_ROTATION_LOCK_UNLOCKED" + ) val autoRotateSetting = settingManager.getRotationLockSetting(DEVICE_STATE_HALF_FOLDED) @@ -276,7 +278,6 @@ class DeviceStateAutoRotateSettingManagerImplTest { SettableDeviceState(DEVICE_STATE_ROTATION_KEY_FOLDED, isSettable = true), SettableDeviceState(DEVICE_STATE_ROTATION_KEY_HALF_FOLDED, isSettable = false), SettableDeviceState(DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY, isSettable = false), - SettableDeviceState(DEVICE_STATE_ROTATION_LOCK_IGNORED, isSettable = false), ) } diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateAutoRotateSettingManagerProviderTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateAutoRotateSettingManagerProviderTest.kt new file mode 100644 index 000000000000..c3ec4edfdee5 --- /dev/null +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateAutoRotateSettingManagerProviderTest.kt @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2025 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.settingslib.devicestate + +import android.content.Context +import android.os.Handler +import android.platform.test.annotations.DisableFlags +import android.platform.test.annotations.EnableFlags +import android.platform.test.flag.junit.SetFlagsRule +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.window.flags.Flags +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.Mock +import org.mockito.junit.MockitoJUnit +import java.util.concurrent.Executor +import org.mockito.Mockito.`when` as whenever + +@SmallTest +@RunWith(AndroidJUnit4::class) +class DeviceStateAutoRotateSettingManagerProviderTest { + + @get:Rule + val setFlagsRule: SetFlagsRule = SetFlagsRule() + + @get:Rule val rule = MockitoJUnit.rule() + + private val context: Context = ApplicationProvider.getApplicationContext() + + @Mock + private lateinit var mockExecutor: Executor + + @Mock + private lateinit var mockSecureSettings: SecureSettings + + @Mock + private lateinit var mockMainHandler: Handler + + @Mock + private lateinit var mockPosturesHelper: PosturesHelper + + @Before + fun setup() { + whenever(mockSecureSettings.getStringForUser(any(), anyInt())).thenReturn("") + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_REFACTOR) + fun createInstance_refactorFlagEnabled_returnsRefactoredManager() { + val manager = + DeviceStateAutoRotateSettingManagerProvider.createInstance( + context, mockExecutor, mockSecureSettings, mockMainHandler, mockPosturesHelper + ) + + assertThat(manager).isInstanceOf(DeviceStateAutoRotateSettingManagerImpl::class.java) + } + + @Test + @DisableFlags(Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_REFACTOR) + fun createInstance_refactorFlagDisabled_returnsLegacyManager() { + val manager = + DeviceStateAutoRotateSettingManagerProvider.createInstance( + context, mockExecutor, mockSecureSettings, mockMainHandler, mockPosturesHelper + ) + + assertThat(manager).isInstanceOf(DeviceStateRotationLockSettingsManager::class.java) + } +} diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java index baebaf7dfef0..b23ea5f1786f 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java @@ -151,8 +151,8 @@ public class DeviceStateRotationLockSettingsManagerTest { new String[]{"2:1", "1:0:1", "0:2"}); List<SettableDeviceState> settableDeviceStates = - DeviceStateRotationLockSettingsManager.getInstance( - mMockContext).getSettableDeviceStates(); + new DeviceStateRotationLockSettingsManager(mMockContext, + mFakeSecureSettings).getSettableDeviceStates(); assertThat(settableDeviceStates).containsExactly( new SettableDeviceState(/* deviceState= */ 2, /* isSettable= */ true), diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java index 2273b4f81eea..527a1f16a84f 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java @@ -16,6 +16,8 @@ package com.android.providers.settings; +import static com.android.settingslib.devicestate.DeviceStateAutoRotateSettingUtils.isDeviceStateRotationLockEnabled; + import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; @@ -49,7 +51,6 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.LocalePicker; import com.android.server.backup.Flags; -import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager; import java.io.FileNotFoundException; import java.util.ArrayList; @@ -348,7 +349,7 @@ public class SettingsHelper { private boolean shouldSkipAutoRotateRestore() { // When device state based auto rotation settings are available, let's skip the restoring // of the standard auto rotation settings to avoid conflicting setting values. - return DeviceStateRotationLockSettingsManager.isDeviceStateRotationLockEnabled(mContext); + return isDeviceStateRotationLockEnabled(mContext); } public String onBackupValue(String name, String value) { diff --git a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp index fb1f715bc68f..172f687ef6fd 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp +++ b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp @@ -40,6 +40,7 @@ android_app { "com_android_systemui_flags_lib", "SettingsLibDisplayUtils", "SettingsLibSettingsTheme", + "SystemUI-shared-utils", "com_android_a11y_menu_flags_lib", "//frameworks/libs/systemui:view_capture", ], diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java index a60778658c59..db2fbd96408c 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java +++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java @@ -22,8 +22,6 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.View.ACCESSIBILITY_LIVE_REGION_POLITE; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; -import static com.android.app.viewcapture.ViewCaptureFactory.getViewCaptureAwareWindowManagerInstance; - import static java.lang.Math.max; import android.animation.Animator; @@ -55,11 +53,11 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.UiContext; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService; import com.android.systemui.accessibility.accessibilitymenu.R; import com.android.systemui.accessibility.accessibilitymenu.activity.A11yMenuSettingsActivity.A11yMenuPreferenceFragment; import com.android.systemui.accessibility.accessibilitymenu.model.A11yMenuShortcut; +import com.android.systemui.utils.windowmanager.WindowManagerUtils; import java.util.ArrayList; import java.util.List; @@ -145,9 +143,7 @@ public class A11yMenuOverlayLayout { final Display display = mDisplayManager.getDisplay(DEFAULT_DISPLAY); final Context uiContext = mService.createWindowContext( display, TYPE_ACCESSIBILITY_OVERLAY, /* options= */null); - final ViewCaptureAwareWindowManager windowManager = - getViewCaptureAwareWindowManagerInstance(uiContext, - com.android.systemui.Flags.enableViewCaptureTracing()); + final WindowManager windowManager = WindowManagerUtils.getWindowManager(uiContext); mLayout = new A11yMenuFrameLayout(uiContext); updateLayoutPosition(uiContext); inflateLayoutAndSetOnTouchListener(mLayout, uiContext); @@ -162,8 +158,7 @@ public class A11yMenuOverlayLayout { public void clearLayout() { if (mLayout != null) { - ViewCaptureAwareWindowManager windowManager = getViewCaptureAwareWindowManagerInstance( - mLayout.getContext(), com.android.systemui.Flags.enableViewCaptureTracing()); + WindowManager windowManager = WindowManagerUtils.getWindowManager(mLayout.getContext()); if (windowManager != null) { windowManager.removeView(mLayout); } @@ -178,7 +173,7 @@ public class A11yMenuOverlayLayout { return; } updateLayoutPosition(mLayout.getContext()); - WindowManager windowManager = mLayout.getContext().getSystemService(WindowManager.class); + WindowManager windowManager = WindowManagerUtils.getWindowManager(mLayout.getContext()); if (windowManager != null) { windowManager.updateViewLayout(mLayout, mLayoutParameter); } diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java index b899c45b0f7e..842834b5fc27 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java +++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java @@ -36,6 +36,7 @@ import com.android.systemui.accessibility.accessibilitymenu.R; import com.android.systemui.accessibility.accessibilitymenu.activity.A11yMenuSettingsActivity.A11yMenuPreferenceFragment; import com.android.systemui.accessibility.accessibilitymenu.model.A11yMenuShortcut; import com.android.systemui.accessibility.accessibilitymenu.view.A11yMenuFooter.A11yMenuFooterCallBack; +import com.android.systemui.utils.windowmanager.WindowManagerUtils; import java.util.ArrayList; import java.util.List; @@ -292,8 +293,8 @@ public class A11yMenuViewPager { // Keeps footer window height unchanged no matter the density is changed. mA11yMenuFooter.adjustFooterToDensityScale(densityScale); // Adjust the view pager height for system bar and display cutout insets. - WindowManager windowManager = mA11yMenuLayout.getContext() - .getSystemService(WindowManager.class); + WindowManager windowManager = WindowManagerUtils + .getWindowManager(mA11yMenuLayout.getContext()); WindowMetrics windowMetric = windowManager.getCurrentWindowMetrics(); Insets windowInsets = windowMetric.getWindowInsets().getInsetsIgnoringVisibility( WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout()); diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index 7800a5059092..a696b65deabf 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -2172,3 +2172,10 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "extended_apps_shortcut_category" + namespace: "systemui" + description: "Allow users to add shortcuts to open apps that are not present in the apps category in shortcut helper by default" + bug: "394290928" +} diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt index 1fb7901dcb59..440a81fc2152 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt @@ -1088,9 +1088,8 @@ constructor( if (!success) finishedCallback?.onAnimationFinished() } } else { - // This should never happen, as either the controller or factory should always be - // defined. This final call is for safety in case something goes wrong. - Log.wtf(TAG, "initAndRun with neither a controller nor factory") + // This happens when onDisposed() has already been called due to the animation being + // cancelled. Only issue the callback. finishedCallback?.onAnimationFinished() } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java index aa95abb3528f..0b0088926aae 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java @@ -73,14 +73,10 @@ import android.widget.ImageView; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCapture; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.systemui.SysuiTestCase; import com.android.systemui.res.R; -import kotlin.Lazy; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -108,8 +104,6 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { private SfVsyncFrameCallbackProvider mSfVsyncFrameProvider; @Mock private MagnificationModeSwitch.ClickListener mClickListener; - @Mock - private Lazy<ViewCapture> mLazyViewCapture; private TestableWindowManager mWindowManager; private ViewPropertyAnimator mViewPropertyAnimator; private MagnificationModeSwitch mMagnificationModeSwitch; @@ -123,7 +117,6 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { mContext = Mockito.spy(getContext()); final WindowManager wm = mContext.getSystemService(WindowManager.class); mWindowManager = spy(new TestableWindowManager(wm)); - mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager); mContext.addMockSystemService(Context.ACCESSIBILITY_SERVICE, mAccessibilityManager); mSpyImageView = Mockito.spy(new ImageView(mContext)); mViewPropertyAnimator = Mockito.spy(mSpyImageView.animate()); @@ -139,10 +132,8 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { return null; }).when(mSfVsyncFrameProvider).postFrameCallback( any(Choreographer.FrameCallback.class)); - ViewCaptureAwareWindowManager vwm = new ViewCaptureAwareWindowManager(mWindowManager, - mLazyViewCapture, false); - mMagnificationModeSwitch = new MagnificationModeSwitch(mContext, mSpyImageView, - mSfVsyncFrameProvider, mClickListener, vwm); + mMagnificationModeSwitch = new MagnificationModeSwitch(mContext, mWindowManager, + mSpyImageView, mSfVsyncFrameProvider, mClickListener); assertNotNull(mTouchListener); } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java index 3cd3fefb8ef0..02ec5aac120c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java @@ -23,11 +23,11 @@ import static org.mockito.Mockito.verify; import android.content.pm.ActivityInfo; import android.testing.TestableLooper; +import android.view.WindowManager; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.systemui.SysuiTestCase; import com.android.systemui.accessibility.WindowMagnificationSettings.MagnificationSize; @@ -58,15 +58,15 @@ public class MagnificationSettingsControllerTest extends SysuiTestCase { @Mock private SecureSettings mSecureSettings; @Mock - private ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; + private WindowManager mWindowManager; @Before public void setUp() { MockitoAnnotations.initMocks(this); mMagnificationSettingsController = new MagnificationSettingsController( mContext, mSfVsyncFrameProvider, - mMagnificationSettingControllerCallback, mSecureSettings, - mWindowMagnificationSettings, mViewCaptureAwareWindowManager); + mMagnificationSettingControllerCallback, mSecureSettings, mWindowManager, + mWindowMagnificationSettings); } @After diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MirrorWindowControlTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MirrorWindowControlTest.java index 12c866f0adb2..463bfe5ae73f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MirrorWindowControlTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/MirrorWindowControlTest.java @@ -27,14 +27,15 @@ import static org.mockito.Mockito.verify; import android.content.Context; import android.graphics.Point; +import android.os.Looper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.WindowManager; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.SysuiTestCase; import org.junit.Before; @@ -48,7 +49,7 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public class MirrorWindowControlTest extends SysuiTestCase { - @Mock ViewCaptureAwareWindowManager mWindowManager; + @Mock WindowManager mWindowManager; View mView; int mViewWidth; int mViewHeight; @@ -69,8 +70,12 @@ public class MirrorWindowControlTest extends SysuiTestCase { return null; }).when(mWindowManager).addView(any(View.class), any(LayoutParams.class)); + if (Looper.myLooper() == null) { + Looper.prepare(); + } + mStubMirrorWindowControl = new StubMirrorWindowControl(getContext(), mView, mViewWidth, - mViewHeight); + mViewHeight, mWindowManager); } @Test @@ -122,8 +127,9 @@ public class MirrorWindowControlTest extends SysuiTestCase { boolean mInvokeOnCreateView = false; - StubMirrorWindowControl(Context context, View view, int width, int height) { - super(context); + StubMirrorWindowControl(Context context, View view, int width, int height, + WindowManager windowManager) { + super(context, windowManager); mView = view; mWidth = width; mHeight = height; diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java index e1e515eb31f5..b1c837a99f3d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java @@ -24,11 +24,11 @@ import android.provider.Settings; import android.testing.TestableLooper; import android.view.Display; import android.view.View; +import android.view.WindowManager; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.SysuiTestCase; import org.junit.After; @@ -51,8 +51,6 @@ public class ModeSwitchesControllerTest extends SysuiTestCase { private View mSpyView; @Mock private MagnificationModeSwitch.ClickListener mListener; - @Mock - private ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; @Before @@ -61,8 +59,9 @@ public class ModeSwitchesControllerTest extends SysuiTestCase { mSupplier = new FakeSwitchSupplier(mContext.getSystemService(DisplayManager.class)); mModeSwitchesController = new ModeSwitchesController(mSupplier); mModeSwitchesController.setClickListenerDelegate(mListener); - mModeSwitch = Mockito.spy(new MagnificationModeSwitch(mContext, mModeSwitchesController, - mViewCaptureAwareWindowManager)); + WindowManager wm = mContext.getSystemService(WindowManager.class); + mModeSwitch = Mockito.spy(new MagnificationModeSwitch(mContext, wm, + mModeSwitchesController)); mSpyView = Mockito.spy(new View(mContext)); } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java index 6edf94939010..95ebd8190e9c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java @@ -72,7 +72,7 @@ public class DragToInteractAnimationControllerTest extends SysuiTestCase { stubWindowManager); final MenuView stubMenuView = spy(new MenuView(mContext, stubMenuViewModel, stubMenuViewAppearance, mockSecureSettings)); - mInteractView = spy(new DragToInteractView(mContext)); + mInteractView = spy(new DragToInteractView(mContext, stubWindowManager)); mDismissView = spy(new DismissView(mContext)); if (Flags.floatingMenuDragToEdit()) { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java index fff6def52803..572d140b850d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java @@ -101,7 +101,7 @@ public class MenuListViewTouchHandlerTest extends SysuiTestCase { mStubMenuView.setTranslationY(0); mMenuAnimationController = spy(new MenuAnimationController( mStubMenuView, stubMenuViewAppearance)); - mInteractView = spy(new DragToInteractView(mContext)); + mInteractView = spy(new DragToInteractView(mContext, windowManager)); mDismissView = spy(new DismissView(mContext)); if (Flags.floatingMenuDragToEdit()) { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java index 4f043109a534..b5fa52570d6a 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java @@ -39,15 +39,11 @@ import android.view.accessibility.AccessibilityManager; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCapture; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.settingslib.bluetooth.HearingAidDeviceManager; import com.android.systemui.SysuiTestCase; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.util.settings.SecureSettings; -import kotlin.Lazy; - import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -78,16 +74,11 @@ public class MenuViewLayerControllerTest extends SysuiTestCase { @Mock private WindowMetrics mWindowMetrics; - @Mock - private Lazy<ViewCapture> mLazyViewCapture; - private MenuViewLayerController mMenuViewLayerController; @Before public void setUp() throws Exception { final WindowManager wm = mContext.getSystemService(WindowManager.class); - final ViewCaptureAwareWindowManager viewCaptureAwareWm = new ViewCaptureAwareWindowManager( - mWindowManager, mLazyViewCapture, /* isViewCaptureEnabled= */ false); doAnswer(invocation -> wm.getMaximumWindowMetrics()).when( mWindowManager).getMaximumWindowMetrics(); mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager); @@ -95,8 +86,8 @@ public class MenuViewLayerControllerTest extends SysuiTestCase { when(mWindowMetrics.getBounds()).thenReturn(new Rect(0, 0, 1080, 2340)); when(mWindowMetrics.getWindowInsets()).thenReturn(stubDisplayInsets()); mMenuViewLayerController = new MenuViewLayerController(mContext, mWindowManager, - viewCaptureAwareWm, mAccessibilityManager, mSecureSettings, - mock(NavigationModeController.class), mHearingAidDeviceManager); + mAccessibilityManager, mSecureSettings, mock(NavigationModeController.class), + mHearingAidDeviceManager); } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt index 446891a7873e..c4fafc192260 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt @@ -41,7 +41,6 @@ import android.widget.ScrollView import androidx.constraintlayout.widget.ConstraintLayout import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.app.viewcapture.ViewCapture import com.android.internal.jank.InteractionJankMonitor import com.android.internal.widget.LockPatternUtils import com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN @@ -116,7 +115,6 @@ open class AuthContainerViewTest : SysuiTestCase() { @Mock private lateinit var packageManager: PackageManager @Mock private lateinit var activityTaskManager: ActivityTaskManager @Mock private lateinit var accessibilityManager: AccessibilityManager - @Mock private lateinit var lazyViewCapture: Lazy<ViewCapture> private lateinit var displayRepository: FakeDisplayRepository private lateinit var displayStateInteractor: DisplayStateInteractor @@ -689,7 +687,6 @@ open class AuthContainerViewTest : SysuiTestCase() { { credentialViewModel }, fakeExecutor, vibrator, - lazyViewCapture, msdlPlayer, ) { override fun postOnAnimation(runnable: Runnable) { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java index a1a2aa70d869..f4185ee48510 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java @@ -83,7 +83,6 @@ import android.view.WindowManager; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCapture; import com.android.internal.R; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.widget.LockPatternUtils; @@ -100,11 +99,10 @@ import com.android.systemui.util.concurrency.Execution; import com.android.systemui.util.concurrency.FakeExecution; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import com.google.android.msdl.domain.MSDLPlayer; -import dagger.Lazy; - import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -175,8 +173,6 @@ public class AuthControllerTest extends SysuiTestCase { private PromptViewModel mPromptViewModel; @Mock private UdfpsUtils mUdfpsUtils; - @Mock - private Lazy<ViewCapture> mLazyViewCapture; @Captor private ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mFpAuthenticatorsRegisteredCaptor; @@ -198,6 +194,8 @@ public class AuthControllerTest extends SysuiTestCase { private KeyguardManager mKeyguardManager; @Mock private MSDLPlayer mMSDLPlayer; + @Mock + private WindowManagerProvider mWindowManagerProvider; private TestableContext mContextSpy; private Execution mExecution; @@ -1198,7 +1196,8 @@ public class AuthControllerTest extends SysuiTestCase { when(mDisplayManager.getDisplay(displayId)).thenReturn(mockDisplay); } doReturn(mockDisplayContext).when(mContextSpy).createDisplayContext(mockDisplay); - when(mockDisplayContext.getSystemService(WindowManager.class)).thenReturn(mockDisplayWM); + when(mWindowManagerProvider.getWindowManager(mockDisplayContext)) + .thenReturn(mockDisplayWM); return mockDisplayWM; } @@ -1214,7 +1213,7 @@ public class AuthControllerTest extends SysuiTestCase { () -> mLogContextInteractor, () -> mPromptSelectionInteractor, () -> mCredentialViewModel, () -> mPromptViewModel, mInteractionJankMonitor, mHandler, mBackgroundExecutor, mUdfpsUtils, mVibratorHelper, mKeyguardManager, - mLazyViewCapture, mMSDLPlayer); + mMSDLPlayer, mWindowManagerProvider); } @Override diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index a2f5a30a20ff..675c9deaff23 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -45,12 +45,12 @@ import android.view.LayoutInflater; import android.view.Surface; import android.view.View; import android.view.ViewRootImpl; +import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.logging.InstanceIdSequence; import com.android.internal.util.LatencyTracker; import com.android.keyguard.KeyguardUpdateMonitor; @@ -129,7 +129,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Mock private FingerprintManager mFingerprintManager; @Mock - private ViewCaptureAwareWindowManager mWindowManager; + private WindowManager mWindowManager; @Mock private StatusBarStateController mStatusBarStateController; @Mock diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt index b42eddd12e4e..fd99313a17b7 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt @@ -36,7 +36,6 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry import androidx.test.filters.SmallTest -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.app.viewcapture.ViewCaptureFactory import com.android.compose.animation.scene.ObservableTransitionState import com.android.internal.logging.UiEventLogger @@ -143,7 +142,6 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() { mock<ScrimManager> { on { currentController }.thenReturn(mScrimController) } private val mSystemDialogsCloser = mock<SystemDialogsCloser>() private val mDreamOverlayCallbackController = mock<DreamOverlayCallbackController>() - private val mLazyViewCapture = lazy { viewCaptureSpy } private val mViewCaptor = argumentCaptor<View>() private val mTouchHandlersCaptor = argumentCaptor<Set<TouchHandler>>() @@ -156,7 +154,6 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() { private val gestureInteractor = spy(kosmos.gestureInteractor) private lateinit var mCommunalInteractor: CommunalInteractor - private lateinit var mViewCaptureAwareWindowManager: ViewCaptureAwareWindowManager private lateinit var environmentComponents: EnvironmentComponents private lateinit var mService: DreamOverlayService @@ -244,18 +241,12 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() { mComplicationComponentFactory, mAmbientTouchComponentFactory, ) - mViewCaptureAwareWindowManager = - ViewCaptureAwareWindowManager( - mWindowManager, - mLazyViewCapture, - isViewCaptureEnabled = false, - ) mService = DreamOverlayService( mContext, mLifecycleOwner, mMainExecutor, - mViewCaptureAwareWindowManager, + mWindowManager, mComplicationComponentFactory, mDreamComplicationComponentFactory, mDreamOverlayComponentFactory, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt index 63229dbb47a4..8fdbf9b45d2e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt @@ -229,7 +229,6 @@ class FromAlternateBouncerTransitionInteractorTest(flags: FlagsParameterization) } @Test - @EnableFlags(FLAG_GLANCEABLE_HUB_V2) fun transitionToDreaming() = kosmos.runTest { fakePowerRepository.updateWakefulness( diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt index 55e52b780488..18b14a4b3752 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt @@ -55,8 +55,6 @@ class TaskPreviewSizeProviderTest : SysuiTestCase() { @Before fun setup() { - whenever(mockContext.getSystemService(eq(WindowManager::class.java))) - .thenReturn(windowManager) whenever(mockContext.resources).thenReturn(resources) } @@ -154,7 +152,8 @@ class TaskPreviewSizeProviderTest : SysuiTestCase() { return TaskPreviewSizeProvider( mockContext, windowMetricsProvider, - testConfigurationController + testConfigurationController, + windowManager ) .also { it.addCallback(listener) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java index 09e49eb217b0..0e8c5079579e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java @@ -82,7 +82,6 @@ import android.view.inputmethod.InputMethodManager; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.systemui.SysuiTestCase; @@ -218,8 +217,6 @@ public class NavigationBarTest extends SysuiTestCase { @Mock private WindowManager mWindowManager; @Mock - private ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; - @Mock private TelecomManager mTelecomManager; @Mock private InputMethodManager mInputMethodManager; @@ -685,7 +682,6 @@ public class NavigationBarTest extends SysuiTestCase { null, context, mWindowManager, - mViewCaptureAwareWindowManager, () -> mAssistManager, mock(AccessibilityManager.class), deviceProvisionedController, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/power/PowerUITest.java index 338ed7596bd6..70ded2a7f21c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/power/PowerUITest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/power/PowerUITest.java @@ -40,11 +40,11 @@ import android.service.vr.IVrStateCallbacks; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; import android.testing.TestableResources; +import android.view.WindowManager; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCapture; import com.android.settingslib.fuelgauge.Estimate; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -54,8 +54,6 @@ import com.android.systemui.res.R; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.CommandQueue; -import dagger.Lazy; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -96,7 +94,7 @@ public class PowerUITest extends SysuiTestCase { @Mock private BroadcastDispatcher mBroadcastDispatcher; @Mock private CommandQueue mCommandQueue; @Mock private IVrManager mVrManager; - @Mock private Lazy<ViewCapture> mLazyViewCapture; + @Mock private WindowManager mWindowManager; @Before public void setup() { @@ -709,7 +707,7 @@ public class PowerUITest extends SysuiTestCase { mWakefulnessLifecycle, mPowerManager, mUserTracker, - mLazyViewCapture); + mWindowManager); mPowerUI.mThermalService = mThermalServiceMock; } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java index 94db429c2225..676e1ea5321a 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java @@ -172,6 +172,7 @@ import com.android.systemui.user.domain.interactor.UserSwitcherInteractor; import com.android.systemui.util.kotlin.JavaAdapter; import com.android.systemui.util.time.FakeSystemClock; import com.android.systemui.util.time.SystemClock; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import com.android.systemui.wallpapers.ui.viewmodel.WallpaperFocalAreaViewModel; import com.android.wm.shell.animation.FlingAnimationUtils; @@ -296,6 +297,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { @Mock private LargeScreenHeaderHelper mLargeScreenHeaderHelper; @Mock private StatusBarLongPressGestureDetector mStatusBarLongPressGestureDetector; @Mock protected SysUIStateDisplaysInteractor mSysUIStateDisplaysInteractor; + @Mock private WindowManagerProvider mWindowManagerProvider; protected final int mMaxUdfpsBurnInOffsetY = 5; protected FakeFeatureFlagsClassic mFeatureFlags = new FakeFeatureFlagsClassic(); protected KeyguardClockInteractor mKeyguardClockInteractor; @@ -672,7 +674,8 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { mCastController, new ResourcesSplitShadeStateController(), () -> mKosmos.getCommunalTransitionViewModel(), - () -> mLargeScreenHeaderHelper + () -> mLargeScreenHeaderHelper, + mWindowManagerProvider ); } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java index 3788049256a2..fd17b7a32fd3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java @@ -50,7 +50,6 @@ import android.view.WindowManager; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.colorextraction.ColorExtractor; import com.android.systemui.Flags; import com.android.systemui.SysuiTestCase; @@ -100,7 +99,7 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { @Rule public final CheckFlagsRule checkFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); - @Mock private ViewCaptureAwareWindowManager mWindowManager; + @Mock private WindowManager mWindowManager; @Mock private DozeParameters mDozeParameters; @Spy private final NotificationShadeWindowView mNotificationShadeWindowView = spy( new NotificationShadeWindowView(mContext, null)); diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java index 7433267ab3b0..db0c07c50dc6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java @@ -28,6 +28,7 @@ import android.os.Handler; import android.os.Looper; import android.view.ViewGroup; import android.view.ViewParent; +import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; import com.android.internal.logging.MetricsLogger; @@ -79,6 +80,7 @@ import com.android.systemui.statusbar.policy.data.repository.FakeUserSetupReposi import com.android.systemui.user.domain.interactor.SelectedUserInteractor; import com.android.systemui.user.domain.interactor.UserSwitcherInteractor; import com.android.systemui.util.kotlin.JavaAdapter; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import dagger.Lazy; @@ -147,6 +149,7 @@ public class QuickSettingsControllerImplBaseTest extends SysuiTestCase { @Mock protected UserSwitcherInteractor mUserSwitcherInteractor; @Mock protected SelectedUserInteractor mSelectedUserInteractor; @Mock protected LargeScreenHeaderHelper mLargeScreenHeaderHelper; + @Mock protected WindowManagerProvider mWindowManagerProvider; protected FakeDisableFlagsRepository mDisableFlagsRepository = mKosmos.getFakeDisableFlagsRepository(); @@ -232,6 +235,9 @@ public class QuickSettingsControllerImplBaseTest extends SysuiTestCase { mMainHandler = new Handler(Looper.getMainLooper()); + WindowManager wm = mContext.getSystemService(WindowManager.class); + when(mWindowManagerProvider.getWindowManager(mContext)).thenReturn(wm); + mQsController = new QuickSettingsControllerImpl( mPanelViewControllerLazy, mPanelView, @@ -268,7 +274,8 @@ public class QuickSettingsControllerImplBaseTest extends SysuiTestCase { mCastController, splitShadeStateController, () -> mKosmos.getCommunalTransitionViewModel(), - () -> mLargeScreenHeaderHelper + () -> mLargeScreenHeaderHelper, + mWindowManagerProvider ); mQsController.init(); diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt index 5c749e6e35d6..873357c2201e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt @@ -21,8 +21,9 @@ import android.service.notification.StatusBarNotification import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.kosmos.testScope +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.collectLastValue +import com.android.systemui.kosmos.runTest import com.android.systemui.statusbar.RankingBuilder import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.NotificationEntry @@ -35,7 +36,6 @@ import com.android.systemui.testKosmos import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat -import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith @@ -43,17 +43,14 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class RenderNotificationsListInteractorTest : SysuiTestCase() { private val kosmos = testKosmos() - private val testScope = kosmos.testScope - private val notifsRepository = kosmos.activeNotificationListRepository - private val notifsInteractor = kosmos.activeNotificationsInteractor - private val underTest = - RenderNotificationListInteractor(notifsRepository, sectionStyleProvider = mock(), context) + private val Kosmos.outputInteractor by Kosmos.Fixture { activeNotificationsInteractor } + private val Kosmos.underTest by Kosmos.Fixture { renderNotificationListInteractor } @Test fun setRenderedList_preservesOrdering() = - testScope.runTest { - val notifs by collectLastValue(notifsInteractor.topLevelRepresentativeNotifications) + kosmos.runTest { + val notifs by collectLastValue(outputInteractor.topLevelRepresentativeNotifications) val keys = (1..50).shuffled().map { "$it" } val entries = keys.map { mockNotificationEntry(key = it) } underTest.setRenderedList(entries) @@ -65,8 +62,8 @@ class RenderNotificationsListInteractorTest : SysuiTestCase() { @Test fun setRenderList_flatMapsRankings() = - testScope.runTest { - val ranks by collectLastValue(notifsInteractor.activeNotificationRanks) + kosmos.runTest { + val ranks by collectLastValue(outputInteractor.activeNotificationRanks) val single = mockNotificationEntry("single", 0) val group = @@ -90,8 +87,8 @@ class RenderNotificationsListInteractorTest : SysuiTestCase() { @Test fun setRenderList_singleItems_mapsRankings() = - testScope.runTest { - val actual by collectLastValue(notifsInteractor.activeNotificationRanks) + kosmos.runTest { + val actual by collectLastValue(outputInteractor.activeNotificationRanks) val expected = (0..10).shuffled().mapIndexed { index, value -> "$value" to index }.toMap() @@ -104,8 +101,8 @@ class RenderNotificationsListInteractorTest : SysuiTestCase() { @Test fun setRenderList_groupWithNoSummary_flatMapsRankings() = - testScope.runTest { - val actual by collectLastValue(notifsInteractor.activeNotificationRanks) + kosmos.runTest { + val actual by collectLastValue(outputInteractor.activeNotificationRanks) val expected = (0..10).shuffled().mapIndexed { index, value -> "$value" to index }.toMap() @@ -124,8 +121,8 @@ class RenderNotificationsListInteractorTest : SysuiTestCase() { @Test @EnableFlags(PromotedNotificationUi.FLAG_NAME) fun setRenderList_setsPromotionContent() = - testScope.runTest { - val actual by collectLastValue(notifsInteractor.topLevelRepresentativeNotifications) + kosmos.runTest { + val actual by collectLastValue(outputInteractor.topLevelRepresentativeNotifications) val notPromoted1 = mockNotificationEntry("key1", promotedContent = null) val promoted2 = diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/topwindoweffects/TopLevelWindowEffectsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/topwindoweffects/TopLevelWindowEffectsTest.kt index 6d3813c90bfd..bcc6ea3d3b35 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/topwindoweffects/TopLevelWindowEffectsTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/topwindoweffects/TopLevelWindowEffectsTest.kt @@ -20,8 +20,6 @@ import android.view.View import android.view.WindowManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.app.viewcapture.ViewCapture -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.systemui.SysuiTestCase import com.android.systemui.keyevent.data.repository.fakeKeyEventRepository import com.android.systemui.keyevent.data.repository.keyEventRepository @@ -58,20 +56,13 @@ class TopLevelWindowEffectsTest : SysuiTestCase() { private lateinit var windowManager: WindowManager @Mock - private lateinit var viewCapture: Lazy<ViewCapture> - - @Mock private lateinit var viewModelFactory: SqueezeEffectViewModel.Factory private val Kosmos.underTest by Kosmos.Fixture { TopLevelWindowEffects( context = mContext, applicationScope = testScope.backgroundScope, - windowManager = ViewCaptureAwareWindowManager( - windowManager = windowManager, - lazyViewCapture = viewCapture, - isViewCaptureEnabled = false - ), + windowManager = windowManager, keyEventInteractor = keyEventInteractor, viewModelFactory = viewModelFactory, squeezeEffectInteractor = SqueezeEffectInteractor( diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java index 60a15915fb77..046b5d701ddf 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java @@ -57,6 +57,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.settings.UserTracker; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import org.junit.Before; import org.junit.Test; @@ -89,6 +90,8 @@ public class ImageWallpaperTest extends SysuiTestCase { private Context mMockContext; @Mock private UserTracker mUserTracker; + @Mock + private WindowManagerProvider mWindowManagerProvider; @Mock private Bitmap mWallpaperBitmap; @@ -105,7 +108,7 @@ public class ImageWallpaperTest extends SysuiTestCase { when(mWindowMetrics.getBounds()).thenReturn( new Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT)); when(mWindowManager.getCurrentWindowMetrics()).thenReturn(mWindowMetrics); - when(mMockContext.getSystemService(WindowManager.class)).thenReturn(mWindowManager); + when(mWindowManagerProvider.getWindowManager(any())).thenReturn(mWindowManager); // set up display manager doNothing().when(mDisplayManager).registerDisplayListener(any(), any()); @@ -182,7 +185,7 @@ public class ImageWallpaperTest extends SysuiTestCase { } private ImageWallpaper createImageWallpaper() { - return new ImageWallpaper(mFakeExecutor, mUserTracker) { + return new ImageWallpaper(mFakeExecutor, mUserTracker, mWindowManagerProvider) { @Override public Engine onCreateEngine() { return new CanvasEngine() { diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml index a1fa54cf592d..e094155f9041 100644 --- a/packages/SystemUI/res/layout/volume_dialog.xml +++ b/packages/SystemUI/res/layout/volume_dialog.xml @@ -16,17 +16,18 @@ <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/volume_dialog" - android:layout_width="match_parent" + android:layout_width="wrap_content" android:layout_height="match_parent" android:alpha="0" - android:clipChildren="false"> + android:clipChildren="false" + android:minWidth="@dimen/volume_dialog_window_width"> <View android:id="@+id/volume_dialog_background" android:layout_width="@dimen/volume_dialog_width" android:layout_height="0dp" android:layout_marginTop="@dimen/volume_dialog_background_top_margin" - android:layout_marginBottom="@dimen/volume_dialog_background_vertical_margin" + android:layout_marginBottom="@dimen/volume_dialog_background_margin_negative" android:background="@drawable/volume_dialog_background" app:layout_constraintBottom_toBottomOf="@id/volume_dialog_bottom_section_container" app:layout_constraintEnd_toEndOf="@id/volume_dialog_main_slider_container" diff --git a/packages/SystemUI/res/layout/volume_dialog_slider_floating.xml b/packages/SystemUI/res/layout/volume_dialog_slider_floating.xml index db800aa4a873..1dba96cafb70 100644 --- a/packages/SystemUI/res/layout/volume_dialog_slider_floating.xml +++ b/packages/SystemUI/res/layout/volume_dialog_slider_floating.xml @@ -17,8 +17,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/volume_dialog_floating_slider_background" - android:paddingHorizontal="@dimen/volume_dialog_floating_sliders_horizontal_padding" - android:paddingVertical="@dimen/volume_dialog_floating_sliders_vertical_padding"> + android:paddingHorizontal="@dimen/volume_dialog_floating_sliders_padding" + android:paddingVertical="@dimen/volume_dialog_floating_sliders_padding"> <include layout="@layout/volume_dialog_slider" /> </FrameLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/volume_dialog_top_section.xml b/packages/SystemUI/res/layout/volume_dialog_top_section.xml index b7455471d9a6..9d3598800bbf 100644 --- a/packages/SystemUI/res/layout/volume_dialog_top_section.xml +++ b/packages/SystemUI/res/layout/volume_dialog_top_section.xml @@ -22,15 +22,15 @@ android:clipChildren="false" android:clipToPadding="false" android:gravity="center" - android:paddingEnd="@dimen/volume_dialog_buttons_margin" + android:paddingEnd="@dimen/volume_dialog_background_margin" app:layoutDescription="@xml/volume_dialog_ringer_drawer_motion_scene"> <View android:id="@+id/ringer_buttons_background" android:layout_width="@dimen/volume_dialog_width" android:layout_height="0dp" - android:layout_marginTop="@dimen/volume_dialog_background_vertical_margin" - android:layout_marginBottom="@dimen/volume_dialog_background_vertical_margin" + android:layout_marginTop="@dimen/volume_dialog_background_margin_negative" + android:layout_marginBottom="@dimen/volume_dialog_background_margin_negative" android:background="@drawable/volume_dialog_ringer_background" android:visibility="gone" /> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 7d983068f34e..55e94028b95e 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -2158,28 +2158,25 @@ <dimen name="contextual_edu_dialog_elevation">2dp</dimen> <!-- Volume start --> + <dimen name="volume_dialog_window_width">176dp</dimen> <dimen name="volume_dialog_width">60dp</dimen> <dimen name="volume_dialog_background_corner_radius">30dp</dimen> - <dimen name="volume_dialog_background_vertical_margin"> - @dimen/volume_dialog_buttons_margin_negative - </dimen> <!-- top margin covers half the ringer button + components spacing --> <dimen name="volume_dialog_background_top_margin">-28dp</dimen> + <dimen name="volume_dialog_background_margin">10dp</dimen> + <dimen name="volume_dialog_background_margin_negative">-10dp</dimen> - <dimen name="volume_dialog_window_margin">14dp</dimen> + <dimen name="volume_dialog_window_margin">12dp</dimen> <dimen name="volume_dialog_components_spacing">10dp</dimen> <dimen name="volume_dialog_floating_sliders_spacing">8dp</dimen> - <dimen name="volume_dialog_floating_sliders_vertical_padding">10dp</dimen> <dimen name="volume_dialog_floating_sliders_vertical_padding_negative"> - @dimen/volume_dialog_buttons_margin_negative + @dimen/volume_dialog_background_margin_negative </dimen> - <dimen name="volume_dialog_floating_sliders_horizontal_padding">4dp</dimen> + <dimen name="volume_dialog_floating_sliders_padding">4dp</dimen> <dimen name="volume_dialog_button_size">40dp</dimen> <dimen name="volume_dialog_slider_width">52dp</dimen> <dimen name="volume_dialog_slider_height">254dp</dimen> - <dimen name="volume_dialog_buttons_margin">10dp</dimen> - <dimen name="volume_dialog_buttons_margin_negative">-10dp</dimen> <!-- A primary goal of this margin is to vertically constraint slider height in the landscape orientation when the vertical space is limited @@ -2190,8 +2187,10 @@ <dimen name="volume_dialog_background_square_corner_radius">12dp</dimen> - <dimen name="volume_dialog_ringer_drawer_margin">@dimen/volume_dialog_buttons_margin</dimen> <dimen name="volume_dialog_ringer_drawer_button_size">@dimen/volume_dialog_button_size</dimen> + <dimen name="volume_dialog_ringer_drawer_buttons_spacing"> + @dimen/volume_dialog_components_spacing + </dimen> <dimen name="volume_dialog_ringer_drawer_button_icon_radius">10dp</dimen> <dimen name="volume_dialog_ringer_selected_button_background_radius">20dp</dimen> diff --git a/packages/SystemUI/shared/biometrics/Android.bp b/packages/SystemUI/shared/biometrics/Android.bp index 63de81d4a680..208157c69adf 100644 --- a/packages/SystemUI/shared/biometrics/Android.bp +++ b/packages/SystemUI/shared/biometrics/Android.bp @@ -14,6 +14,9 @@ android_library { "src/**/*.java", "src/**/*.kt", ], + static_libs: [ + "SystemUI-shared-utils", + ], resource_dirs: [ "res", ], diff --git a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/Utils.kt b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/Utils.kt index 5b99a3f16fc2..7aa09cf64405 100644 --- a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/Utils.kt +++ b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/Utils.kt @@ -41,6 +41,7 @@ import com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD import com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN import com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN import com.android.systemui.biometrics.shared.model.PromptKind +import com.android.systemui.utils.windowmanager.WindowManagerUtils object Utils { private const val TAG = "SysUIBiometricUtils" @@ -117,10 +118,9 @@ object Utils { @JvmStatic fun getNavbarInsets(context: Context): Insets { - val windowManager: WindowManager? = context.getSystemService(WindowManager::class.java) - val windowMetrics: WindowMetrics? = windowManager?.maximumWindowMetrics - return windowMetrics?.windowInsets?.getInsets(WindowInsets.Type.navigationBars()) - ?: Insets.NONE + val windowManager: WindowManager = WindowManagerUtils.getWindowManager(context) + val windowMetrics: WindowMetrics = windowManager.maximumWindowMetrics + return windowMetrics.windowInsets.getInsets(WindowInsets.Type.navigationBars()) } /** Converts `drawable` to a [Bitmap]. */ diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java index c82243934b8b..b1fc560f406b 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java @@ -37,6 +37,7 @@ import android.view.Surface; import android.view.WindowManager; import com.android.systemui.shared.recents.model.Task; +import com.android.systemui.utils.windowmanager.WindowManagerUtils; /* Common code */ public class Utilities { @@ -152,7 +153,7 @@ public class Utilities { /** @return whether or not {@param context} represents that of a large screen device or not */ @TargetApi(Build.VERSION_CODES.R) public static boolean isLargeScreen(Context context) { - return isLargeScreen(context.getSystemService(WindowManager.class), context.getResources()); + return isLargeScreen(WindowManagerUtils.getWindowManager(context), context.getResources()); } /** @return whether or not {@param context} represents that of a large screen device or not */ diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java index 4db6ab6ea579..570d774b95e9 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java @@ -16,9 +16,6 @@ package com.android.systemui.shared.rotation; -import static com.android.app.viewcapture.ViewCaptureFactory.getViewCaptureAwareWindowManagerInstance; -import static com.android.systemui.Flags.enableViewCaptureTracing; - import android.annotation.DimenRes; import android.annotation.IdRes; import android.annotation.LayoutRes; @@ -33,6 +30,7 @@ import android.graphics.drawable.Drawable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.FrameLayout; @@ -40,8 +38,8 @@ import android.widget.FrameLayout; import androidx.annotation.BoolRes; import androidx.core.view.OneShotPreDrawListener; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.shared.rotation.FloatingRotationButtonPositionCalculator.Position; +import com.android.systemui.utils.windowmanager.WindowManagerUtils; /** * Containing logic for the rotation button on the physical left bottom corner of the screen. @@ -50,7 +48,7 @@ public class FloatingRotationButton implements RotationButton { private static final int MARGIN_ANIMATION_DURATION_MILLIS = 300; - private final ViewCaptureAwareWindowManager mWindowManager; + private final WindowManager mWindowManager; private final ViewGroup mKeyButtonContainer; private final FloatingRotationButtonView mKeyButtonView; @@ -91,8 +89,7 @@ public class FloatingRotationButton implements RotationButton { @DimenRes int taskbarBottomMargin, @DimenRes int buttonDiameter, @DimenRes int rippleMaxWidth, @BoolRes int floatingRotationBtnPositionLeftResource) { mContext = context; - mWindowManager = getViewCaptureAwareWindowManagerInstance(mContext, - enableViewCaptureTracing()); + mWindowManager = WindowManagerUtils.getWindowManager(mContext); mKeyButtonContainer = (ViewGroup) LayoutInflater.from(mContext).inflate(layout, null); mKeyButtonView = mKeyButtonContainer.findViewById(keyButtonId); mKeyButtonView.setVisibility(View.VISIBLE); diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index 19da5de6b531..59ec6923ce91 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -66,7 +66,6 @@ import android.widget.FrameLayout; import androidx.annotation.VisibleForTesting; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.util.Preconditions; import com.android.settingslib.Utils; import com.android.systemui.biometrics.data.repository.FacePropertyRepository; @@ -167,7 +166,7 @@ public class ScreenDecorations implements ViewGroup mScreenDecorHwcWindow; @VisibleForTesting ScreenDecorHwcLayer mScreenDecorHwcLayer; - private ViewCaptureAwareWindowManager mWindowManager; + private WindowManager mWindowManager; private int mRotation; private UserSettingObserver mColorInversionSetting; private DelayableExecutor mExecutor; @@ -337,7 +336,7 @@ public class ScreenDecorations implements FacePropertyRepository facePropertyRepository, JavaAdapter javaAdapter, CameraProtectionLoader cameraProtectionLoader, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager, + WindowManager windowManager, @ScreenDecorationsThread Handler handler, @ScreenDecorationsThread DelayableExecutor executor) { mContext = context; @@ -353,7 +352,7 @@ public class ScreenDecorations implements mLogger = logger; mFacePropertyRepository = facePropertyRepository; mJavaAdapter = javaAdapter; - mWindowManager = viewCaptureAwareWindowManager; + mWindowManager = windowManager; mHandler = handler; mExecutor = executor; } diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationImpl.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationImpl.java index 115242eb13aa..375137c67f7c 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationImpl.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationImpl.java @@ -44,7 +44,6 @@ import android.window.InputTransferToken; import androidx.annotation.NonNull; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.systemui.dagger.SysUISingleton; @@ -54,6 +53,7 @@ import com.android.systemui.recents.LauncherProxyService; import com.android.systemui.settings.DisplayTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.util.settings.SecureSettings; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import java.io.PrintWriter; import java.util.concurrent.Executor; @@ -97,20 +97,19 @@ public class MagnificationImpl implements Magnification, CommandQueue.Callbacks private final WindowMagnifierCallback mWindowMagnifierCallback; private final SysUiState mSysUiState; private final SecureSettings mSecureSettings; - private final ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; + private final WindowManagerProvider mWindowManagerProvider; WindowMagnificationControllerSupplier(Context context, Handler handler, WindowMagnifierCallback windowMagnifierCallback, DisplayManager displayManager, SysUiState sysUiState, - SecureSettings secureSettings, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + SecureSettings secureSettings, WindowManagerProvider windowManagerProvider) { super(displayManager); mContext = context; mHandler = handler; mWindowMagnifierCallback = windowMagnifierCallback; mSysUiState = sysUiState; mSecureSettings = secureSettings; - mViewCaptureAwareWindowManager = viewCaptureAwareWindowManager; + mWindowManagerProvider = windowManagerProvider; } @Override @@ -118,6 +117,8 @@ public class MagnificationImpl implements Magnification, CommandQueue.Callbacks final Context windowContext = mContext.createWindowContext(display, TYPE_ACCESSIBILITY_OVERLAY, /* options */ null); + final WindowManager windowManager = mWindowManagerProvider + .getWindowManager(windowContext); windowContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI); Supplier<SurfaceControlViewHost> scvhSupplier = () -> @@ -133,7 +134,8 @@ public class MagnificationImpl implements Magnification, CommandQueue.Callbacks mWindowMagnifierCallback, mSysUiState, mSecureSettings, - scvhSupplier); + scvhSupplier, + windowManager); } } @@ -148,17 +150,20 @@ public class MagnificationImpl implements Magnification, CommandQueue.Callbacks private final Executor mExecutor; private final DisplayManager mDisplayManager; private final IWindowManager mIWindowManager; + private final WindowManagerProvider mWindowManagerProvider; FullscreenMagnificationControllerSupplier(Context context, DisplayManager displayManager, Handler handler, - Executor executor, IWindowManager iWindowManager) { + Executor executor, IWindowManager iWindowManager, + WindowManagerProvider windowManagerProvider) { super(displayManager); mContext = context; mHandler = handler; mExecutor = executor; mDisplayManager = displayManager; mIWindowManager = iWindowManager; + mWindowManagerProvider = windowManagerProvider; } @Override @@ -174,7 +179,7 @@ public class MagnificationImpl implements Magnification, CommandQueue.Callbacks mExecutor, mDisplayManager, windowContext.getSystemService(AccessibilityManager.class), - windowContext.getSystemService(WindowManager.class), + mWindowManagerProvider.getWindowManager(windowContext), mIWindowManager, scvhSupplier); } @@ -190,31 +195,32 @@ public class MagnificationImpl implements Magnification, CommandQueue.Callbacks private final Context mContext; private final MagnificationSettingsController.Callback mSettingsControllerCallback; private final SecureSettings mSecureSettings; - private final ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; + private final WindowManagerProvider mWindowManagerProvider; SettingsSupplier(Context context, MagnificationSettingsController.Callback settingsControllerCallback, DisplayManager displayManager, - SecureSettings secureSettings, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + SecureSettings secureSettings, WindowManagerProvider windowManagerProvider) { super(displayManager); mContext = context; mSettingsControllerCallback = settingsControllerCallback; mSecureSettings = secureSettings; - mViewCaptureAwareWindowManager = viewCaptureAwareWindowManager; + mWindowManagerProvider = windowManagerProvider; } @Override protected MagnificationSettingsController createInstance(Display display) { final Context windowContext = mContext.createWindowContext(display, TYPE_ACCESSIBILITY_OVERLAY, /* options */ null); + final WindowManager windowManager = mWindowManagerProvider + .getWindowManager(windowContext); windowContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI); return new MagnificationSettingsController( windowContext, new SfVsyncFrameCallbackProvider(), mSettingsControllerCallback, mSecureSettings, - mViewCaptureAwareWindowManager); + windowManager); } } @@ -229,11 +235,11 @@ public class MagnificationImpl implements Magnification, CommandQueue.Callbacks SecureSettings secureSettings, DisplayTracker displayTracker, DisplayManager displayManager, AccessibilityLogger a11yLogger, IWindowManager iWindowManager, AccessibilityManager accessibilityManager, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + WindowManagerProvider windowManagerProvider) { this(context, mainHandler.getLooper(), executor, commandQueue, modeSwitchesController, sysUiState, launcherProxyService, secureSettings, displayTracker, displayManager, a11yLogger, iWindowManager, accessibilityManager, - viewCaptureAwareWindowManager); + windowManagerProvider); } @VisibleForTesting @@ -244,7 +250,7 @@ public class MagnificationImpl implements Magnification, CommandQueue.Callbacks DisplayManager displayManager, AccessibilityLogger a11yLogger, IWindowManager iWindowManager, AccessibilityManager accessibilityManager, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + WindowManagerProvider windowManagerProvider) { mHandler = new Handler(looper) { @Override public void handleMessage(@NonNull Message msg) { @@ -263,12 +269,13 @@ public class MagnificationImpl implements Magnification, CommandQueue.Callbacks mA11yLogger = a11yLogger; mWindowMagnificationControllerSupplier = new WindowMagnificationControllerSupplier(context, mHandler, mWindowMagnifierCallback, - displayManager, sysUiState, secureSettings, viewCaptureAwareWindowManager); + displayManager, sysUiState, secureSettings, windowManagerProvider); mFullscreenMagnificationControllerSupplier = new FullscreenMagnificationControllerSupplier( - context, displayManager, mHandler, mExecutor, iWindowManager); + context, displayManager, mHandler, mExecutor, iWindowManager, + windowManagerProvider); mMagnificationSettingsSupplier = new SettingsSupplier(context, mMagnificationSettingsControllerCallback, displayManager, secureSettings, - viewCaptureAwareWindowManager); + windowManagerProvider); mModeSwitchesController.setClickListenerDelegate( displayId -> mHandler.post(() -> { diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java index 4723ab958f86..9eb01de239bc 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java @@ -46,7 +46,6 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.widget.ImageView; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.systemui.res.R; @@ -77,7 +76,6 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL private final Context mContext; private final AccessibilityManager mAccessibilityManager; private final WindowManager mWindowManager; - private final ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; private final ImageView mImageView; private final Runnable mWindowInsetChangeRunnable; private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider; @@ -101,21 +99,20 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL void onClick(int displayId); } - MagnificationModeSwitch(@UiContext Context context, ClickListener clickListener, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { - this(context, createView(context), new SfVsyncFrameCallbackProvider(), clickListener, - viewCaptureAwareWindowManager); + MagnificationModeSwitch(@UiContext Context context, WindowManager windowManager, + ClickListener clickListener) { + this(context, windowManager, createView(context), new SfVsyncFrameCallbackProvider(), + clickListener); } @VisibleForTesting - MagnificationModeSwitch(Context context, @NonNull ImageView imageView, - SfVsyncFrameCallbackProvider sfVsyncFrameProvider, ClickListener clickListener, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + MagnificationModeSwitch(Context context, WindowManager windowManager, + @NonNull ImageView imageView, SfVsyncFrameCallbackProvider sfVsyncFrameProvider, + ClickListener clickListener) { mContext = context; mConfiguration = new Configuration(context.getResources().getConfiguration()); mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class); - mWindowManager = mContext.getSystemService(WindowManager.class); - mViewCaptureAwareWindowManager = viewCaptureAwareWindowManager; + mWindowManager = windowManager; mSfVsyncFrameProvider = sfVsyncFrameProvider; mClickListener = clickListener; mParams = createLayoutParams(context); @@ -282,7 +279,7 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL mImageView.animate().cancel(); mIsFadeOutAnimating = false; mImageView.setAlpha(0f); - mViewCaptureAwareWindowManager.removeView(mImageView); + mWindowManager.removeView(mImageView); mContext.unregisterComponentCallbacks(this); mIsVisible = false; } @@ -316,7 +313,7 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL mParams.y = mDraggableWindowBounds.bottom; mToLeftScreenEdge = false; } - mViewCaptureAwareWindowManager.addView(mImageView, mParams); + mWindowManager.addView(mImageView, mParams); // Exclude magnification switch button from system gesture area. setSystemGestureExclusion(); mIsVisible = true; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java index fc7535a712e3..2d5dc8d23383 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java @@ -26,7 +26,6 @@ import android.content.res.Configuration; import android.util.Range; import android.view.WindowManager; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.accessibility.common.MagnificationConstants; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; @@ -62,9 +61,9 @@ public class MagnificationSettingsController implements ComponentCallbacks { SfVsyncFrameCallbackProvider sfVsyncFrameProvider, @NonNull Callback settingsControllerCallback, SecureSettings secureSettings, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { - this(context, sfVsyncFrameProvider, settingsControllerCallback, secureSettings, null, - viewCaptureAwareWindowManager); + WindowManager windowManager) { + this(context, sfVsyncFrameProvider, settingsControllerCallback, secureSettings, + windowManager, null); } @VisibleForTesting @@ -73,8 +72,8 @@ public class MagnificationSettingsController implements ComponentCallbacks { SfVsyncFrameCallbackProvider sfVsyncFrameProvider, @NonNull Callback settingsControllerCallback, SecureSettings secureSettings, - WindowMagnificationSettings windowMagnificationSettings, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + WindowManager windowManager, + WindowMagnificationSettings windowMagnificationSettings) { mContext = context.createWindowContext( context.getDisplay(), WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, @@ -88,7 +87,7 @@ public class MagnificationSettingsController implements ComponentCallbacks { } else { mWindowMagnificationSettings = new WindowMagnificationSettings(mContext, mWindowMagnificationSettingsCallback, - sfVsyncFrameProvider, secureSettings, viewCaptureAwareWindowManager); + sfVsyncFrameProvider, secureSettings, windowManager); } } diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MirrorWindowControl.java b/packages/SystemUI/src/com/android/systemui/accessibility/MirrorWindowControl.java index eb4de6837d41..7f3a869d8222 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/MirrorWindowControl.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/MirrorWindowControl.java @@ -18,9 +18,6 @@ package com.android.systemui.accessibility; import static android.view.WindowManager.LayoutParams; -import static com.android.app.viewcapture.ViewCaptureFactory.getViewCaptureAwareWindowManagerInstance; -import static com.android.systemui.Flags.enableViewCaptureTracing; - import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; @@ -32,8 +29,8 @@ import android.util.MathUtils; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; +import android.view.WindowManager; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.res.R; /** @@ -73,12 +70,11 @@ public abstract class MirrorWindowControl { * @see #setDefaultPosition(LayoutParams) */ private final Point mControlPosition = new Point(); - private final ViewCaptureAwareWindowManager mWindowManager; + private final WindowManager mWindowManager; - MirrorWindowControl(Context context) { + MirrorWindowControl(Context context, WindowManager windowManager) { mContext = context; - mWindowManager = getViewCaptureAwareWindowManagerInstance(mContext, - enableViewCaptureTracing()); + mWindowManager = windowManager; } public void setWindowDelegate(@Nullable MirrorWindowDelegate windowDelegate) { diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/ModeSwitchesController.java b/packages/SystemUI/src/com/android/systemui/accessibility/ModeSwitchesController.java index 53827e65344a..7d9f8674457c 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/ModeSwitchesController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/ModeSwitchesController.java @@ -24,10 +24,11 @@ import android.annotation.MainThread; import android.content.Context; import android.hardware.display.DisplayManager; import android.view.Display; +import android.view.WindowManager; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import javax.inject.Inject; @@ -49,9 +50,9 @@ public class ModeSwitchesController implements ClickListener { @Inject public ModeSwitchesController(Context context, DisplayManager displayManager, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + WindowManagerProvider windowManagerProvider) { mSwitchSupplier = new SwitchSupplier(context, displayManager, this::onClick, - viewCaptureAwareWindowManager); + windowManagerProvider); } @VisibleForTesting @@ -118,7 +119,7 @@ public class ModeSwitchesController implements ClickListener { private final Context mContext; private final ClickListener mClickListener; - private final ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; + private final WindowManagerProvider mWindowManagerProvider; /** * Supplies the switch for the given display. @@ -128,20 +129,20 @@ public class ModeSwitchesController implements ClickListener { * @param clickListener The callback that will run when the switch is clicked */ SwitchSupplier(Context context, DisplayManager displayManager, - ClickListener clickListener, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + ClickListener clickListener, WindowManagerProvider windowManagerProvider) { super(displayManager); mContext = context; mClickListener = clickListener; - mViewCaptureAwareWindowManager = viewCaptureAwareWindowManager; + mWindowManagerProvider = windowManagerProvider; } @Override protected MagnificationModeSwitch createInstance(Display display) { final Context uiContext = mContext.createWindowContext(display, TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, /* options */ null); - return new MagnificationModeSwitch(uiContext, mClickListener, - mViewCaptureAwareWindowManager); + final WindowManager uiWindowManager = mWindowManagerProvider + .getWindowManager(uiContext); + return new MagnificationModeSwitch(uiContext, uiWindowManager, mClickListener); } } } diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SimpleMirrorWindowControl.java b/packages/SystemUI/src/com/android/systemui/accessibility/SimpleMirrorWindowControl.java index bc469eed7359..3cde033bf56a 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/SimpleMirrorWindowControl.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/SimpleMirrorWindowControl.java @@ -27,6 +27,7 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; +import android.view.WindowManager; import com.android.systemui.res.R; @@ -48,8 +49,8 @@ class SimpleMirrorWindowControl extends MirrorWindowControl implements View.OnCl private final PointF mLastDrag = new PointF(); private final Handler mHandler; - SimpleMirrorWindowControl(Context context, Handler handler) { - super(context); + SimpleMirrorWindowControl(Context context, Handler handler, WindowManager windowManager) { + super(context, windowManager); mHandler = handler; final Resources resource = context.getResources(); mMoveFrameAmountShort = resource.getDimensionPixelSize( diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java index 8734d05bc894..9cd77e790e8c 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java @@ -249,7 +249,8 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold @NonNull WindowMagnifierCallback callback, SysUiState sysUiState, SecureSettings secureSettings, - Supplier<SurfaceControlViewHost> scvhSupplier) { + Supplier<SurfaceControlViewHost> scvhSupplier, + WindowManager windowManager) { mContext = context; mHandler = handler; mAnimationController = animationController; @@ -265,7 +266,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold mDisplayId = mContext.getDisplayId(); mRotation = display.getRotation(); - mWm = context.getSystemService(WindowManager.class); + mWm = windowManager; mWindowBounds = new Rect(mWm.getCurrentWindowMetrics().getBounds()); mResources = mContext.getResources(); diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java index 3b6f8f87a1a8..bd4b6420bf37 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java @@ -56,7 +56,6 @@ import android.widget.LinearLayout; import android.widget.SeekBar; import android.widget.Switch; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView; @@ -75,7 +74,6 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest private final Context mContext; private final AccessibilityManager mAccessibilityManager; private final WindowManager mWindowManager; - private final ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; private final SecureSettings mSecureSettings; private final Runnable mWindowInsetChangeRunnable; @@ -137,11 +135,10 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest @VisibleForTesting WindowMagnificationSettings(Context context, WindowMagnificationSettingsCallback callback, SfVsyncFrameCallbackProvider sfVsyncFrameProvider, SecureSettings secureSettings, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + WindowManager windowManager) { mContext = context; mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class); - mWindowManager = mContext.getSystemService(WindowManager.class); - mViewCaptureAwareWindowManager = viewCaptureAwareWindowManager; + mWindowManager = windowManager; mSfVsyncFrameProvider = sfVsyncFrameProvider; mCallback = callback; mSecureSettings = secureSettings; @@ -324,7 +321,7 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest // Unregister observer before removing view mSecureSettings.unregisterContentObserverSync(mMagnificationCapabilityObserver); - mViewCaptureAwareWindowManager.removeView(mSettingView); + mWindowManager.removeView(mSettingView); mIsVisible = false; if (resetPosition) { mParams.x = 0; @@ -382,7 +379,7 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest mParams.y = mDraggableWindowBounds.bottom; } - mViewCaptureAwareWindowManager.addView(mSettingView, mParams); + mWindowManager.addView(mSettingView, mParams); mSecureSettings.registerContentObserverForUserSync( Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY, diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java index f8e4bda15d01..ef42837ba776 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java @@ -31,7 +31,6 @@ import android.view.accessibility.IUserInitializationCompleteCallback; import androidx.annotation.MainThread; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; @@ -60,7 +59,6 @@ public class AccessibilityFloatingMenuController implements private final Context mContext; private final WindowManager mWindowManager; - private final ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; private final DisplayManager mDisplayManager; private final AccessibilityManager mAccessibilityManager; private final HearingAidDeviceManager mHearingAidDeviceManager; @@ -105,7 +103,6 @@ public class AccessibilityFloatingMenuController implements @Inject public AccessibilityFloatingMenuController(Context context, WindowManager windowManager, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager, DisplayManager displayManager, AccessibilityManager accessibilityManager, AccessibilityButtonTargetsObserver accessibilityButtonTargetsObserver, @@ -118,7 +115,6 @@ public class AccessibilityFloatingMenuController implements @Main Handler handler) { mContext = context; mWindowManager = windowManager; - mViewCaptureAwareWindowManager = viewCaptureAwareWindowManager; mDisplayManager = displayManager; mAccessibilityManager = accessibilityManager; mAccessibilityButtonTargetsObserver = accessibilityButtonTargetsObserver; @@ -205,8 +201,8 @@ public class AccessibilityFloatingMenuController implements final Context windowContext = mContext.createWindowContext(defaultDisplay, TYPE_NAVIGATION_BAR_PANEL, /* options= */ null); mFloatingMenu = new MenuViewLayerController(windowContext, mWindowManager, - mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings, - mNavigationModeController, mHearingAidDeviceManager); + mAccessibilityManager, mSecureSettings, mNavigationModeController, + mHearingAidDeviceManager); } mFloatingMenu.show(); diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DragToInteractView.kt b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DragToInteractView.kt index 13c1a450832f..52e69efdbc19 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DragToInteractView.kt +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DragToInteractView.kt @@ -48,7 +48,7 @@ import com.android.wm.shell.shared.bubbles.DismissView * * @note [setup] method should be called after initialisation */ -class DragToInteractView(context: Context) : FrameLayout(context) { +class DragToInteractView(context: Context, windowManager: WindowManager) : FrameLayout(context) { /** * The configuration is used to provide module specific resource ids * @@ -86,8 +86,7 @@ class DragToInteractView(context: Context) : FrameLayout(context) { private val spring = PhysicsAnimator.SpringConfig(STIFFNESS_LOW, DAMPING_RATIO_LOW_BOUNCY) private val INTERACT_SCRIM_FADE_MS = 200L - private var wm: WindowManager = - context.getSystemService(Context.WINDOW_SERVICE) as WindowManager + private var wm: WindowManager = windowManager private var gradientDrawable: GradientDrawable? = null private val GRADIENT_ALPHA: IntProperty<GradientDrawable> = diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java index 81095220b4a6..8fb260c2df36 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java @@ -212,7 +212,7 @@ class MenuViewLayer extends FrameLayout implements mMenuAnimationController = mMenuView.getMenuAnimationController(); mMenuAnimationController.setSpringAnimationsEndAction(this::onSpringAnimationsEndAction); mDismissView = new DismissView(context); - mDragToInteractView = new DragToInteractView(context); + mDragToInteractView = new DragToInteractView(context, windowManager); DismissViewUtils.setup(mDismissView); mDismissView.getCircle().setId(R.id.action_remove_menu); mNotificationFactory = new MenuNotificationFactory(context); diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java index 102efcf7badd..7bf7e23b5df5 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java @@ -25,7 +25,6 @@ import android.graphics.PixelFormat; import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.settingslib.bluetooth.HearingAidDeviceManager; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.util.settings.SecureSettings; @@ -35,16 +34,15 @@ import com.android.systemui.util.settings.SecureSettings; * of {@link IAccessibilityFloatingMenu}. */ class MenuViewLayerController implements IAccessibilityFloatingMenu { - private final ViewCaptureAwareWindowManager mWindowManager; + private final WindowManager mWindowManager; private final MenuViewLayer mMenuViewLayer; private boolean mIsShowing; MenuViewLayerController(Context context, WindowManager windowManager, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager, AccessibilityManager accessibilityManager, SecureSettings secureSettings, NavigationModeController navigationModeController, HearingAidDeviceManager hearingAidDeviceManager) { - mWindowManager = viewCaptureAwareWindowManager; + mWindowManager = windowManager; MenuViewModel menuViewModel = new MenuViewModel( context, accessibilityManager, secureSettings, hearingAidDeviceManager); diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java index f4e2b82f1773..14ce2cf60919 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java @@ -33,7 +33,6 @@ import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import com.android.app.animation.Interpolators; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.res.R; /** @@ -41,17 +40,16 @@ import com.android.systemui.res.R; */ public class AssistDisclosure { private final Context mContext; - private final ViewCaptureAwareWindowManager mWm; + private final WindowManager mWm; private final Handler mHandler; private AssistDisclosureView mView; private boolean mViewAdded; - public AssistDisclosure(Context context, Handler handler, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + public AssistDisclosure(Context context, Handler handler, WindowManager windowManager) { mContext = context; mHandler = handler; - mWm = viewCaptureAwareWindowManager; + mWm = windowManager; } public void postShow() { diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index 2d44d401b0b0..75ec8dfd881e 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -24,8 +24,8 @@ import android.provider.Settings; import android.service.voice.VisualQueryAttentionResult; import android.service.voice.VoiceInteractionSession; import android.util.Log; +import android.view.WindowManager; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.app.AssistUtils; import com.android.internal.app.IVisualQueryDetectionAttentionListener; import com.android.internal.app.IVisualQueryRecognitionStatusListener; @@ -199,12 +199,12 @@ public class AssistManager { SelectedUserInteractor selectedUserInteractor, ActivityManager activityManager, AssistInteractor interactor, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + WindowManager windowManager) { mContext = context; mDeviceProvisionedController = controller; mCommandQueue = commandQueue; mAssistUtils = assistUtils; - mAssistDisclosure = new AssistDisclosure(context, uiHandler, viewCaptureAwareWindowManager); + mAssistDisclosure = new AssistDisclosure(context, uiHandler, windowManager); mLauncherProxyService = launcherProxyService; mPhoneStateMonitor = phoneStateMonitor; mAssistLogger = assistLogger; diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java index 6e257442d139..56273eb9a2cf 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java @@ -33,7 +33,6 @@ import android.view.WindowManager; import android.view.animation.PathInterpolator; import android.widget.FrameLayout; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.assist.AssistLogger; @@ -67,7 +66,7 @@ public class DefaultUiController implements AssistManager.UiController { protected InvocationLightsView mInvocationLightsView; protected final AssistLogger mAssistLogger; - private final ViewCaptureAwareWindowManager mWindowManager; + private final WindowManager mWindowManager; private final MetricsLogger mMetricsLogger; private final Lazy<AssistManager> mAssistManagerLazy; private final WindowManager.LayoutParams mLayoutParams; @@ -81,12 +80,12 @@ public class DefaultUiController implements AssistManager.UiController { @Inject public DefaultUiController(Context context, AssistLogger assistLogger, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager, - MetricsLogger metricsLogger, Lazy<AssistManager> assistManagerLazy, + WindowManager windowManager, MetricsLogger metricsLogger, + Lazy<AssistManager> assistManagerLazy, NavigationBarController navigationBarController) { mAssistLogger = assistLogger; mRoot = new FrameLayout(context); - mWindowManager = viewCaptureAwareWindowManager; + mWindowManager = windowManager; mMetricsLogger = metricsLogger; mAssistManagerLazy = assistManagerLazy; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index b8e95ee1dbf0..7bb08edd4773 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -20,7 +20,6 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static com.android.internal.jank.InteractionJankMonitor.CUJ_BIOMETRIC_PROMPT_TRANSITION; -import static com.android.systemui.Flags.enableViewCaptureTracing; import android.animation.Animator; import android.annotation.IntDef; @@ -57,8 +56,6 @@ import android.window.OnBackInvokedDispatcher; import androidx.constraintlayout.widget.ConstraintLayout; import com.android.app.animation.Interpolators; -import com.android.app.viewcapture.ViewCapture; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.widget.LockPatternUtils; @@ -78,11 +75,10 @@ import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.res.R; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.util.concurrency.DelayableExecutor; +import com.android.systemui.utils.windowmanager.WindowManagerUtils; import com.google.android.msdl.domain.MSDLPlayer; -import kotlin.Lazy; - import kotlinx.coroutines.CoroutineScope; import java.io.PrintWriter; @@ -132,7 +128,7 @@ public class AuthContainerView extends LinearLayout private final Config mConfig; private final int mEffectiveUserId; private final IBinder mWindowToken = new Binder(); - private final ViewCaptureAwareWindowManager mWindowManager; + private final WindowManager mWindowManager; @Nullable private final AuthContextPlugins mAuthContextPlugins; private final Interpolator mLinearOutSlowIn; private final LockPatternUtils mLockPatternUtils; @@ -298,16 +294,13 @@ public class AuthContainerView extends LinearLayout @NonNull Provider<CredentialViewModel> credentialViewModelProvider, @NonNull @Background DelayableExecutor bgExecutor, @NonNull VibratorHelper vibratorHelper, - Lazy<ViewCapture> lazyViewCapture, @NonNull MSDLPlayer msdlPlayer) { super(config.mContext); mConfig = config; mLockPatternUtils = lockPatternUtils; mEffectiveUserId = userManager.getCredentialOwnerProfile(mConfig.mUserId); - WindowManager wm = getContext().getSystemService(WindowManager.class); - mWindowManager = new ViewCaptureAwareWindowManager(wm, lazyViewCapture, - enableViewCaptureTracing()); + mWindowManager = WindowManagerUtils.getWindowManager(getContext()); mAuthContextPlugins = authContextPlugins; mWakefulnessLifecycle = wakefulnessLifecycle; mApplicationCoroutineScope = applicationCoroutineScope; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index 68a282018ba4..f2c071f14466 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -22,7 +22,6 @@ import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR import static android.view.Display.INVALID_DISPLAY; import static com.android.systemui.Flags.contAuthPlugin; -import static com.android.systemui.util.ConvenienceExtensionsKt.toKotlinLazy; import android.annotation.NonNull; import android.annotation.Nullable; @@ -67,7 +66,6 @@ import android.view.DisplayInfo; import android.view.MotionEvent; import android.view.WindowManager; -import com.android.app.viewcapture.ViewCapture; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; @@ -93,6 +91,7 @@ import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.Execution; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import com.google.android.msdl.domain.MSDLPlayer; @@ -194,7 +193,7 @@ public class AuthController implements @NonNull private final VibratorHelper mVibratorHelper; @NonNull private final MSDLPlayer mMSDLPlayer; - private final kotlin.Lazy<ViewCapture> mLazyViewCapture; + private final WindowManagerProvider mWindowManagerProvider; @VisibleForTesting final TaskStackListener mTaskStackListener = new TaskStackListener() { @@ -693,8 +692,8 @@ public class AuthController implements @NonNull UdfpsUtils udfpsUtils, @NonNull VibratorHelper vibratorHelper, @NonNull KeyguardManager keyguardManager, - Lazy<ViewCapture> daggerLazyViewCapture, - @NonNull MSDLPlayer msdlPlayer) { + @NonNull MSDLPlayer msdlPlayer, + WindowManagerProvider windowManagerProvider) { mContext = context; mExecution = execution; mUserManager = userManager; @@ -755,7 +754,7 @@ public class AuthController implements context.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_EXPORTED_UNAUDITED); mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class); - mLazyViewCapture = toKotlinLazy(daggerLazyViewCapture); + mWindowManagerProvider = windowManagerProvider; } // TODO(b/229290039): UDFPS controller should manage its dimensions on its own. Remove this. @@ -1278,7 +1277,7 @@ public class AuthController implements Log.e(TAG, "unable to get Display for user=" + userId); return null; } - return mContext.createDisplayContext(display).getSystemService(WindowManager.class); + return mWindowManagerProvider.getWindowManager(mContext.createDisplayContext(display)); } private void onDialogDismissed(@BiometricPrompt.DismissedReason int reason) { @@ -1337,8 +1336,7 @@ public class AuthController implements return new AuthContainerView(config, mApplicationCoroutineScope, mFpProps, mFaceProps, wakefulnessLifecycle, userManager, mContextPlugins, lockPatternUtils, mInteractionJankMonitor, mPromptSelectorInteractor, viewModel, - mCredentialViewModelProvider, bgExecutor, mVibratorHelper, - mLazyViewCapture, mMSDLPlayer); + mCredentialViewModelProvider, bgExecutor, mVibratorHelper, mMSDLPlayer); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 659d3b46fea9..b16c416fb9df 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -57,12 +57,12 @@ import android.view.HapticFeedbackConstants; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; +import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.InstanceId; @@ -145,7 +145,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { private final Execution mExecution; private final FingerprintManager mFingerprintManager; @NonNull private final LayoutInflater mInflater; - private final ViewCaptureAwareWindowManager mWindowManager; + private final WindowManager mWindowManager; private final DelayableExecutor mFgExecutor; @NonNull private final Executor mBiometricExecutor; @NonNull private final StatusBarStateController mStatusBarStateController; @@ -659,7 +659,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { @NonNull Execution execution, @NonNull @ShadeDisplayAware LayoutInflater inflater, @Nullable FingerprintManager fingerprintManager, - @NonNull ViewCaptureAwareWindowManager viewCaptureAwareWindowManager, + @NonNull @Main WindowManager windowManager, @NonNull StatusBarStateController statusBarStateController, @Main DelayableExecutor fgExecutor, @NonNull StatusBarKeyguardViewManager statusBarKeyguardViewManager, @@ -705,7 +705,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { // The fingerprint manager is queried for UDFPS before this class is constructed, so the // fingerprint manager should never be null. mFingerprintManager = checkNotNull(fingerprintManager); - mWindowManager = viewCaptureAwareWindowManager; + mWindowManager = windowManager; mFgExecutor = fgExecutor; mStatusBarStateController = statusBarStateController; mKeyguardStateController = keyguardStateController; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt index bdf58275effa..61b670715572 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt @@ -42,7 +42,6 @@ import android.view.accessibility.AccessibilityManager import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener import androidx.annotation.VisibleForTesting import com.android.app.tracing.coroutines.launchTraced as launch -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.animation.ActivityTransitionAnimator import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor @@ -88,7 +87,7 @@ class UdfpsControllerOverlay constructor( private val context: Context, private val inflater: LayoutInflater, - private val windowManager: ViewCaptureAwareWindowManager, + private val windowManager: WindowManager, private val accessibilityManager: AccessibilityManager, private val statusBarStateController: StatusBarStateController, private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt index 02c378417f3d..fcc0121e8f93 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt @@ -27,7 +27,6 @@ import android.view.View import android.view.ViewGroup import android.view.ViewOutlineProvider import android.view.WindowInsets -import android.view.WindowManager import android.view.accessibility.AccessibilityManager import android.widget.ImageView import android.widget.TextView @@ -48,6 +47,7 @@ import com.android.systemui.biometrics.ui.viewmodel.isSmall import com.android.systemui.biometrics.ui.viewmodel.isTop import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R +import com.android.systemui.utils.windowmanager.WindowManagerUtils import kotlin.math.abs import kotlinx.coroutines.flow.combine import com.android.app.tracing.coroutines.launchTraced as launch @@ -66,7 +66,7 @@ object BiometricViewSizeBinder { viewsToHideWhenSmall: List<View>, jankListener: BiometricJankListener, ) { - val windowManager = requireNotNull(view.context.getSystemService(WindowManager::class.java)) + val windowManager = WindowManagerUtils.getWindowManager(view.context) val accessibilityManager = requireNotNull(view.context.getSystemService(AccessibilityManager::class.java)) diff --git a/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt index 7d518f4f7e78..718ef51aa161 100644 --- a/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt @@ -23,20 +23,19 @@ import android.os.SystemProperties import android.view.Surface import android.view.View import android.view.WindowManager -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.internal.annotations.VisibleForTesting import com.android.internal.logging.UiEvent import com.android.internal.logging.UiEventLogger import com.android.settingslib.Utils +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags -import com.android.systemui.res.R +import com.android.systemui.surfaceeffects.ripple.RippleView import com.android.systemui.statusbar.commandline.Command import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.ConfigurationController -import com.android.systemui.surfaceeffects.ripple.RippleView import com.android.systemui.util.time.SystemClock import java.io.PrintWriter import javax.inject.Inject @@ -58,7 +57,6 @@ class WiredChargingRippleController @Inject constructor( featureFlags: FeatureFlags, private val context: Context, private val windowManager: WindowManager, - private val viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager, private val systemClock: SystemClock, private val uiEventLogger: UiEventLogger ) { @@ -163,12 +161,12 @@ class WiredChargingRippleController @Inject constructor( override fun onViewAttachedToWindow(view: View) { layoutRipple() rippleView.startRipple(Runnable { - viewCaptureAwareWindowManager.removeView(rippleView) + windowManager.removeView(rippleView) }) rippleView.removeOnAttachStateChangeListener(this) } }) - viewCaptureAwareWindowManager.addView(rippleView, windowLayoutParams) + windowManager.addView(rippleView, windowLayoutParams) uiEventLogger.log(WiredChargingRippleEvent.CHARGING_RIPPLE_PLAYED) } diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java index e5e9c4685264..4ca55400561e 100644 --- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java +++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java @@ -28,10 +28,10 @@ import android.util.Slog; import android.view.Gravity; import android.view.WindowManager; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.systemui.surfaceeffects.ripple.RippleShader.RippleShape; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; /** * A WirelessChargingAnimation is a view containing view + animation for wireless charging. @@ -60,11 +60,11 @@ public class WirelessChargingAnimation { */ private WirelessChargingAnimation(@NonNull Context context, @Nullable Looper looper, int transmittingBatteryLevel, int batteryLevel, Callback callback, boolean isDozing, - RippleShape rippleShape, UiEventLogger uiEventLogger, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + RippleShape rippleShape, UiEventLogger uiEventLogger, WindowManager windowManager, + WindowManagerProvider windowManagerProvider) { mCurrentWirelessChargingView = new WirelessChargingView(context, looper, transmittingBatteryLevel, batteryLevel, callback, isDozing, - rippleShape, uiEventLogger, viewCaptureAwareWindowManager); + rippleShape, uiEventLogger, windowManager, windowManagerProvider); } /** @@ -75,11 +75,11 @@ public class WirelessChargingAnimation { public static WirelessChargingAnimation makeWirelessChargingAnimation(@NonNull Context context, @Nullable Looper looper, int transmittingBatteryLevel, int batteryLevel, Callback callback, boolean isDozing, RippleShape rippleShape, - UiEventLogger uiEventLogger, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + UiEventLogger uiEventLogger, WindowManager windowManager, + WindowManagerProvider windowManagerProvider) { return new WirelessChargingAnimation(context, looper, transmittingBatteryLevel, - batteryLevel, callback, isDozing, rippleShape, uiEventLogger, - viewCaptureAwareWindowManager); + batteryLevel, callback, isDozing, rippleShape, uiEventLogger, windowManager, + windowManagerProvider); } /** @@ -88,10 +88,10 @@ public class WirelessChargingAnimation { */ public static WirelessChargingAnimation makeChargingAnimationWithNoBatteryLevel( @NonNull Context context, RippleShape rippleShape, UiEventLogger uiEventLogger, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + WindowManager windowManager, WindowManagerProvider windowManagerProvider) { return makeWirelessChargingAnimation(context, null, UNKNOWN_BATTERY_LEVEL, UNKNOWN_BATTERY_LEVEL, null, false, - rippleShape, uiEventLogger, viewCaptureAwareWindowManager); + rippleShape, uiEventLogger, windowManager, windowManagerProvider); } /** @@ -123,19 +123,21 @@ public class WirelessChargingAnimation { private int mGravity; private WirelessChargingLayout mView; private WirelessChargingLayout mNextView; - private ViewCaptureAwareWindowManager mWM; + private WindowManager mWM; private Callback mCallback; + private WindowManagerProvider mWindowManagerProvider; public WirelessChargingView(Context context, @Nullable Looper looper, int transmittingBatteryLevel, int batteryLevel, Callback callback, boolean isDozing, RippleShape rippleShape, UiEventLogger uiEventLogger, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + WindowManager windowManager, WindowManagerProvider windowManagerProvider) { mCallback = callback; mNextView = new WirelessChargingLayout(context, transmittingBatteryLevel, batteryLevel, isDozing, rippleShape); mGravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER; mUiEventLogger = uiEventLogger; - mWM = viewCaptureAwareWindowManager; + mWM = windowManager; + mWindowManagerProvider = windowManagerProvider; final WindowManager.LayoutParams params = mParams; params.height = WindowManager.LayoutParams.MATCH_PARENT; @@ -207,6 +209,7 @@ public class WirelessChargingAnimation { if (context == null) { context = mView.getContext(); } + mWM = mWindowManagerProvider.getWindowManager(context); mParams.packageName = packageName; mParams.hideTimeoutMilliseconds = DURATION; diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayWindow.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayWindow.java index dc3b50c93298..059ea3271235 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayWindow.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayWindow.java @@ -27,7 +27,6 @@ import android.view.Window; import android.view.WindowInsets; import android.view.WindowManager; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.policy.PhoneWindow; import com.android.systemui.clipboardoverlay.dagger.ClipboardOverlayModule.OverlayWindowContext; import com.android.systemui.screenshot.FloatingWindowUtil; @@ -45,7 +44,6 @@ public class ClipboardOverlayWindow extends PhoneWindow private final Context mContext; private final WindowManager mWindowManager; - private final ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; private final WindowManager.LayoutParams mWindowLayoutParams; private boolean mKeyboardVisible; @@ -55,7 +53,6 @@ public class ClipboardOverlayWindow extends PhoneWindow @Inject ClipboardOverlayWindow(@OverlayWindowContext Context context, - @OverlayWindowContext ViewCaptureAwareWindowManager viewCaptureAwareWindowManager, @OverlayWindowContext WindowManager windowManager) { super(context); mContext = context; @@ -66,10 +63,9 @@ public class ClipboardOverlayWindow extends PhoneWindow requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS); setBackgroundDrawableResource(android.R.color.transparent); mWindowManager = windowManager; - mViewCaptureAwareWindowManager = viewCaptureAwareWindowManager; mWindowLayoutParams = FloatingWindowUtil.getFloatingWindowParams(); mWindowLayoutParams.setTitle("ClipboardOverlay"); - setWindowManager(windowManager, null, null); + setWindowManager(mWindowManager, null, null); setWindowFocusable(false); } @@ -86,12 +82,10 @@ public class ClipboardOverlayWindow extends PhoneWindow attach(); withWindowAttached(() -> { - WindowInsets currentInsets = mWindowManager.getCurrentWindowMetrics() - .getWindowInsets(); + WindowInsets currentInsets = mWindowManager.getCurrentWindowMetrics().getWindowInsets(); mKeyboardVisible = currentInsets.isVisible(WindowInsets.Type.ime()); peekDecorView().getViewTreeObserver().addOnGlobalLayoutListener(() -> { - WindowInsets insets = mWindowManager.getCurrentWindowMetrics() - .getWindowInsets(); + WindowInsets insets = mWindowManager.getCurrentWindowMetrics().getWindowInsets(); boolean keyboardVisible = insets.isVisible(WindowInsets.Type.ime()); if (keyboardVisible != mKeyboardVisible) { mKeyboardVisible = keyboardVisible; @@ -112,7 +106,7 @@ public class ClipboardOverlayWindow extends PhoneWindow void remove() { final View decorView = peekDecorView(); if (decorView != null && decorView.isAttachedToWindow()) { - mViewCaptureAwareWindowManager.removeViewImmediate(decorView); + mWindowManager.removeViewImmediate(decorView); } } @@ -146,7 +140,7 @@ public class ClipboardOverlayWindow extends PhoneWindow if (decorView.isAttachedToWindow()) { return; } - mViewCaptureAwareWindowManager.addView(decorView, mWindowLayoutParams); + mWindowManager.addView(decorView, mWindowLayoutParams); decorView.requestApplyInsets(); } @@ -167,7 +161,7 @@ public class ClipboardOverlayWindow extends PhoneWindow } final View decorView = peekDecorView(); if (decorView != null && decorView.isAttachedToWindow()) { - mViewCaptureAwareWindowManager.updateViewLayout(decorView, mWindowLayoutParams); + mWindowManager.updateViewLayout(decorView, mWindowLayoutParams); } } } diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java index c86a84b17efe..7a60cce63a33 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java @@ -19,9 +19,7 @@ package com.android.systemui.clipboardoverlay.dagger; import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT; import static com.android.systemui.Flags.clipboardOverlayMultiuser; -import static com.android.systemui.Flags.enableViewCaptureTracing; import static com.android.systemui.shared.Flags.usePreferredImageEditor; -import static com.android.systemui.util.ConvenienceExtensionsKt.toKotlinLazy; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -31,8 +29,6 @@ import android.view.Display; import android.view.LayoutInflater; import android.view.WindowManager; -import com.android.app.viewcapture.ViewCapture; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.clipboardoverlay.ActionIntentCreator; import com.android.systemui.clipboardoverlay.ClipboardOverlayView; import com.android.systemui.clipboardoverlay.DefaultIntentCreator; @@ -40,6 +36,7 @@ import com.android.systemui.clipboardoverlay.IntentCreator; import com.android.systemui.res.R; import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import dagger.Lazy; import dagger.Module; @@ -89,21 +86,9 @@ public interface ClipboardOverlayModule { */ @Provides @OverlayWindowContext - static WindowManager provideWindowManager(@OverlayWindowContext Context context) { - return context.getSystemService(WindowManager.class); - } - - /** - * - */ - @Provides - @OverlayWindowContext - static ViewCaptureAwareWindowManager provideViewCaptureAwareWindowManager( - @OverlayWindowContext WindowManager windowManager, - Lazy<ViewCapture> daggerLazyViewCapture) { - return new ViewCaptureAwareWindowManager(windowManager, - /* lazyViewCapture= */ toKotlinLazy(daggerLazyViewCapture), - /* isViewCaptureEnabled= */ enableViewCaptureTracing()); + static WindowManager provideWindowManager(@OverlayWindowContext Context context, + WindowManagerProvider windowManagerProvider) { + return windowManagerProvider.getWindowManager(context); } @Provides diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java index 7354f4096801..f45bafdfb17e 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java @@ -16,9 +16,6 @@ package com.android.systemui.dagger; -import static com.android.systemui.Flags.enableViewCaptureTracing; -import static com.android.systemui.util.ConvenienceExtensionsKt.toKotlinLazy; - import android.annotation.Nullable; import android.annotation.SuppressLint; import android.app.ActivityManager; @@ -103,7 +100,6 @@ import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.satellite.SatelliteManager; -import android.view.Choreographer; import android.view.CrossWindowBlurListeners; import android.view.IWindowManager; import android.view.LayoutInflater; @@ -115,13 +111,9 @@ import android.view.accessibility.CaptioningManager; import android.view.inputmethod.InputMethodManager; import android.view.textclassifier.TextClassificationManager; -import androidx.annotation.NonNull; import androidx.asynclayoutinflater.view.AsyncLayoutInflater; import androidx.core.app.NotificationManagerCompat; -import com.android.app.viewcapture.ViewCapture; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; -import com.android.app.viewcapture.ViewCaptureFactory; import com.android.internal.app.IBatteryStats; import com.android.internal.appwidget.IAppWidgetService; import com.android.internal.jank.InteractionJankMonitor; @@ -135,8 +127,9 @@ import com.android.systemui.dagger.qualifiers.TestHarness; import com.android.systemui.shared.system.PackageManagerWrapper; import com.android.systemui.user.utils.UserScopedService; import com.android.systemui.user.utils.UserScopedServiceImpl; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; +import com.android.systemui.utils.windowmanager.WindowManagerProviderImpl; -import dagger.Lazy; import dagger.Module; import dagger.Provides; @@ -713,38 +706,23 @@ public class FrameworkServicesModule { @Provides @Singleton - static WindowManager provideWindowManager(Context context) { - return context.getSystemService(WindowManager.class); - } - - /** A window manager working for the default display only. */ - @Provides - @Singleton - @Main - static WindowManager provideMainWindowManager(WindowManager windowManager) { - return windowManager; + static WindowManagerProvider provideWindowManagerProvider() { + return new WindowManagerProviderImpl(); } @Provides @Singleton - static ViewCaptureAwareWindowManager provideViewCaptureAwareWindowManager( - WindowManager windowManager, Lazy<ViewCapture> daggerLazyViewCapture) { - return new ViewCaptureAwareWindowManager(windowManager, - /* lazyViewCapture= */ toKotlinLazy(daggerLazyViewCapture), - /* isViewCaptureEnabled= */ enableViewCaptureTracing()); + static WindowManager provideWindowManager(Context context, + WindowManagerProvider windowManagerProvider) { + return windowManagerProvider.getWindowManager(context); } + /** A window manager working for the default display only. */ @Provides @Singleton - static ViewCaptureAwareWindowManager.Factory viewCaptureAwareWindowManagerFactory( - Lazy<ViewCapture> daggerLazyViewCapture) { - return new ViewCaptureAwareWindowManager.Factory() { - @NonNull - @Override - public ViewCaptureAwareWindowManager create(@NonNull WindowManager windowManager) { - return provideViewCaptureAwareWindowManager(windowManager, daggerLazyViewCapture); - } - }; + @Main + static WindowManager provideMainWindowManager(WindowManager windowManager) { + return windowManager; } @Provides @@ -835,12 +813,6 @@ public class FrameworkServicesModule { @Provides @Singleton - static ViewCapture provideViewCapture(Context context) { - return ViewCaptureFactory.getInstance(context); - } - - @Provides - @Singleton @Nullable static SupervisionManager provideSupervisionManager(Context context) { return (SupervisionManager) context.getSystemService(Context.SUPERVISION_SERVICE); diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt index 3390640fa6c6..aaaaacef001a 100644 --- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt @@ -31,6 +31,7 @@ import com.android.systemui.display.shared.model.DisplayWindowProperties import com.android.systemui.res.R import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround import com.android.systemui.statusbar.core.StatusBarConnectedDisplays +import com.android.systemui.utils.windowmanager.WindowManagerUtils import com.google.common.collect.HashBasedTable import com.google.common.collect.Table import java.io.PrintWriter @@ -110,7 +111,7 @@ constructor( return null } @SuppressLint("NonInjectedService") // Need to manually get the service - val windowManager = context.getSystemService(WindowManager::class.java) as WindowManager + val windowManager = WindowManagerUtils.getWindowManager(context) val layoutInflater = LayoutInflater.from(context) DisplayWindowProperties(displayId, windowType, context, windowManager, layoutInflater) } diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java index a2bcb98e36fe..fd716eea799a 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java @@ -46,7 +46,6 @@ import androidx.lifecycle.LifecycleService; import androidx.lifecycle.ServiceLifecycleDispatcher; import androidx.lifecycle.ViewModelStore; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.compose.animation.scene.OverlayKey; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; @@ -117,7 +116,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ @Nullable private final ComponentName mHomeControlPanelDreamComponent; private final UiEventLogger mUiEventLogger; - private final ViewCaptureAwareWindowManager mWindowManager; + private final WindowManager mWindowManager; private final String mWindowTitle; // A reference to the {@link Window} used to hold the dream overlay. @@ -378,7 +377,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ Context context, DreamOverlayLifecycleOwner lifecycleOwner, @Main DelayableExecutor executor, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager, + WindowManager windowManager, ComplicationComponent.Factory complicationComponentFactory, DreamComplicationComponent.Factory dreamComplicationComponentFactory, DreamOverlayComponent.Factory dreamOverlayComponentFactory, @@ -403,7 +402,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ super(executor); mContext = context; mExecutor = executor; - mWindowManager = viewCaptureAwareWindowManager; + mWindowManager = windowManager; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mScrimManager = scrimManager; mLowLightDreamComponent = lowLightDreamComponent; diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/docking/binder/KeyboardDockingIndicationViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyboard/docking/binder/KeyboardDockingIndicationViewBinder.kt index c2974a8d5429..c08a8e297174 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/docking/binder/KeyboardDockingIndicationViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/docking/binder/KeyboardDockingIndicationViewBinder.kt @@ -20,7 +20,6 @@ import android.content.Context import android.graphics.Paint import android.graphics.PixelFormat import android.view.WindowManager -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyboard.docking.ui.KeyboardDockingIndicationView @@ -38,7 +37,7 @@ constructor( context: Context, @Application private val applicationScope: CoroutineScope, private val viewModel: KeyboardDockingIndicationViewModel, - private val windowManager: ViewCaptureAwareWindowManager, + private val windowManager: WindowManager ) { private val windowLayoutParams = diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt index a3796ab5ee27..cc03e49b462b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt @@ -145,7 +145,7 @@ constructor( KeyguardState.GLANCEABLE_HUB } else if (isOccluded && !isDreaming) { KeyguardState.OCCLUDED - } else if (hubV2 && isDreaming) { + } else if (isDreaming) { KeyguardState.DREAMING } else if (hubV2 && isIdleOnCommunal) { if (SceneContainerFlag.isEnabled) return@collect diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/SideFpsProgressBar.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/SideFpsProgressBar.kt index 1fd609dba637..853f1769994e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/SideFpsProgressBar.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/SideFpsProgressBar.kt @@ -26,7 +26,6 @@ import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.WindowManager import android.widget.ProgressBar import androidx.core.view.isGone -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.systemui.dagger.SysUISingleton import com.android.systemui.res.R import javax.inject.Inject @@ -38,7 +37,7 @@ class SideFpsProgressBar @Inject constructor( private val layoutInflater: LayoutInflater, - private val windowManager: ViewCaptureAwareWindowManager, + private val windowManager: WindowManager, ) { private var overlayView: View? = null @@ -91,7 +90,7 @@ constructor( ) { if (overlayView == null) { overlayView = layoutInflater.inflate(R.layout.sidefps_progress_bar, null, false) - windowManager.addView(requireNotNull(overlayView), overlayViewParams) + windowManager.addView(overlayView, overlayViewParams) progressBar?.pivotX = 0.0f progressBar?.pivotY = 0.0f } diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt index 2a23620839e5..6a2c4519e1a5 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt @@ -35,7 +35,6 @@ import android.view.ViewGroup import android.view.WindowManager import android.view.accessibility.AccessibilityManager import com.android.app.animation.Interpolators -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.internal.logging.InstanceId import com.android.internal.widget.CachingIconView import com.android.systemui.common.shared.model.ContentDescription @@ -73,7 +72,7 @@ constructor( private val commandQueue: CommandQueue, context: Context, logger: MediaTttReceiverLogger, - viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager, + windowManager: WindowManager, @Main private val mainExecutor: DelayableExecutor, accessibilityManager: AccessibilityManager, configurationController: ConfigurationController, @@ -90,7 +89,7 @@ constructor( TemporaryViewDisplayController<ChipReceiverInfo, MediaTttReceiverLogger>( context, logger, - viewCaptureAwareWindowManager, + windowManager, mainExecutor, accessibilityManager, configurationController, diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionTaskView.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionTaskView.kt index 9265bfb2f66b..5ffa7fa0ef8d 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionTaskView.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionTaskView.kt @@ -26,13 +26,13 @@ import android.graphics.Shader import android.util.AttributeSet import android.view.View import android.view.WindowManager -import androidx.core.content.getSystemService import androidx.core.content.res.use import com.android.systemui.res.R import com.android.systemui.mediaprojection.appselector.data.RecentTask import com.android.systemui.shared.recents.model.ThumbnailData import com.android.systemui.shared.recents.utilities.PreviewPositionHelper import com.android.systemui.shared.recents.utilities.Utilities.isLargeScreen +import com.android.systemui.utils.windowmanager.WindowManagerUtils /** * Custom view that shows a thumbnail preview of one recent task based on [ThumbnailData]. @@ -53,7 +53,7 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 } } - private val windowManager: WindowManager = context.getSystemService()!! + private val windowManager: WindowManager = WindowManagerUtils.getWindowManager(context) private val paint = Paint(Paint.ANTI_ALIAS_FLAG) private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = defaultBackgroundColor } diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProvider.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProvider.kt index c829471f53f3..57fd1e790f0b 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProvider.kt @@ -19,6 +19,7 @@ package com.android.systemui.mediaprojection.appselector.view import android.content.Context import android.content.res.Configuration import android.graphics.Rect +import android.view.WindowManager import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorScope @@ -36,6 +37,7 @@ constructor( private val context: Context, private val windowMetricsProvider: WindowMetricsProvider, private val configurationController: ConfigurationController, + private val windowManager: WindowManager, ) : CallbackController<TaskPreviewSizeListener>, ConfigurationListener, DefaultLifecycleObserver { /** Returns the size of the task preview on the screen in pixels */ @@ -65,7 +67,7 @@ constructor( val width = maxWindowBounds.width() var height = maximumWindowHeight - val isLargeScreen = isLargeScreen(context) + val isLargeScreen = isLargeScreen(windowManager, context.resources) if (isLargeScreen) { val taskbarSize = windowMetricsProvider.currentWindowInsets.bottom height -= taskbarSize diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java index 39482bea0111..c5c8c01f8b39 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java @@ -16,17 +16,12 @@ package com.android.systemui.navigationbar; -import static com.android.systemui.Flags.enableViewCaptureTracing; -import static com.android.systemui.util.ConvenienceExtensionsKt.toKotlinLazy; - import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import com.android.app.displaylib.PerDisplayRepository; -import com.android.app.viewcapture.ViewCapture; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.dagger.qualifiers.DisplayId; import com.android.systemui.model.SysUiState; import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope; @@ -34,8 +29,8 @@ import com.android.systemui.navigationbar.views.NavigationBarFrame; import com.android.systemui.navigationbar.views.NavigationBarView; import com.android.systemui.res.R; import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; -import dagger.Lazy; import dagger.Module; import dagger.Provides; @@ -70,8 +65,9 @@ public interface NavigationBarModule { @Provides @NavigationBarScope @DisplayId - static WindowManager provideWindowManager(@DisplayId Context context) { - return context.getSystemService(WindowManager.class); + static WindowManager provideWindowManager(@DisplayId Context context, + WindowManagerProvider windowManagerProvider) { + return windowManagerProvider.getWindowManager(context); } /** A SysUiState for the navigation bar display. */ @@ -87,15 +83,4 @@ public interface NavigationBarModule { return defaultState; } } - - /** A ViewCaptureAwareWindowManager specific to the display's context. */ - @Provides - @NavigationBarScope - @DisplayId - static ViewCaptureAwareWindowManager provideViewCaptureAwareWindowManager( - @DisplayId WindowManager windowManager, Lazy<ViewCapture> daggerLazyViewCapture) { - return new ViewCaptureAwareWindowManager(windowManager, - /* lazyViewCapture= */ toKotlinLazy(daggerLazyViewCapture), - /* isViewCaptureEnabled= */ enableViewCaptureTracing()); - } } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt index 44c828731e24..6d7492686985 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt @@ -33,7 +33,6 @@ import androidx.annotation.VisibleForTesting import androidx.core.os.postDelayed import androidx.core.view.isVisible import androidx.dynamicanimation.animation.DynamicAnimation -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.internal.jank.Cuj import com.android.internal.jank.InteractionJankMonitor import com.android.internal.util.LatencyTracker @@ -85,7 +84,7 @@ class BackPanelController @AssistedInject constructor( @Assisted context: Context, - private val windowManager: ViewCaptureAwareWindowManager, + private val windowManager: WindowManager, private val viewConfiguration: ViewConfiguration, @Assisted private val mainHandler: Handler, private val systemClock: SystemClock, diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java index 8b5b3adeef1f..ad0acbdaf702 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java @@ -104,7 +104,6 @@ import android.view.inputmethod.InputMethodManager; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; @@ -199,7 +198,6 @@ public class NavigationBar extends ViewController<NavigationBarView> implements private final Context mContext; private final Bundle mSavedState; private final WindowManager mWindowManager; - private final ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; private final AccessibilityManager mAccessibilityManager; private final DeviceProvisionedController mDeviceProvisionedController; private final StatusBarStateController mStatusBarStateController; @@ -560,7 +558,6 @@ public class NavigationBar extends ViewController<NavigationBarView> implements @Nullable Bundle savedState, @DisplayId Context context, @DisplayId WindowManager windowManager, - @DisplayId ViewCaptureAwareWindowManager viewCaptureAwareWindowManager, Lazy<AssistManager> assistManagerLazy, AccessibilityManager accessibilityManager, DeviceProvisionedController deviceProvisionedController, @@ -605,7 +602,6 @@ public class NavigationBar extends ViewController<NavigationBarView> implements mContext = context; mSavedState = savedState; mWindowManager = windowManager; - mViewCaptureAwareWindowManager = viewCaptureAwareWindowManager; mAccessibilityManager = accessibilityManager; mDeviceProvisionedController = deviceProvisionedController; mStatusBarStateController = statusBarStateController; @@ -726,7 +722,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mView); try { - mViewCaptureAwareWindowManager.addView( + mWindowManager.addView( mFrame, getBarLayoutParams( mContext.getResources() @@ -783,7 +779,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements mCommandQueue.removeCallback(this); Trace.beginSection("NavigationBar#removeViewImmediate"); try { - mViewCaptureAwareWindowManager.removeViewImmediate(mView.getRootView()); + mWindowManager.removeViewImmediate(mView.getRootView()); } catch (IllegalArgumentException e) { // Wrapping this in a try/catch to avoid crashes when a display is instantly removed // after being added, and initialization hasn't finished yet. @@ -888,7 +884,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements resetSecondaryHandle(); getBarTransitions().removeDarkIntensityListener(mOrientationHandleIntensityListener); try { - mViewCaptureAwareWindowManager.removeView(mOrientationHandle); + mWindowManager.removeView(mOrientationHandle); } catch (IllegalArgumentException e) { // Wrapping this in a try/catch to avoid crashes when a display is instantly removed // after being added, and initialization hasn't finished yet. @@ -967,7 +963,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements mOrientationParams.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT; try { - mViewCaptureAwareWindowManager.addView(mOrientationHandle, mOrientationParams); + mWindowManager.addView(mOrientationHandle, mOrientationParams); } catch (WindowManager.InvalidDisplayException e) { // Wrapping this in a try/catch to avoid crashes when a display is instantly removed // after being added, and initialization hasn't finished yet. diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java index cbc4c26b2f94..d2974e9f90bd 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java @@ -87,6 +87,7 @@ import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.LightBarTransitionsController; +import com.android.systemui.utils.windowmanager.WindowManagerUtils; import com.android.wm.shell.back.BackAnimation; import com.android.wm.shell.pip.Pip; @@ -729,7 +730,7 @@ public class NavigationBarView extends FrameLayout { } else { return; } - WindowManager wm = getContext().getSystemService(WindowManager.class); + WindowManager wm = WindowManagerUtils.getWindowManager(getContext()); wm.updateViewLayout((View) getParent(), lp); } } diff --git a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java index 2ecca2d8c776..f37a86e2b9d5 100644 --- a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java +++ b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java @@ -16,8 +16,6 @@ package com.android.systemui.power; -import static com.android.systemui.Flags.enableViewCaptureTracing; - import android.animation.Animator; import android.animation.AnimatorInflater; import android.animation.AnimatorListenerAdapter; @@ -30,28 +28,21 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.FrameLayout; - -import com.android.app.viewcapture.ViewCapture; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.res.R; -import kotlin.Lazy; - /** * View that shows a warning shortly before the device goes into sleep * after prolonged user inactivity when bound to. */ public class InattentiveSleepWarningView extends FrameLayout { private final IBinder mWindowToken = new Binder(); - private final ViewCaptureAwareWindowManager mWindowManager; + private final WindowManager mWindowManager; private Animator mFadeOutAnimator; private boolean mDismissing; - InattentiveSleepWarningView(Context context, Lazy<ViewCapture> lazyViewCapture) { + InattentiveSleepWarningView(Context context, WindowManager windowManager) { super(context); - WindowManager wm = mContext.getSystemService(WindowManager.class); - mWindowManager = new ViewCaptureAwareWindowManager(wm, lazyViewCapture, - enableViewCaptureTracing()); + mWindowManager = windowManager; final LayoutInflater layoutInflater = LayoutInflater.from(mContext); layoutInflater.inflate(R.layout.inattentive_sleep_warning, this, true /* attachToRoot */); diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java index 861a7ce282af..4e1bfd15e58c 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java @@ -16,8 +16,6 @@ package com.android.systemui.power; -import static com.android.systemui.util.ConvenienceExtensionsKt.toKotlinLazy; - import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -42,11 +40,11 @@ import android.service.vr.IVrStateCallbacks; import android.text.format.DateUtils; import android.util.Log; import android.util.Slog; +import android.view.WindowManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.app.viewcapture.ViewCapture; import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.fuelgauge.Estimate; import com.android.settingslib.utils.ThreadUtils; @@ -59,8 +57,6 @@ import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.policy.ConfigurationController; -import kotlin.Lazy; - import java.io.PrintWriter; import java.util.Arrays; import java.util.concurrent.Future; @@ -120,9 +116,9 @@ public class PowerUI implements private IThermalEventListener mSkinThermalEventListener; private IThermalEventListener mUsbThermalEventListener; private final Context mContext; + private final WindowManager mWindowManager; private final BroadcastDispatcher mBroadcastDispatcher; private final CommandQueue mCommandQueue; - private final Lazy<ViewCapture> mLazyViewCapture; @Nullable private final IVrManager mVrManager; private final WakefulnessLifecycle.Observer mWakefulnessObserver = @@ -164,7 +160,7 @@ public class PowerUI implements WakefulnessLifecycle wakefulnessLifecycle, PowerManager powerManager, UserTracker userTracker, - dagger.Lazy<ViewCapture> daggerLazyViewCapture) { + WindowManager windowManager) { mContext = context; mBroadcastDispatcher = broadcastDispatcher; mCommandQueue = commandQueue; @@ -174,7 +170,7 @@ public class PowerUI implements mPowerManager = powerManager; mWakefulnessLifecycle = wakefulnessLifecycle; mUserTracker = userTracker; - mLazyViewCapture = toKotlinLazy(daggerLazyViewCapture); + mWindowManager = windowManager; } public void start() { @@ -649,7 +645,7 @@ public class PowerUI implements @Override public void showInattentiveSleepWarning() { if (mOverlayView == null) { - mOverlayView = new InattentiveSleepWarningView(mContext, mLazyViewCapture); + mOverlayView = new InattentiveSleepWarningView(mContext, mWindowManager); } mOverlayView.show(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java index 6b5a22a4fc09..945e051606b9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java @@ -65,7 +65,6 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.annotation.WorkerThread; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.logging.UiEventLogger; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; @@ -186,7 +185,7 @@ public class InternetDetailsContentController implements AccessPointController.A private GlobalSettings mGlobalSettings; private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; private ConnectivityManager.NetworkCallback mConnectivityManagerNetworkCallback; - private ViewCaptureAwareWindowManager mWindowManager; + private WindowManager mWindowManager; private ToastFactory mToastFactory; private SignalDrawable mSignalDrawable; private SignalDrawable mSecondarySignalDrawable; // For the secondary mobile data sub in DSDS @@ -252,7 +251,7 @@ public class InternetDetailsContentController implements AccessPointController.A @Main Handler handler, @Main Executor mainExecutor, BroadcastDispatcher broadcastDispatcher, KeyguardUpdateMonitor keyguardUpdateMonitor, GlobalSettings globalSettings, KeyguardStateController keyguardStateController, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager, ToastFactory toastFactory, + @ShadeDisplayAware WindowManager windowManager, ToastFactory toastFactory, @Background Handler workerHandler, CarrierConfigTracker carrierConfigTracker, LocationController locationController, @@ -284,7 +283,7 @@ public class InternetDetailsContentController implements AccessPointController.A mAccessPointController = accessPointController; mWifiIconInjector = new WifiUtils.InternetIconInjector(mContext); mConnectivityManagerNetworkCallback = new DataConnectivityListener(); - mWindowManager = viewCaptureAwareWindowManager; + mWindowManager = windowManager; mToastFactory = toastFactory; mSignalDrawable = new SignalDrawable(mContext); mSecondarySignalDrawable = new SignalDrawable(mContext); diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java index 432a35a1a3dd..a1281ec23f92 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java +++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java @@ -16,9 +16,7 @@ package com.android.systemui.recents; -import static com.android.systemui.Flags.enableViewCaptureTracing; import static com.android.systemui.shared.recents.utilities.Utilities.isLargeScreen; -import static com.android.systemui.util.ConvenienceExtensionsKt.toKotlinLazy; import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE; import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE; import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE; @@ -55,8 +53,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; -import com.android.app.viewcapture.ViewCapture; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.CoreStartable; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; @@ -87,7 +83,6 @@ public class ScreenPinningRequest implements private final Lazy<NavigationBarController> mNavigationBarControllerLazy; private final AccessibilityManager mAccessibilityService; private final WindowManager mWindowManager; - private final ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; private final BroadcastDispatcher mBroadcastDispatcher; private final UserTracker mUserTracker; @@ -112,15 +107,12 @@ public class ScreenPinningRequest implements Lazy<NavigationBarController> navigationBarControllerLazy, BroadcastDispatcher broadcastDispatcher, UserTracker userTracker, - Lazy<ViewCapture> daggerLazyViewCapture) { + WindowManager windowManager) { mContext = context; mNavigationBarControllerLazy = navigationBarControllerLazy; mAccessibilityService = (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); - mWindowManager = (WindowManager) - mContext.getSystemService(Context.WINDOW_SERVICE); - mViewCaptureAwareWindowManager = new ViewCaptureAwareWindowManager(mWindowManager, - toKotlinLazy(daggerLazyViewCapture), enableViewCaptureTracing()); + mWindowManager = windowManager; mNavBarMode = navigationModeController.addListener(this); mBroadcastDispatcher = broadcastDispatcher; mUserTracker = userTracker; @@ -131,7 +123,7 @@ public class ScreenPinningRequest implements public void clearPrompt() { if (mRequestWindow != null) { - mViewCaptureAwareWindowManager.removeView(mRequestWindow); + mWindowManager.removeView(mRequestWindow); mRequestWindow = null; } } @@ -152,7 +144,7 @@ public class ScreenPinningRequest implements // show the confirmation WindowManager.LayoutParams lp = getWindowLayoutParams(); - mViewCaptureAwareWindowManager.addView(mRequestWindow, lp); + mWindowManager.addView(mRequestWindow, lp); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotWindow.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotWindow.kt index c4fe7a428084..644e12cba6fc 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotWindow.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotWindow.kt @@ -31,7 +31,6 @@ import android.view.Window import android.view.WindowInsets import android.view.WindowManager import android.window.WindowContext -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.internal.policy.PhoneWindow import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -42,7 +41,6 @@ class ScreenshotWindow @AssistedInject constructor( private val windowManager: WindowManager, - private val viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager, private val context: Context, @Assisted private val display: Display, ) { @@ -97,7 +95,7 @@ constructor( Log.d(TAG, "attachWindow") } attachRequested = true - viewCaptureAwareWindowManager.addView(decorView, params) + windowManager.addView(decorView, params) decorView.requestApplyInsets() decorView.requireViewById<ViewGroup>(R.id.content).apply { @@ -135,7 +133,7 @@ constructor( if (LogConfig.DEBUG_WINDOW) { Log.d(TAG, "Removing screenshot window") } - viewCaptureAwareWindowManager.removeViewImmediate(decorView) + windowManager.removeViewImmediate(decorView) detachRequested = false } if (attachRequested && !detachRequested) { diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java index c671f7d9db14..4ad4ab3410d6 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java @@ -102,6 +102,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.SplitShadeStateController; import com.android.systemui.util.LargeScreenUtils; import com.android.systemui.util.kotlin.JavaAdapter; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import dalvik.annotation.optimization.NeverCompile; @@ -299,6 +300,8 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum private final Runnable mQsCollapseExpandAction = this::collapseOrExpandQs; private final QS.ScrollListener mQsScrollListener = this::onScroll; + private final WindowManagerProvider mWindowManagerProvider; + @Inject public QuickSettingsControllerImpl( Lazy<NotificationPanelViewController> panelViewControllerLazy, @@ -336,7 +339,8 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum CastController castController, SplitShadeStateController splitShadeStateController, Lazy<CommunalTransitionViewModel> communalTransitionViewModelLazy, - Lazy<LargeScreenHeaderHelper> largeScreenHeaderHelperLazy + Lazy<LargeScreenHeaderHelper> largeScreenHeaderHelperLazy, + WindowManagerProvider windowManagerProvider ) { SceneContainerFlag.assertInLegacyMode(); mPanelViewControllerLazy = panelViewControllerLazy; @@ -387,6 +391,8 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum mLockscreenShadeTransitionController.addCallback(new LockscreenShadeTransitionCallback()); dumpManager.registerDumpable(this); + + mWindowManagerProvider = windowManagerProvider; } @VisibleForTesting @@ -532,7 +538,7 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum * on ACTION_DOWN, and safely queried repeatedly thereafter during ACTION_MOVE events. */ void updateGestureInsetsCache() { - WindowManager wm = this.mPanelView.getContext().getSystemService(WindowManager.class); + WindowManager wm = mWindowManagerProvider.getWindowManager(this.mPanelView.getContext()); WindowMetrics windowMetrics = wm.getCurrentWindowMetrics(); mCachedGestureInsets = windowMetrics.getWindowInsets().getInsets( WindowInsets.Type.systemGestures()); diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt index cd224735cc62..446d4b450edc 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt @@ -49,6 +49,8 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackRebind import com.android.systemui.statusbar.phone.ConfigurationControllerImpl import com.android.systemui.statusbar.phone.ConfigurationForwarder import com.android.systemui.statusbar.policy.ConfigurationController +import com.android.systemui.utils.windowmanager.WindowManagerProvider +import com.android.systemui.utils.windowmanager.WindowManagerUtils import dagger.Module import dagger.Provides import dagger.multibindings.ClassKey @@ -111,9 +113,10 @@ object ShadeDisplayAwareModule { fun provideShadeWindowManager( defaultWindowManager: WindowManager, @ShadeDisplayAware context: Context, + windowManagerProvider: WindowManagerProvider ): WindowManager { return if (ShadeWindowGoesAround.isEnabled) { - context.getSystemService(WindowManager::class.java) as WindowManager + windowManagerProvider.getWindowManager(context) } else { defaultWindowManager } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java b/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java index 97e62d79b374..2a9a47d83dd4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java @@ -28,9 +28,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED; import static android.window.DisplayAreaOrganizer.KEY_ROOT_DISPLAY_AREA_ID; -import static com.android.systemui.Flags.enableViewCaptureTracing; -import static com.android.systemui.util.ConvenienceExtensionsKt.toKotlinLazy; - import android.animation.ArgbEvaluator; import android.animation.ValueAnimator; import android.annotation.NonNull; @@ -76,16 +73,13 @@ import android.widget.Button; import android.widget.FrameLayout; import android.widget.RelativeLayout; -import com.android.app.viewcapture.ViewCapture; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.CoreStartable; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.res.R; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.systemui.util.settings.SecureSettings; - -import kotlin.Lazy; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import javax.inject.Inject; @@ -112,13 +106,14 @@ public class ImmersiveModeConfirmation implements CoreStartable, CommandQueue.Ca private long mShowDelayMs = 0L; private final IBinder mWindowToken = new Binder(); private final CommandQueue mCommandQueue; + private final WindowManagerProvider mWindowManagerProvider; private ClingWindowView mClingWindow; /** The wrapper on the last {@link WindowManager} used to add the confirmation window. */ @Nullable - private ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; + private WindowManager mWindowManager; /** - * The WindowContext that is registered with {@link #mViewCaptureAwareWindowManager} with + * The WindowContext that is registered with {@link #mWindowManager} with * options to specify the {@link RootDisplayArea} to attach the confirmation window. */ @Nullable @@ -136,21 +131,18 @@ public class ImmersiveModeConfirmation implements CoreStartable, CommandQueue.Ca private ContentObserver mContentObserver; - private Lazy<ViewCapture> mLazyViewCapture; - @Inject public ImmersiveModeConfirmation(Context context, CommandQueue commandQueue, - SecureSettings secureSettings, - dagger.Lazy<ViewCapture> daggerLazyViewCapture, - @Background Handler backgroundHandler) { + SecureSettings secureSettings, @Background Handler backgroundHandler, + WindowManagerProvider windowManagerProvider) { mSysUiContext = context; final Display display = mSysUiContext.getDisplay(); mDisplayContext = display.getDisplayId() == DEFAULT_DISPLAY ? mSysUiContext : mSysUiContext.createDisplayContext(display); mCommandQueue = commandQueue; mSecureSettings = secureSettings; - mLazyViewCapture = toKotlinLazy(daggerLazyViewCapture); mBackgroundHandler = backgroundHandler; + mWindowManagerProvider = windowManagerProvider; } boolean loadSetting(int currentUserId) { @@ -257,14 +249,14 @@ public class ImmersiveModeConfirmation implements CoreStartable, CommandQueue.Ca private void handleHide() { if (mClingWindow != null) { if (DEBUG) Log.d(TAG, "Hiding immersive mode confirmation"); - if (mViewCaptureAwareWindowManager != null) { + if (mWindowManager != null) { try { - mViewCaptureAwareWindowManager.removeView(mClingWindow); + mWindowManager.removeView(mClingWindow); } catch (WindowManager.InvalidDisplayException e) { Log.w(TAG, "Fail to hide the immersive confirmation window because of " + e); } - mViewCaptureAwareWindowManager = null; + mWindowManager = null; mWindowContext = null; } mClingWindow = null; @@ -525,8 +517,8 @@ public class ImmersiveModeConfirmation implements CoreStartable, CommandQueue.Ca * confirmation window. */ @NonNull - private ViewCaptureAwareWindowManager createWindowManager(int rootDisplayAreaId) { - if (mViewCaptureAwareWindowManager != null) { + private WindowManager createWindowManager(int rootDisplayAreaId) { + if (mWindowManager != null) { throw new IllegalStateException( "Must not create a new WindowManager while there is an existing one"); } @@ -535,10 +527,8 @@ public class ImmersiveModeConfirmation implements CoreStartable, CommandQueue.Ca mWindowContextRootDisplayAreaId = rootDisplayAreaId; mWindowContext = mDisplayContext.createWindowContext( IMMERSIVE_MODE_CONFIRMATION_WINDOW_TYPE, options); - WindowManager wm = mWindowContext.getSystemService(WindowManager.class); - mViewCaptureAwareWindowManager = new ViewCaptureAwareWindowManager(wm, mLazyViewCapture, - enableViewCaptureTracing()); - return mViewCaptureAwareWindowManager; + mWindowManager = mWindowManagerProvider.getWindowManager(mWindowContext); + return mWindowManager; } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java index ef0660fbcd1c..3d7d08910502 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java @@ -79,6 +79,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.systemui.res.R; import com.android.systemui.statusbar.phone.CentralSurfaces; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetDialog; @@ -148,43 +149,44 @@ public final class KeyboardShortcutListSearch { private KeyCharacterMap mBackupKeyCharacterMap; @VisibleForTesting - KeyboardShortcutListSearch(Context context, WindowManager windowManager, int deviceId) { + KeyboardShortcutListSearch(Context context, @NonNull WindowManager windowManager, + int deviceId) { this.mContext = new ContextThemeWrapper( context, R.style.KeyboardShortcutHelper); this.mPackageManager = AppGlobals.getPackageManager(); - if (windowManager != null) { - this.mWindowManager = windowManager; - } else { - this.mWindowManager = mContext.getSystemService(WindowManager.class); - } + this.mWindowManager = windowManager; loadResources(this.mContext); createHardcodedShortcuts(deviceId); } - private static KeyboardShortcutListSearch getInstance(Context context, int deviceId) { + private static KeyboardShortcutListSearch getInstance(Context context, int deviceId, + WindowManagerProvider windowManagerProvider) { if (sInstance == null) { - sInstance = new KeyboardShortcutListSearch(context, null, deviceId); + WindowManager windowManager = windowManagerProvider.getWindowManager(context); + sInstance = new KeyboardShortcutListSearch(context, windowManager, deviceId); } return sInstance; } - public static void show(Context context, int deviceId) { + public static void show(Context context, int deviceId, + WindowManagerProvider windowManagerProvider) { MetricsLogger.visible(context, MetricsProto.MetricsEvent.KEYBOARD_SHORTCUTS_HELPER); synchronized (sLock) { if (sInstance != null && !sInstance.mContext.equals(context)) { dismiss(); } - getInstance(context, deviceId).showKeyboardShortcuts(deviceId); + getInstance(context, deviceId, windowManagerProvider).showKeyboardShortcuts(deviceId); } } - public static void toggle(Context context, int deviceId) { + public static void toggle(Context context, int deviceId, + WindowManagerProvider windowManagerProvider) { synchronized (sLock) { if (isShowing()) { dismiss(); } else { - show(context, deviceId); + show(context, deviceId, windowManagerProvider); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java index 2157d754ce87..bd6006c8faa6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java @@ -70,6 +70,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.settingslib.Utils; import com.android.systemui.res.R; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import java.util.ArrayList; import java.util.Collections; @@ -141,38 +142,38 @@ public final class KeyboardShortcuts { this.mContext = new ContextThemeWrapper( context, android.R.style.Theme_DeviceDefault_Settings); this.mPackageManager = AppGlobals.getPackageManager(); - if (windowManager != null) { - this.mWindowManager = windowManager; - } else { - this.mWindowManager = mContext.getSystemService(WindowManager.class); - } + this.mWindowManager = windowManager; loadResources(context); } - private static KeyboardShortcuts getInstance(Context context) { + private static KeyboardShortcuts getInstance(Context context, + WindowManagerProvider windowManagerProvider) { if (sInstance == null) { - sInstance = new KeyboardShortcuts(context, null); + WindowManager windowManager = windowManagerProvider.getWindowManager(context); + sInstance = new KeyboardShortcuts(context, windowManager); } return sInstance; } - public static void show(Context context, int deviceId) { + public static void show(Context context, int deviceId, + WindowManagerProvider windowManagerProvider) { MetricsLogger.visible(context, MetricsProto.MetricsEvent.KEYBOARD_SHORTCUTS_HELPER); synchronized (sLock) { if (sInstance != null && !sInstance.mContext.equals(context)) { dismiss(); } - getInstance(context).showKeyboardShortcuts(deviceId); + getInstance(context, windowManagerProvider).showKeyboardShortcuts(deviceId); } } - public static void toggle(Context context, int deviceId) { + public static void toggle(Context context, int deviceId, + WindowManagerProvider windowManagerProvider) { synchronized (sLock) { if (isShowing()) { dismiss(); } else { - show(context, deviceId); + show(context, deviceId, windowManagerProvider); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutsReceiver.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutsReceiver.java index 815f1fcfdec6..54c84aa139cc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutsReceiver.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutsReceiver.java @@ -24,6 +24,7 @@ import android.content.Intent; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.shared.recents.utilities.Utilities; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import javax.inject.Inject; @@ -31,10 +32,13 @@ import javax.inject.Inject; public class KeyboardShortcutsReceiver extends BroadcastReceiver { private final FeatureFlags mFeatureFlags; + private final WindowManagerProvider mWindowManagerProvider; @Inject - public KeyboardShortcutsReceiver(FeatureFlags featureFlags) { + public KeyboardShortcutsReceiver(FeatureFlags featureFlags, + WindowManagerProvider windowManagerProvider) { mFeatureFlags = featureFlags; + mWindowManagerProvider = windowManagerProvider; } @Override @@ -44,13 +48,14 @@ public class KeyboardShortcutsReceiver extends BroadcastReceiver { } if (isTabletLayoutFlagEnabled() && Utilities.isLargeScreen(context)) { if (Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(intent.getAction())) { - KeyboardShortcutListSearch.show(context, -1 /* deviceId unknown */); + KeyboardShortcutListSearch.show(context, -1 /* deviceId unknown */, + mWindowManagerProvider); } else if (Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(intent.getAction())) { KeyboardShortcutListSearch.dismiss(); } } else { if (Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(intent.getAction())) { - KeyboardShortcuts.show(context, -1 /* deviceId unknown */); + KeyboardShortcuts.show(context, -1 /* deviceId unknown */, mWindowManagerProvider); } else if (Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(intent.getAction())) { KeyboardShortcuts.dismiss(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt index 7fc5e8abe904..587d80fc3848 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt @@ -18,7 +18,6 @@ package com.android.systemui.statusbar.data.repository import android.view.Display import android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background @@ -48,7 +47,6 @@ constructor( private val windowControllerFactory: PrivacyDotWindowController.Factory, private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository, private val privacyDotViewControllerStore: PrivacyDotViewControllerStore, - private val viewCaptureAwareWindowManagerFactory: ViewCaptureAwareWindowManager.Factory, ) : PrivacyDotWindowControllerStore, StatusBarPerDisplayStoreImpl<PrivacyDotWindowController>( @@ -72,8 +70,7 @@ constructor( return windowControllerFactory.create( displayId = displayId, privacyDotViewController = privacyDotViewController, - viewCaptureAwareWindowManager = - viewCaptureAwareWindowManagerFactory.create(displayWindowProperties.windowManager), + windowManager = displayWindowProperties.windowManager, inflater = displayWindowProperties.layoutInflater, ) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotWindowController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotWindowController.kt index e2bcfb752e6c..7999ca9fd3e9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotWindowController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotWindowController.kt @@ -24,10 +24,10 @@ import android.view.DisplayCutout.BOUNDS_POSITION_RIGHT import android.view.DisplayCutout.BOUNDS_POSITION_TOP import android.view.LayoutInflater import android.view.View +import android.view.WindowManager import android.view.WindowManager.InvalidDisplayException import android.view.WindowManager.LayoutParams.WRAP_CONTENT import android.widget.FrameLayout -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.systemui.ScreenDecorations import com.android.systemui.ScreenDecorationsThread import com.android.systemui.decor.DecorProvider @@ -54,7 +54,7 @@ class PrivacyDotWindowController constructor( @Assisted private val displayId: Int, @Assisted private val privacyDotViewController: PrivacyDotViewController, - @Assisted private val viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager, + @Assisted private val windowManager: WindowManager, @Assisted private val inflater: LayoutInflater, @ScreenDecorationsThread private val uiExecutor: Executor, private val dotFactory: PrivacyDotDecorProviderFactory, @@ -106,7 +106,7 @@ constructor( try { // Wrapping this in a try/catch to avoid crashes when a display is instantly removed // after being added, and initialization hasn't finished yet. - viewCaptureAwareWindowManager.addView(rootView, params) + windowManager.addView(rootView, params) } catch (e: InvalidDisplayException) { Log.e( TAG, @@ -118,7 +118,7 @@ constructor( } fun stop() { - dotViews.forEach { viewCaptureAwareWindowManager.removeView(it) } + dotViews.forEach { windowManager.removeView(it) } } @AssistedFactory @@ -126,7 +126,7 @@ constructor( fun create( displayId: Int, privacyDotViewController: PrivacyDotViewController, - viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager, + windowManager: WindowManager, inflater: LayoutInflater, ): PrivacyDotWindowController } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index e617254fa288..fe367a3927ed 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -90,7 +90,6 @@ import androidx.annotation.NonNull; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleRegistry; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.logging.MetricsLogger; @@ -233,6 +232,7 @@ import com.android.systemui.util.WallpaperController; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.MessageRouter; import com.android.systemui.util.kotlin.JavaAdapter; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import com.android.systemui.volume.VolumeComponent; import com.android.systemui.wallet.controller.QuickAccessWalletController; import com.android.wm.shell.bubbles.Bubbles; @@ -597,7 +597,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { private final EmergencyGestureIntentFactory mEmergencyGestureIntentFactory; - private final ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; private final QuickAccessWalletController mWalletController; /** @@ -713,8 +712,9 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { BrightnessMirrorShowingRepository brightnessMirrorShowingRepository, GlanceableHubContainerController glanceableHubContainerController, EmergencyGestureIntentFactory emergencyGestureIntentFactory, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager, - QuickAccessWalletController walletController + QuickAccessWalletController walletController, + WindowManager windowManager, + WindowManagerProvider windowManagerProvider ) { mContext = context; mNotificationsController = notificationsController; @@ -852,7 +852,8 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mLightRevealScrim = lightRevealScrim; - mViewCaptureAwareWindowManager = viewCaptureAwareWindowManager; + mWindowManager = windowManager; + mWindowManagerProvider = windowManagerProvider; } private void initBubbles(Bubbles bubbles) { @@ -880,8 +881,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mColorExtractor.addOnColorsChangedListener(mOnColorsChangedListener); - mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); - mDisplay = mContext.getDisplay(); mDisplayId = mDisplay.getDisplayId(); updateDisplaySize(); @@ -1716,7 +1715,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mNotificationShadeWindowController.setRequestTopUi(false, TAG); } }, /* isDozing= */ false, RippleShape.CIRCLE, - sUiEventLogger, mViewCaptureAwareWindowManager).show(animationDelay); + sUiEventLogger, mWindowManager, mWindowManagerProvider).show(animationDelay); } @Override @@ -2876,6 +2875,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { protected WindowManager mWindowManager; protected IWindowManager mWindowManagerService; private final IDreamManager mDreamManager; + private final WindowManagerProvider mWindowManagerProvider; protected Display mDisplay; private int mDisplayId; @@ -2912,9 +2912,9 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { protected void toggleKeyboardShortcuts(int deviceId) { if (shouldUseTabletKeyboardShortcuts()) { - KeyboardShortcutListSearch.toggle(mContext, deviceId); + KeyboardShortcutListSearch.toggle(mContext, deviceId, mWindowManagerProvider); } else { - KeyboardShortcuts.toggle(mContext, deviceId); + KeyboardShortcuts.toggle(mContext, deviceId, mWindowManagerProvider); } } @@ -2928,7 +2928,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { private boolean shouldUseTabletKeyboardShortcuts() { return mFeatureFlags.isEnabled(SHORTCUT_LIST_SEARCH_LAYOUT) - && Utilities.isLargeScreen(mContext); + && Utilities.isLargeScreen(mWindowManager, mContext.getResources()); } private void clearNotificationEffects() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt index caf8a43b2aaf..67a7eee2977a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt @@ -104,6 +104,7 @@ private constructor( // intercepted. See [View.OnTouchEvent] if (event.source == InputDevice.SOURCE_MOUSE) { if (event.action == MotionEvent.ACTION_UP) { + dispatchEventToShadeDisplayPolicy(event) v.performClick() shadeController.animateExpandShade() } @@ -113,6 +114,15 @@ private constructor( } } + private fun dispatchEventToShadeDisplayPolicy(event: MotionEvent) { + if (ShadeWindowGoesAround.isEnabled) { + // Notify the shade display policy that the status bar was touched. This may cause + // the shade to change display if the touch was in a display different than the shade + // one. + lazyStatusBarShadeDisplayPolicy.get().onStatusBarTouched(event, mView.width) + } + } + private val configurationListener = object : ConfigurationController.ConfigurationListener { override fun onDensityOrFontScaleChanged() { @@ -232,9 +242,6 @@ private constructor( !upOrCancel || shadeController.isExpandedVisible, ) } - if (ShadeWindowGoesAround.isEnabled && event.action == MotionEvent.ACTION_DOWN) { - lazyStatusBarShadeDisplayPolicy.get().onStatusBarTouched(event, mView.width) - } } private fun addDarkReceivers() { @@ -249,6 +256,9 @@ private constructor( inner class PhoneStatusBarViewTouchHandler : Gefingerpoken { override fun onInterceptTouchEvent(event: MotionEvent): Boolean { + if (event.action == MotionEvent.ACTION_DOWN) { + dispatchEventToShadeDisplayPolicy(event) + } return if (Flags.statusBarSwipeOverChip()) { shadeViewController.handleExternalInterceptTouch(event) } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingController.java index fa022b4768fc..0f8d534df659 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingController.java @@ -28,7 +28,6 @@ import android.util.IndentingPrintWriter; import androidx.annotation.NonNull; import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManager; -import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager; import com.android.systemui.Dumpable; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; @@ -49,7 +48,7 @@ public final class DeviceStateRotationLockSettingController private final RotationPolicyWrapper mRotationPolicyWrapper; private final DeviceStateManager mDeviceStateManager; private final Executor mMainExecutor; - private final DeviceStateRotationLockSettingsManager mDeviceStateRotationLockSettingsManager; + private final DeviceStateAutoRotateSettingManager mDeviceStateAutoRotateSettingManager; private final DeviceStateRotationLockSettingControllerLogger mLogger; // On registration for DeviceStateCallback, we will receive a callback with the current state @@ -65,13 +64,13 @@ public final class DeviceStateRotationLockSettingController RotationPolicyWrapper rotationPolicyWrapper, DeviceStateManager deviceStateManager, @Main Executor executor, - DeviceStateRotationLockSettingsManager deviceStateRotationLockSettingsManager, + DeviceStateAutoRotateSettingManager deviceStateAutoRotateSettingManager, DeviceStateRotationLockSettingControllerLogger logger, DumpManager dumpManager) { mRotationPolicyWrapper = rotationPolicyWrapper; mDeviceStateManager = deviceStateManager; mMainExecutor = executor; - mDeviceStateRotationLockSettingsManager = deviceStateRotationLockSettingsManager; + mDeviceStateAutoRotateSettingManager = deviceStateAutoRotateSettingManager; mLogger = logger; dumpManager.registerDumpable(this); } @@ -86,14 +85,14 @@ public final class DeviceStateRotationLockSettingController mDeviceStateManager.registerCallback(mMainExecutor, mDeviceStateCallback); mDeviceStateAutoRotateSettingListener = () -> readPersistedSetting("deviceStateRotationLockChange", mDeviceState); - mDeviceStateRotationLockSettingsManager.registerListener( + mDeviceStateAutoRotateSettingManager.registerListener( mDeviceStateAutoRotateSettingListener); } else { if (mDeviceStateCallback != null) { mDeviceStateManager.unregisterCallback(mDeviceStateCallback); } if (mDeviceStateAutoRotateSettingListener != null) { - mDeviceStateRotationLockSettingsManager.unregisterListener( + mDeviceStateAutoRotateSettingManager.unregisterListener( mDeviceStateAutoRotateSettingListener); } } @@ -102,7 +101,7 @@ public final class DeviceStateRotationLockSettingController @Override public void onRotationLockStateChanged(boolean newRotationLocked, boolean affordanceVisible) { int deviceState = mDeviceState; - boolean currentRotationLocked = mDeviceStateRotationLockSettingsManager + boolean currentRotationLocked = mDeviceStateAutoRotateSettingManager .isRotationLocked(deviceState); mLogger.logRotationLockStateChanged(deviceState, newRotationLocked, currentRotationLocked); if (deviceState == -1) { @@ -117,7 +116,7 @@ public final class DeviceStateRotationLockSettingController private void saveNewRotationLockSetting(boolean isRotationLocked) { int deviceState = mDeviceState; mLogger.logSaveNewRotationLockSetting(isRotationLocked, deviceState); - mDeviceStateRotationLockSettingsManager.updateSetting(deviceState, isRotationLocked); + mDeviceStateAutoRotateSettingManager.updateSetting(deviceState, isRotationLocked); } private void updateDeviceState(@NonNull DeviceState state) { @@ -139,7 +138,7 @@ public final class DeviceStateRotationLockSettingController private void readPersistedSetting(String caller, int state) { int rotationLockSetting = - mDeviceStateRotationLockSettingsManager.getRotationLockSetting(state); + mDeviceStateAutoRotateSettingManager.getRotationLockSetting(state); boolean shouldBeLocked = rotationLockSetting == DEVICE_STATE_ROTATION_LOCK_LOCKED; boolean isLocked = mRotationPolicyWrapper.isRotationLocked(); @@ -167,7 +166,7 @@ public final class DeviceStateRotationLockSettingController @Override public void dump(@NonNull PrintWriter printWriter, @NonNull String[] args) { IndentingPrintWriter pw = new IndentingPrintWriter(printWriter); - mDeviceStateRotationLockSettingsManager.dump(pw); + mDeviceStateAutoRotateSettingManager.dump(printWriter, null); pw.println("DeviceStateRotationLockSettingController"); pw.increaseIndent(); pw.println("mDeviceState: " + mDeviceState); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java index d1e807f18196..e2a6c195af38 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java @@ -18,13 +18,20 @@ package com.android.systemui.statusbar.policy.dagger; import android.content.Context; import android.content.res.Resources; +import android.hardware.devicestate.DeviceStateManager; +import android.os.Handler; import android.os.UserManager; import com.android.internal.R; -import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager; +import com.android.settingslib.devicestate.AndroidSecureSettings; +import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManager; +import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManagerProvider; +import com.android.settingslib.devicestate.PosturesHelper; +import com.android.settingslib.devicestate.SecureSettings; import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Application; +import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.log.LogBuffer; @@ -222,12 +229,34 @@ public interface StatusBarPolicyModule { return controller; } - /** Returns a singleton instance of DeviceStateRotationLockSettingsManager */ + /** */ + @SysUISingleton + @Provides + static SecureSettings provideAndroidSecureSettings(Context context) { + return new AndroidSecureSettings(context.getContentResolver()); + } + + /** */ @SysUISingleton @Provides - static DeviceStateRotationLockSettingsManager provideAutoRotateSettingsManager( - Context context) { - return DeviceStateRotationLockSettingsManager.getInstance(context); + static PosturesHelper providePosturesHelper(Context context, + DeviceStateManager deviceStateManager) { + return new PosturesHelper(context, deviceStateManager); + } + + /** Returns a singleton instance of DeviceStateAutoRotateSettingManager based on auto-rotate + * refactor flag. */ + @SysUISingleton + @Provides + static DeviceStateAutoRotateSettingManager provideAutoRotateSettingsManager( + Context context, + @Background Executor bgExecutor, + SecureSettings secureSettings, + @Main Handler mainHandler, + PosturesHelper posturesHelper + ) { + return DeviceStateAutoRotateSettingManagerProvider.createInstance(context, bgExecutor, + secureSettings, mainHandler, posturesHelper); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.kt index ecfcb29a9944..eae310ed169b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.kt @@ -19,7 +19,7 @@ package com.android.systemui.statusbar.window import android.content.Context import android.view.View import android.view.ViewGroup -import com.android.app.viewcapture.ViewCaptureAwareWindowManager +import android.view.WindowManager import com.android.systemui.animation.ActivityTransitionAnimator import com.android.systemui.fragments.FragmentHostManager import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController @@ -84,7 +84,7 @@ interface StatusBarWindowController { fun interface Factory { fun create( context: Context, - viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager, + windowManager: WindowManager, statusBarConfigurationController: StatusBarConfigurationController, contentInsetsProvider: StatusBarContentInsetsProvider, ): StatusBarWindowController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java index 25972ac2bedf..77cd58111b94 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java @@ -47,7 +47,6 @@ import android.view.WindowManager; import androidx.annotation.NonNull; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.policy.SystemBarUtils; import com.android.systemui.animation.ActivityTransitionAnimator; import com.android.systemui.animation.DelegateTransitionAnimatorController; @@ -78,7 +77,7 @@ public class StatusBarWindowControllerImpl implements StatusBarWindowController private static final boolean DEBUG = false; private final Context mContext; - private final ViewCaptureAwareWindowManager mWindowManager; + private final WindowManager mWindowManager; private final StatusBarConfigurationController mStatusBarConfigurationController; private final IWindowManager mIWindowManager; private final StatusBarContentInsetsProvider mContentInsetsProvider; @@ -100,7 +99,7 @@ public class StatusBarWindowControllerImpl implements StatusBarWindowController public StatusBarWindowControllerImpl( @Assisted Context context, @InternalWindowViewInflater StatusBarWindowViewInflater statusBarWindowViewInflater, - @Assisted ViewCaptureAwareWindowManager viewCaptureAwareWindowManager, + @Assisted WindowManager windowManager, @Assisted StatusBarConfigurationController statusBarConfigurationController, IWindowManager iWindowManager, @Assisted StatusBarContentInsetsProvider contentInsetsProvider, @@ -108,7 +107,7 @@ public class StatusBarWindowControllerImpl implements StatusBarWindowController Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider, @Main Executor mainExecutor) { mContext = context; - mWindowManager = viewCaptureAwareWindowManager; + mWindowManager = windowManager; mStatusBarConfigurationController = statusBarConfigurationController; mIWindowManager = iWindowManager; mContentInsetsProvider = contentInsetsProvider; @@ -406,7 +405,7 @@ public class StatusBarWindowControllerImpl implements StatusBarWindowController @Override StatusBarWindowControllerImpl create( @NonNull Context context, - @NonNull ViewCaptureAwareWindowManager viewCaptureAwareWindowManager, + @NonNull WindowManager windowManager, @NonNull StatusBarConfigurationController statusBarConfigurationController, @NonNull StatusBarContentInsetsProvider contentInsetsProvider); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt index 39afc38dad11..74c028a8c7ae 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt @@ -18,7 +18,6 @@ package com.android.systemui.statusbar.window import android.content.Context import android.view.WindowManager -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.display.data.repository.DisplayRepository @@ -42,7 +41,6 @@ constructor( @Background backgroundApplicationScope: CoroutineScope, private val controllerFactory: StatusBarWindowController.Factory, private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository, - private val viewCaptureAwareWindowManagerFactory: ViewCaptureAwareWindowManager.Factory, private val statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore, private val statusBarContentInsetsProviderStore: StatusBarContentInsetsProviderStore, displayRepository: DisplayRepository, @@ -67,11 +65,9 @@ constructor( statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null val contentInsetsProvider = statusBarContentInsetsProviderStore.forDisplay(displayId) ?: return null - val viewCaptureAwareWindowManager = - viewCaptureAwareWindowManagerFactory.create(statusBarDisplayContext.windowManager) return controllerFactory.create( statusBarDisplayContext.context, - viewCaptureAwareWindowManager, + statusBarDisplayContext.windowManager, statusBarConfigurationController, contentInsetsProvider, ) @@ -89,7 +85,7 @@ class SingleDisplayStatusBarWindowControllerStore @Inject constructor( context: Context, - viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager, + windowManager: WindowManager, factory: StatusBarWindowControllerImpl.Factory, statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore, statusBarContentInsetsProviderStore: StatusBarContentInsetsProviderStore, @@ -98,7 +94,7 @@ constructor( PerDisplayStore<StatusBarWindowController> by SingleDisplayStore( factory.create( context, - viewCaptureAwareWindowManager, + windowManager, statusBarConfigurationControllerStore.defaultDisplay, statusBarContentInsetsProviderStore.defaultDisplay, ) diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt index 635576743462..ea5f422f977d 100644 --- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt +++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt @@ -32,7 +32,6 @@ import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_ICONS import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_TEXT import androidx.annotation.CallSuper import androidx.annotation.VisibleForTesting -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.systemui.CoreStartable import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager @@ -70,7 +69,7 @@ import java.io.PrintWriter abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : TemporaryViewLogger<T>>( internal val context: Context, internal val logger: U, - internal val windowManager: ViewCaptureAwareWindowManager, + internal val windowManager: WindowManager, @Main private val mainExecutor: DelayableExecutor, private val accessibilityManager: AccessibilityManager, private val configurationController: ConfigurationController, diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt index 9b9cba9186f4..b6f54331b29f 100644 --- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt @@ -29,6 +29,7 @@ import android.view.View import android.view.View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE import android.view.View.ACCESSIBILITY_LIVE_REGION_NONE import android.view.ViewGroup +import android.view.WindowManager import android.view.accessibility.AccessibilityManager import android.view.accessibility.AccessibilityNodeInfo import android.widget.ImageView @@ -37,7 +38,6 @@ import androidx.annotation.DimenRes import androidx.annotation.IdRes import androidx.annotation.VisibleForTesting import com.android.app.animation.Interpolators -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.internal.widget.CachingIconView import com.android.systemui.Gefingerpoken import com.android.systemui.classifier.FalsingCollector @@ -81,7 +81,7 @@ open class ChipbarCoordinator constructor( context: Context, logger: ChipbarLogger, - viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager, + windowManager: WindowManager, @Main mainExecutor: DelayableExecutor, accessibilityManager: AccessibilityManager, configurationController: ConfigurationController, @@ -100,7 +100,7 @@ constructor( TemporaryViewDisplayController<ChipbarInfo, ChipbarLogger>( context, logger, - viewCaptureAwareWindowManager, + windowManager, mainExecutor, accessibilityManager, configurationController, diff --git a/packages/SystemUI/src/com/android/systemui/topwindoweffects/TopLevelWindowEffects.kt b/packages/SystemUI/src/com/android/systemui/topwindoweffects/TopLevelWindowEffects.kt index c11e4c507914..00c6ffd861da 100644 --- a/packages/SystemUI/src/com/android/systemui/topwindoweffects/TopLevelWindowEffects.kt +++ b/packages/SystemUI/src/com/android/systemui/topwindoweffects/TopLevelWindowEffects.kt @@ -21,7 +21,6 @@ import android.graphics.PixelFormat import android.view.Gravity import android.view.WindowInsets import android.view.WindowManager -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application @@ -38,7 +37,7 @@ import javax.inject.Inject class TopLevelWindowEffects @Inject constructor( @Application private val context: Context, @Application private val applicationScope: CoroutineScope, - private val windowManager: ViewCaptureAwareWindowManager, + private val windowManager: WindowManager, private val squeezeEffectInteractor: SqueezeEffectInteractor, private val keyEventInteractor: KeyEventInteractor, private val viewModelFactory: SqueezeEffectViewModel.Factory diff --git a/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt b/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt index 70fd5ab767d0..f1a556353273 100644 --- a/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt +++ b/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt @@ -20,7 +20,6 @@ import android.graphics.Rect import android.util.IndentingPrintWriter import android.view.View import android.view.ViewGroup -import dagger.Lazy import java.io.PrintWriter /** [Sequence] that yields all of the direct children of this [ViewGroup] */ @@ -56,11 +55,6 @@ val View.boundsOnScreen: Rect return bounds } -/** Extension method to convert [dagger.Lazy] to [kotlin.Lazy] for object of any class [T]. */ -fun <T> Lazy<T>.toKotlinLazy(): kotlin.Lazy<T> { - return lazy { this.get() } -} - /** * Returns whether this [Collection] contains exactly all [elements]. * diff --git a/packages/SystemUI/src/com/android/systemui/util/display/DisplayHelper.java b/packages/SystemUI/src/com/android/systemui/util/display/DisplayHelper.java index 8acd6535e751..757b2d973312 100644 --- a/packages/SystemUI/src/com/android/systemui/util/display/DisplayHelper.java +++ b/packages/SystemUI/src/com/android/systemui/util/display/DisplayHelper.java @@ -21,6 +21,8 @@ import android.hardware.display.DisplayManager; import android.view.Display; import android.view.WindowManager; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; + import javax.inject.Inject; /** @@ -29,14 +31,17 @@ import javax.inject.Inject; public class DisplayHelper { private final Context mContext; private final DisplayManager mDisplayManager; + private final WindowManagerProvider mWindowManagerProvider; /** * Default constructor. */ @Inject - public DisplayHelper(Context context, DisplayManager displayManager) { + public DisplayHelper(Context context, DisplayManager displayManager, + WindowManagerProvider windowManagerProvider) { mContext = context; mDisplayManager = displayManager; + mWindowManagerProvider = windowManagerProvider; } @@ -45,9 +50,8 @@ public class DisplayHelper { */ public Rect getMaxBounds(int displayId, int windowContextType) { final Display display = mDisplayManager.getDisplay(displayId); - WindowManager windowManager = mContext.createDisplayContext(display) - .createWindowContext(windowContextType, null) - .getSystemService(WindowManager.class); + WindowManager windowManager = mWindowManagerProvider.getWindowManager(mContext + .createDisplayContext(display).createWindowContext(windowContextType, null)); return windowManager.getMaximumWindowMetrics().getBounds(); } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt index 3ac6c7bc0c6b..457b6ac42f8b 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialog.kt @@ -18,6 +18,7 @@ package com.android.systemui.volume.dialog import android.content.Context import android.os.Bundle +import android.view.Gravity import android.view.MotionEvent import android.view.View import android.view.ViewGroup @@ -57,8 +58,10 @@ constructor( attributes.apply { title = "VolumeDialog" // Not the same as Window#setTitle } - setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) + setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT) + setGravity(Gravity.END) } + setCancelable(false) setCanceledOnTouchOutside(true) } diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/RingerDrawerConstraintsUtils.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/RingerDrawerConstraintsUtils.kt index fb9884cf4341..ad24f08a7214 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/RingerDrawerConstraintsUtils.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/RingerDrawerConstraintsUtils.kt @@ -111,7 +111,7 @@ private fun ConstraintSet.adjustOpenConstraintsForDrawer( view.id, ConstraintSet.START, motionLayout.context.resources.getDimensionPixelSize( - R.dimen.volume_dialog_ringer_drawer_margin + R.dimen.volume_dialog_background_margin ), ) } @@ -121,7 +121,7 @@ private fun ConstraintSet.adjustOpenConstraintsForDrawer( view.id, ConstraintSet.END, motionLayout.context.resources.getDimensionPixelSize( - R.dimen.volume_dialog_components_spacing + R.dimen.volume_dialog_ringer_drawer_buttons_spacing ), ) } else { @@ -140,7 +140,7 @@ private fun ConstraintSet.adjustOpenConstraintsForDrawer( view.id, ConstraintSet.BOTTOM, motionLayout.context.resources.getDimensionPixelSize( - R.dimen.volume_dialog_components_spacing + R.dimen.volume_dialog_ringer_drawer_buttons_spacing ), ) } else { @@ -158,10 +158,10 @@ private fun ConstraintSet.adjustOpenConstraintsForDrawer( R.dimen.volume_dialog_ringer_drawer_button_size ) * (motionLayout.childCount - 1)) + (motionLayout.context.resources.getDimensionPixelSize( - R.dimen.volume_dialog_ringer_drawer_margin + R.dimen.volume_dialog_background_margin ) * 2) + (motionLayout.context.resources.getDimensionPixelSize( - R.dimen.volume_dialog_components_spacing + R.dimen.volume_dialog_ringer_drawer_buttons_spacing ) * (motionLayout.childCount - 2)) ORIENTATION_PORTRAIT -> diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java index b1c6455a6e57..107f670eae8d 100644 --- a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java @@ -42,7 +42,6 @@ import android.service.wallpaper.WallpaperService; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; -import android.view.WindowManager; import androidx.annotation.NonNull; @@ -50,6 +49,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.dagger.qualifiers.LongRunning; import com.android.systemui.settings.UserTracker; import com.android.systemui.util.concurrency.DelayableExecutor; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -71,6 +71,7 @@ public class ImageWallpaper extends WallpaperService { private boolean mPagesComputed = false; private final UserTracker mUserTracker; + private final WindowManagerProvider mWindowManagerProvider; // used to handle WallpaperService messages (e.g. DO_ATTACH, MSG_UPDATE_SURFACE) // and to receive WallpaperService callbacks (e.g. onCreateEngine, onSurfaceRedrawNeeded) @@ -84,10 +85,12 @@ public class ImageWallpaper extends WallpaperService { private static final int DELAY_UNLOAD_BITMAP = 2000; @Inject - public ImageWallpaper(@LongRunning DelayableExecutor longExecutor, UserTracker userTracker) { + public ImageWallpaper(@LongRunning DelayableExecutor longExecutor, UserTracker userTracker, + WindowManagerProvider windowManagerProvider) { super(); mLongExecutor = longExecutor; mUserTracker = userTracker; + mWindowManagerProvider = windowManagerProvider; } @Override @@ -552,8 +555,7 @@ public class ImageWallpaper extends WallpaperService { } private void getDisplaySizeAndUpdateColorExtractor() { - Rect window = getDisplayContext() - .getSystemService(WindowManager.class) + Rect window = mWindowManagerProvider.getWindowManager(getDisplayContext()) .getCurrentWindowMetrics() .getBounds(); mWallpaperLocalColorExtractor.setDisplayDimensions(window.width(), window.height()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java index 0769ada805a2..645e306eed07 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java @@ -80,8 +80,6 @@ import androidx.annotation.Nullable; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCapture; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.biometrics.AuthController; import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository; @@ -104,7 +102,6 @@ import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.commandline.CommandRegistry; import com.android.systemui.statusbar.events.PrivacyDotViewController; -import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.concurrency.FakeThreadFactory; import com.android.systemui.util.kotlin.JavaAdapter; @@ -112,8 +109,6 @@ import com.android.systemui.util.settings.FakeSettings; import com.android.systemui.util.settings.SecureSettings; import com.android.systemui.util.time.FakeSystemClock; -import kotlin.Lazy; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -132,7 +127,6 @@ public class ScreenDecorationsTest extends SysuiTestCase { private ScreenDecorations mScreenDecorations; private WindowManager mWindowManager; - private ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; private DisplayManager mDisplayManager; private SecureSettings mSecureSettings; private FakeExecutor mExecutor; @@ -179,8 +173,6 @@ public class ScreenDecorationsTest extends SysuiTestCase { private CutoutDecorProviderFactory mCutoutFactory; @Mock private JavaAdapter mJavaAdapter; - @Mock - private Lazy<ViewCapture> mLazyViewCapture; private FakeFacePropertyRepository mFakeFacePropertyRepository = new FakeFacePropertyRepository(); @@ -254,14 +246,12 @@ public class ScreenDecorationsTest extends SysuiTestCase { new ScreenDecorationsLogger(logcatLogBuffer("TestLogBuffer")), mFakeFacePropertyRepository)); - mViewCaptureAwareWindowManager = new ViewCaptureAwareWindowManager(mWindowManager, - mLazyViewCapture, false); mScreenDecorations = spy(new ScreenDecorations(mContext, mSecureSettings, mCommandRegistry, mUserTracker, mDisplayTracker, mDotViewController, mPrivacyDotDecorProviderFactory, mFaceScanningProviderFactory, new ScreenDecorationsLogger(logcatLogBuffer("TestLogBuffer")), mFakeFacePropertyRepository, mJavaAdapter, mCameraProtectionLoader, - mViewCaptureAwareWindowManager, mMainHandler, mExecutor) { + mWindowManager, mMainHandler, mExecutor) { @Override public void start() { super.start(); @@ -1276,7 +1266,7 @@ public class ScreenDecorationsTest extends SysuiTestCase { mPrivacyDotDecorProviderFactory, mFaceScanningProviderFactory, new ScreenDecorationsLogger(logcatLogBuffer("TestLogBuffer")), mFakeFacePropertyRepository, mJavaAdapter, mCameraProtectionLoader, - mViewCaptureAwareWindowManager, mMainHandler, mExecutor); + mWindowManager, mMainHandler, mExecutor); screenDecorations.start(); when(mContext.getDisplay()).thenReturn(mDisplay); when(mDisplay.getDisplayInfo(any())).thenAnswer(new Answer<Boolean>() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java index 6d75c4ca3a38..d3d4e24001cb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java @@ -43,13 +43,13 @@ import android.view.accessibility.IRemoteMagnificationAnimationCallback; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.SysuiTestCase; import com.android.systemui.model.SysUiState; import com.android.systemui.recents.LauncherProxyService; import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.util.settings.SecureSettings; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import org.junit.Before; import org.junit.Test; @@ -94,7 +94,7 @@ public class IMagnificationConnectionTest extends SysuiTestCase { @Mock private IWindowManager mIWindowManager; @Mock - private ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; + private WindowManagerProvider mWindowManagerProvider; private IMagnificationConnection mIMagnificationConnection; private MagnificationImpl mMagnification; @@ -116,8 +116,7 @@ public class IMagnificationConnectionTest extends SysuiTestCase { mTestableLooper.getLooper(), mContext.getMainExecutor(), mCommandQueue, mModeSwitchesController, mSysUiState, mLauncherProxyService, mSecureSettings, mDisplayTracker, getContext().getSystemService(DisplayManager.class), - mA11yLogger, mIWindowManager, mAccessibilityManager, - mViewCaptureAwareWindowManager); + mA11yLogger, mIWindowManager, mAccessibilityManager, mWindowManagerProvider); mMagnification.mWindowMagnificationControllerSupplier = new FakeWindowMagnificationControllerSupplier( mContext.getSystemService(DisplayManager.class)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationTest.java index 8bfd2545ff2b..ae96e8fe7b8b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationTest.java @@ -50,13 +50,13 @@ import android.view.accessibility.IMagnificationConnectionCallback; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.SysuiTestCase; import com.android.systemui.model.SysUiState; import com.android.systemui.recents.LauncherProxyService; import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.util.settings.SecureSettings; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import org.junit.Before; import org.junit.Test; @@ -98,7 +98,7 @@ public class MagnificationTest extends SysuiTestCase { @Mock private IWindowManager mIWindowManager; @Mock - private ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; + private WindowManagerProvider mWindowManagerProvider; @Before public void setUp() throws Exception { @@ -132,8 +132,7 @@ public class MagnificationTest extends SysuiTestCase { mCommandQueue, mModeSwitchesController, mSysUiState, mLauncherProxyService, mSecureSettings, mDisplayTracker, getContext().getSystemService(DisplayManager.class), mA11yLogger, mIWindowManager, - getContext().getSystemService(AccessibilityManager.class), - mViewCaptureAwareWindowManager); + getContext().getSystemService(AccessibilityManager.class), mWindowManagerProvider); mMagnification.mWindowMagnificationControllerSupplier = new FakeControllerSupplier( mContext.getSystemService(DisplayManager.class), mWindowMagnificationController); mMagnification.mMagnificationSettingsSupplier = new FakeSettingsSupplier( diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java index a0f5b2214f80..ac0378b093c5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java @@ -51,8 +51,6 @@ import android.view.animation.AccelerateInterpolator; import android.window.InputTransferToken; import androidx.test.filters.LargeTest; - -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.systemui.Flags; import com.android.systemui.SysuiTestCase; @@ -112,8 +110,6 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase { SysUiState mSysUiState; @Mock SecureSettings mSecureSettings; - @Mock - ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; private SpyWindowMagnificationController mController; private WindowMagnificationController mSpyController; private WindowMagnificationAnimationController mWindowMagnificationAnimationController; @@ -167,7 +163,7 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase { mSecureSettings, scvhSupplier, mSfVsyncFrameProvider, - mViewCaptureAwareWindowManager); + mWindowManager); mSpyController = mController.getSpyController(); } @@ -1023,7 +1019,7 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase { SecureSettings secureSettings, Supplier<SurfaceControlViewHost> scvhSupplier, SfVsyncFrameCallbackProvider sfVsyncFrameProvider, - ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) { + WindowManager windowManager) { super( context, handler, @@ -1033,7 +1029,8 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase { callback, sysUiState, secureSettings, - scvhSupplier); + scvhSupplier, + windowManager); mSpyController = Mockito.mock(WindowMagnificationController.class); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java index 5b32b922d377..c8e0b14152fd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java @@ -238,7 +238,8 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { mWindowMagnifierCallback, mSysUiState, mSecureSettings, - scvhSupplier); + scvhSupplier, + mWindowManager); verify(mMirrorWindowControl).setWindowDelegate( any(MirrorWindowControl.MirrorWindowDelegate.class)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java index 45b9f4ad2322..dfc3ff2791b2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java @@ -65,8 +65,6 @@ import androidx.test.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCapture; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.systemui.SysuiTestCase; import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView; @@ -74,8 +72,6 @@ import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView.OnSeekBarW import com.android.systemui.res.R; import com.android.systemui.util.settings.SecureSettings; -import kotlin.Lazy; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -104,8 +100,6 @@ public class WindowMagnificationSettingsTest extends SysuiTestCase { private SecureSettings mSecureSettings; @Mock private WindowMagnificationSettingsCallback mWindowMagnificationSettingsCallback; - @Mock - private Lazy<ViewCapture> mLazyViewCapture; private TestableWindowManager mWindowManager; private WindowMagnificationSettings mWindowMagnificationSettings; private MotionEventHelper mMotionEventHelper = new MotionEventHelper(); @@ -123,6 +117,7 @@ public class WindowMagnificationSettingsTest extends SysuiTestCase { final WindowManager wm = mContext.getSystemService(WindowManager.class); mWindowManager = spy(new TestableWindowManager(wm)); mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager); + mContext.addMockSystemService(Context.ACCESSIBILITY_SERVICE, mAccessibilityManager); when(mSecureSettings.getIntForUser(anyString(), anyInt(), anyInt())).then( @@ -130,11 +125,9 @@ public class WindowMagnificationSettingsTest extends SysuiTestCase { when(mSecureSettings.getFloatForUser(anyString(), anyFloat(), anyInt())).then( returnsSecondArg()); - ViewCaptureAwareWindowManager vwm = new ViewCaptureAwareWindowManager(mWindowManager, - mLazyViewCapture, /* isViewCaptureEnabled= */ false); mWindowMagnificationSettings = new WindowMagnificationSettings(mContext, mWindowMagnificationSettingsCallback, mSfVsyncFrameProvider, - mSecureSettings, vwm); + mSecureSettings, mWindowManager); mSettingView = mWindowMagnificationSettings.getSettingView(); mZoomSeekbar = mSettingView.findViewById(R.id.magnifier_zoom_slider); diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java index bc9d4c7fa0e6..b81cbe48b4ff 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java @@ -38,8 +38,6 @@ import android.view.accessibility.AccessibilityManager; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCapture; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.settingslib.bluetooth.HearingAidDeviceManager; @@ -51,8 +49,6 @@ import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.util.settings.SecureSettings; -import kotlin.Lazy; - import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -78,7 +74,6 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { private Context mContextWrapper; private WindowManager mWindowManager; - private ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; private AccessibilityManager mAccessibilityManager; private KeyguardUpdateMonitor mKeyguardUpdateMonitor; private AccessibilityFloatingMenuController mController; @@ -93,8 +88,6 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { @Mock private SecureSettings mSecureSettings; @Mock - private Lazy<ViewCapture> mLazyViewCapture; - @Mock private NavigationModeController mNavigationModeController; @Mock private HearingAidDeviceManager mHearingAidDeviceManager; @@ -110,8 +103,6 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { }; mWindowManager = mContext.getSystemService(WindowManager.class); - mViewCaptureAwareWindowManager = new ViewCaptureAwareWindowManager(mWindowManager, - mLazyViewCapture, /* isViewCaptureEnabled= */ false); mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class); mTestableLooper = TestableLooper.get(this); @@ -172,8 +163,8 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { enableAccessibilityFloatingMenuConfig(); mController = setUpController(); mController.mFloatingMenu = new MenuViewLayerController(mContextWrapper, mWindowManager, - mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings, - mNavigationModeController, mHearingAidDeviceManager); + mAccessibilityManager, mSecureSettings, mNavigationModeController, + mHearingAidDeviceManager); captureKeyguardUpdateMonitorCallback(); mKeyguardCallback.onUserUnlocked(); @@ -200,8 +191,8 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { enableAccessibilityFloatingMenuConfig(); mController = setUpController(); mController.mFloatingMenu = new MenuViewLayerController(mContextWrapper, mWindowManager, - mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings, - mNavigationModeController, mHearingAidDeviceManager); + mAccessibilityManager, mSecureSettings, mNavigationModeController, + mHearingAidDeviceManager); captureKeyguardUpdateMonitorCallback(); mKeyguardCallback.onUserSwitching(fakeUserId); @@ -215,8 +206,8 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { enableAccessibilityFloatingMenuConfig(); mController = setUpController(); mController.mFloatingMenu = new MenuViewLayerController(mContextWrapper, mWindowManager, - mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings, - mNavigationModeController, mHearingAidDeviceManager); + mAccessibilityManager, mSecureSettings, mNavigationModeController, + mHearingAidDeviceManager); captureKeyguardUpdateMonitorCallback(); mKeyguardCallback.onUserUnlocked(); mKeyguardCallback.onKeyguardVisibilityChanged(true); @@ -362,18 +353,15 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { private AccessibilityFloatingMenuController setUpController() { final WindowManager windowManager = mContext.getSystemService(WindowManager.class); - final ViewCaptureAwareWindowManager viewCaptureAwareWindowManager = - new ViewCaptureAwareWindowManager(windowManager, mLazyViewCapture, - /* isViewCaptureEnabled= */ false); final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); final FakeDisplayTracker displayTracker = new FakeDisplayTracker(mContext); mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class); final AccessibilityFloatingMenuController controller = new AccessibilityFloatingMenuController(mContextWrapper, windowManager, - viewCaptureAwareWindowManager, displayManager, mAccessibilityManager, - mTargetsObserver, mModeObserver, mHearingAidDeviceManager, - mKeyguardUpdateMonitor, mSecureSettings, displayTracker, - mNavigationModeController, new Handler(mTestableLooper.getLooper())); + displayManager, mAccessibilityManager, mTargetsObserver, mModeObserver, + mHearingAidDeviceManager, mKeyguardUpdateMonitor, mSecureSettings, + displayTracker, mNavigationModeController, + new Handler(mTestableLooper.getLooper())); controller.init(); return controller; diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt index 6cc8238f2d09..dfb6afe8bd12 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt @@ -352,6 +352,7 @@ class ActivityTransitionAnimatorTest : SysuiTestCase() { val controller = createController() val runner = underTest.createEphemeralRunner(controller) runner.onAnimationCancelled() + waitForIdleSync() runner.onAnimationStart( TRANSIT_NONE, emptyArray(), @@ -359,12 +360,13 @@ class ActivityTransitionAnimatorTest : SysuiTestCase() { emptyArray(), iCallback, ) - waitForIdleSync() + verify(controller).onTransitionAnimationCancelled() verify(controller, never()).onTransitionAnimationStart(anyBoolean()) verify(listener).onTransitionAnimationCancelled() verify(listener, never()).onTransitionAnimationStart() + verify(iCallback).onAnimationFinished() assertNull(runner.delegate) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt index a1d038ad8554..a9e6a3ebdb30 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt @@ -28,8 +28,6 @@ import android.view.WindowManager import android.view.accessibility.AccessibilityManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.app.viewcapture.ViewCapture -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ActivityTransitionAnimator @@ -62,7 +60,6 @@ import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.testKosmos import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.google.common.truth.Truth.assertThat -import dagger.Lazy import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -98,7 +95,6 @@ class UdfpsControllerOverlayTest : SysuiTestCase() { @Mock private lateinit var inflater: LayoutInflater @Mock private lateinit var windowManager: WindowManager - @Mock private lateinit var lazyViewCapture: kotlin.Lazy<ViewCapture> @Mock private lateinit var accessibilityManager: AccessibilityManager @Mock private lateinit var statusBarStateController: StatusBarStateController @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager @@ -160,11 +156,7 @@ class UdfpsControllerOverlayTest : SysuiTestCase() { UdfpsControllerOverlay( context, inflater, - ViewCaptureAwareWindowManager( - windowManager, - lazyViewCapture, - isViewCaptureEnabled = false, - ), + windowManager, accessibilityManager, statusBarStateController, statusBarKeyguardViewManager, diff --git a/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt index 57b397cfca7e..034bab855faf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt @@ -23,13 +23,11 @@ import android.view.WindowManager import android.view.WindowMetrics import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.app.viewcapture.ViewCapture -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.internal.logging.UiEventLogger +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags -import com.android.systemui.res.R import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.ConfigurationController @@ -42,12 +40,12 @@ import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers import org.mockito.Mock +import org.mockito.Mockito.`when` import org.mockito.Mockito.any import org.mockito.Mockito.eq import org.mockito.Mockito.never import org.mockito.Mockito.reset import org.mockito.Mockito.verify -import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations @SmallTest @@ -62,7 +60,6 @@ class WiredChargingRippleControllerTest : SysuiTestCase() { @Mock private lateinit var windowManager: WindowManager @Mock private lateinit var uiEventLogger: UiEventLogger @Mock private lateinit var windowMetrics: WindowMetrics - @Mock private lateinit var lazyViewCapture: Lazy<ViewCapture> private val systemClock = FakeSystemClock() @Before @@ -71,9 +68,7 @@ class WiredChargingRippleControllerTest : SysuiTestCase() { `when`(featureFlags.isEnabled(Flags.CHARGING_RIPPLE)).thenReturn(true) controller = WiredChargingRippleController( commandRegistry, batteryController, configurationController, - featureFlags, context, windowManager, - ViewCaptureAwareWindowManager(windowManager, - lazyViewCapture, isViewCaptureEnabled = false), systemClock, uiEventLogger) + featureFlags, context, windowManager, systemClock, uiEventLogger) rippleView.setupShader() controller.rippleView = rippleView // Replace the real ripple view with a mock instance controller.registerCallbacks() diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index 9b314f25e02b..41fdaa74e57b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -73,10 +73,10 @@ import android.view.IRemoteAnimationFinishedCallback; import android.view.RemoteAnimationTarget; import android.view.View; import android.view.ViewRootImpl; +import android.view.WindowManager; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.foldables.FoldGracePeriodProvider; import com.android.internal.logging.InstanceId; import com.android.internal.logging.UiEventLogger; @@ -175,7 +175,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { private @Mock BroadcastDispatcher mBroadcastDispatcher; private @Mock DismissCallbackRegistry mDismissCallbackRegistry; private @Mock DumpManager mDumpManager; - private @Mock ViewCaptureAwareWindowManager mWindowManager; + private @Mock WindowManager mWindowManager; private @Mock IActivityManager mActivityManager; private @Mock ConfigurationController mConfigurationController; private @Mock PowerManager mPowerManager; diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt index c7beb158c2de..add87686bc9f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt @@ -20,8 +20,8 @@ import android.content.Context import android.os.Handler import android.os.PowerManager import android.view.ViewGroup +import android.view.WindowManager import android.view.accessibility.AccessibilityManager -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.systemui.dump.DumpManager import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.policy.ConfigurationController @@ -35,7 +35,7 @@ class FakeMediaTttChipControllerReceiver( commandQueue: CommandQueue, context: Context, logger: MediaTttReceiverLogger, - viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager, + windowManager: WindowManager, mainExecutor: DelayableExecutor, accessibilityManager: AccessibilityManager, configurationController: ConfigurationController, @@ -53,7 +53,7 @@ class FakeMediaTttChipControllerReceiver( commandQueue, context, logger, - viewCaptureAwareWindowManager, + windowManager, mainExecutor, accessibilityManager, configurationController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt index 378dd452d030..1aa6ac67ec27 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt @@ -31,8 +31,6 @@ import android.view.accessibility.AccessibilityManager import android.widget.ImageView import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.app.viewcapture.ViewCapture -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.internal.logging.InstanceId import com.android.internal.logging.testing.UiEventLoggerFake import com.android.systemui.SysuiTestCase @@ -75,8 +73,6 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() { @Mock private lateinit var windowManager: WindowManager @Mock private lateinit var commandQueue: CommandQueue @Mock private lateinit var rippleController: MediaTttReceiverRippleController - @Mock private lateinit var lazyViewCapture: Lazy<ViewCapture> - private lateinit var viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager private lateinit var commandQueueCallback: CommandQueue.Callbacks private lateinit var fakeAppIconDrawable: Drawable private lateinit var uiEventLoggerFake: UiEventLoggerFake @@ -114,18 +110,12 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() { fakeWakeLockBuilder = WakeLockFake.Builder(context) fakeWakeLockBuilder.setWakeLock(fakeWakeLock) - viewCaptureAwareWindowManager = - ViewCaptureAwareWindowManager( - windowManager, - lazyViewCapture, - isViewCaptureEnabled = false, - ) controllerReceiver = FakeMediaTttChipControllerReceiver( commandQueue, context, logger, - viewCaptureAwareWindowManager, + windowManager, fakeExecutor, accessibilityManager, configurationController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt index c90ac5993c31..18de32e80da6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt @@ -34,7 +34,6 @@ import android.widget.TextView import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.app.viewcapture.ViewCapture -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.internal.logging.testing.UiEventLoggerFake import com.android.internal.statusbar.IUndoMediaTransferCallback import com.android.systemui.SysuiTestCase @@ -100,7 +99,6 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Mock private lateinit var windowManager: WindowManager @Mock private lateinit var vibratorHelper: VibratorHelper @Mock private lateinit var swipeHandler: SwipeChipbarAwayGestureHandler - @Mock private lateinit var lazyViewCapture: Lazy<ViewCapture> private lateinit var fakeWakeLockBuilder: WakeLockFake.Builder private lateinit var fakeWakeLock: WakeLockFake private lateinit var chipbarCoordinator: ChipbarCoordinator @@ -145,11 +143,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { ChipbarCoordinator( context, chipbarLogger, - ViewCaptureAwareWindowManager( - windowManager, - lazyViewCapture, - isViewCaptureEnabled = false, - ), + windowManager, fakeExecutor, accessibilityManager, configurationController, @@ -1476,7 +1470,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { private fun ViewGroup.getUndoButton(): View = this.requireViewById(R.id.end_button) private fun ChipStateSender.getExpectedStateText( - otherDeviceName: String = OTHER_DEVICE_NAME + otherDeviceName: String = OTHER_DEVICE_NAME, ): String? { return this.getChipTextString(context, otherDeviceName).loadText(context) } @@ -1487,7 +1481,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo, - null, + null ) } @@ -1497,7 +1491,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo, - null, + null ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt index b4db6da2000a..b169cc12f08a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt @@ -27,7 +27,6 @@ import android.view.ViewConfiguration import android.view.WindowManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.internal.jank.Cuj import com.android.internal.util.LatencyTracker import com.android.systemui.SysuiTestCase @@ -64,7 +63,7 @@ class BackPanelControllerTest : SysuiTestCase() { private var triggerThreshold: Float = 0.0f private val touchSlop = ViewConfiguration.get(context).scaledEdgeSlop @Mock private lateinit var vibratorHelper: VibratorHelper - @Mock private lateinit var viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager + @Mock private lateinit var windowManager: WindowManager @Mock private lateinit var configurationController: ConfigurationController @Mock private lateinit var latencyTracker: LatencyTracker private val interactionJankMonitor by lazy { kosmos.interactionJankMonitor } @@ -79,7 +78,7 @@ class BackPanelControllerTest : SysuiTestCase() { mBackPanelController = BackPanelController( context, - viewCaptureAwareWindowManager, + windowManager, ViewConfiguration.get(context), Handler.createAsync(testableLooper.looper), systemClock, diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentControllerTest.java index e4a4953063bb..e949c8a10c9c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentControllerTest.java @@ -62,7 +62,6 @@ import android.view.WindowManager; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.logging.UiEventLogger; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.settingslib.wifi.WifiUtils; @@ -162,7 +161,7 @@ public class InternetDetailsContentControllerTest extends SysuiTestCase { @Mock InternetDetailsContentController.InternetDialogCallback mInternetDialogCallback; @Mock - private ViewCaptureAwareWindowManager mWindowManager; + private WindowManager mWindowManager; @Mock private ToastFactory mToastFactory; @Mock @@ -234,9 +233,8 @@ public class InternetDetailsContentControllerTest extends SysuiTestCase { mSubscriptionManager, mTelephonyManager, mWifiManager, mConnectivityManager, mHandler, mExecutor, mBroadcastDispatcher, mock(KeyguardUpdateMonitor.class), mGlobalSettings, mKeyguardStateController, - mWindowManager, mToastFactory, mWorkerHandler, - mCarrierConfigTracker, mLocationController, mDialogTransitionAnimator, - mWifiStateWorker, mFlags); + mWindowManager, mToastFactory, mWorkerHandler, mCarrierConfigTracker, + mLocationController, mDialogTransitionAnimator, mWifiStateWorker, mFlags); mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor, mInternetDetailsContentController.mOnSubscriptionsChangedListener); mInternetDetailsContentController.onStart(mInternetDialogCallback, true); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutListSearchTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutListSearchTest.java index 8045a13ff9be..07204ee814d2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutListSearchTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutListSearchTest.java @@ -34,6 +34,7 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.systemui.SysuiTestCase; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import com.google.android.material.bottomsheet.BottomSheetDialog; @@ -61,6 +62,7 @@ public class KeyboardShortcutListSearchTest extends SysuiTestCase { @Mock private BottomSheetDialog mBottomSheetDialog; @Mock WindowManager mWindowManager; @Mock Handler mHandler; + @Mock WindowManagerProvider mWindowManagerProvider; @Before public void setUp() { @@ -77,7 +79,7 @@ public class KeyboardShortcutListSearchTest extends SysuiTestCase { public void toggle_isShowingTrue_instanceShouldBeNull() { when(mBottomSheetDialog.isShowing()).thenReturn(true); - mKeyboardShortcutListSearch.toggle(mContext, DEVICE_ID); + mKeyboardShortcutListSearch.toggle(mContext, DEVICE_ID, mWindowManagerProvider); assertThat(mKeyboardShortcutListSearch.sInstance).isNull(); } @@ -86,7 +88,7 @@ public class KeyboardShortcutListSearchTest extends SysuiTestCase { public void toggle_isShowingFalse_showKeyboardShortcuts() { when(mBottomSheetDialog.isShowing()).thenReturn(false); - mKeyboardShortcutListSearch.toggle(mContext, DEVICE_ID); + mKeyboardShortcutListSearch.toggle(mContext, DEVICE_ID, mWindowManagerProvider); verify(mWindowManager).requestAppKeyboardShortcuts(any(), anyInt()); verify(mWindowManager).requestImeKeyboardShortcuts(any(), anyInt()); @@ -96,7 +98,7 @@ public class KeyboardShortcutListSearchTest extends SysuiTestCase { public void requestAppKeyboardShortcuts_callback_sanitisesIcons() { KeyboardShortcutGroup group = createKeyboardShortcutGroupForIconTests(); - mKeyboardShortcutListSearch.toggle(mContext, DEVICE_ID); + mKeyboardShortcutListSearch.toggle(mContext, DEVICE_ID, mWindowManagerProvider); ArgumentCaptor<WindowManager.KeyboardShortcutsReceiver> callbackCaptor = ArgumentCaptor.forClass(WindowManager.KeyboardShortcutsReceiver.class); @@ -114,7 +116,7 @@ public class KeyboardShortcutListSearchTest extends SysuiTestCase { public void requestImeKeyboardShortcuts_callback_sanitisesIcons() { KeyboardShortcutGroup group = createKeyboardShortcutGroupForIconTests(); - mKeyboardShortcutListSearch.toggle(mContext, DEVICE_ID); + mKeyboardShortcutListSearch.toggle(mContext, DEVICE_ID, mWindowManagerProvider); ArgumentCaptor<WindowManager.KeyboardShortcutsReceiver> callbackCaptor = ArgumentCaptor.forClass(WindowManager.KeyboardShortcutsReceiver.class); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsReceiverTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsReceiverTest.java index 2cb9791cc159..0bd9b29a1a37 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsReceiverTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsReceiverTest.java @@ -36,6 +36,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.shared.recents.utilities.Utilities; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import org.junit.After; import org.junit.Before; @@ -59,6 +60,7 @@ public class KeyboardShortcutsReceiverTest extends SysuiTestCase { @Mock private KeyboardShortcuts mKeyboardShortcuts; @Mock private KeyboardShortcutListSearch mKeyboardShortcutListSearch; + @Mock private WindowManagerProvider mWindowManagerProvider; @Before public void setUp() { @@ -69,7 +71,8 @@ public class KeyboardShortcutsReceiverTest extends SysuiTestCase { KeyboardShortcuts.sInstance = mKeyboardShortcuts; KeyboardShortcutListSearch.sInstance = mKeyboardShortcutListSearch; - mKeyboardShortcutsReceiver = spy(new KeyboardShortcutsReceiver(mFeatureFlags)); + mKeyboardShortcutsReceiver = spy(new KeyboardShortcutsReceiver(mFeatureFlags, + mWindowManagerProvider)); } @Before diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsTest.java index 20ecaf75c625..939f2b899dbe 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyboardShortcutsTest.java @@ -39,6 +39,7 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.systemui.SysuiTestCase; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import org.junit.Before; import org.junit.Rule; @@ -67,6 +68,7 @@ public class KeyboardShortcutsTest extends SysuiTestCase { @Mock private Dialog mDialog; @Mock WindowManager mWindowManager; @Mock Handler mHandler; + @Mock WindowManagerProvider mWindowManagerProvider; @Before public void setUp() { @@ -92,7 +94,7 @@ public class KeyboardShortcutsTest extends SysuiTestCase { public void toggle_isShowingTrue_instanceShouldBeNull() { when(mDialog.isShowing()).thenReturn(true); - KeyboardShortcuts.toggle(mContext, DEVICE_ID); + KeyboardShortcuts.toggle(mContext, DEVICE_ID, mWindowManagerProvider); assertThat(KeyboardShortcuts.sInstance).isNull(); } @@ -101,7 +103,7 @@ public class KeyboardShortcutsTest extends SysuiTestCase { public void toggle_isShowingFalse_showKeyboardShortcuts() { when(mDialog.isShowing()).thenReturn(false); - KeyboardShortcuts.toggle(mContext, DEVICE_ID); + KeyboardShortcuts.toggle(mContext, DEVICE_ID, mWindowManagerProvider); verify(mWindowManager).requestAppKeyboardShortcuts(any(), anyInt()); verify(mWindowManager).requestImeKeyboardShortcuts(any(), anyInt()); @@ -131,7 +133,7 @@ public class KeyboardShortcutsTest extends SysuiTestCase { @Test public void requestAppKeyboardShortcuts_callback_sanitisesIcons() { KeyboardShortcutGroup group = createKeyboardShortcutGroupForIconTests(); - KeyboardShortcuts.toggle(mContext, DEVICE_ID); + KeyboardShortcuts.toggle(mContext, DEVICE_ID, mWindowManagerProvider); emitAppShortcuts(singletonList(group), DEVICE_ID); @@ -142,7 +144,7 @@ public class KeyboardShortcutsTest extends SysuiTestCase { @Test public void requestImeKeyboardShortcuts_callback_sanitisesIcons() { KeyboardShortcutGroup group = createKeyboardShortcutGroupForIconTests(); - KeyboardShortcuts.toggle(mContext, DEVICE_ID); + KeyboardShortcuts.toggle(mContext, DEVICE_ID, mWindowManagerProvider); emitImeShortcuts(singletonList(group), DEVICE_ID); @@ -153,7 +155,7 @@ public class KeyboardShortcutsTest extends SysuiTestCase { @Test public void onImeAndAppShortcutsReceived_appShortcutsNull_doesNotCrash() { KeyboardShortcutGroup group = createKeyboardShortcutGroupForIconTests(); - KeyboardShortcuts.toggle(mContext, DEVICE_ID); + KeyboardShortcuts.toggle(mContext, DEVICE_ID, mWindowManagerProvider); emitImeShortcuts(singletonList(group), DEVICE_ID); emitAppShortcuts(/* groups= */ null, DEVICE_ID); @@ -162,7 +164,7 @@ public class KeyboardShortcutsTest extends SysuiTestCase { @Test public void onImeAndAppShortcutsReceived_imeShortcutsNull_doesNotCrash() { KeyboardShortcutGroup group = createKeyboardShortcutGroupForIconTests(); - KeyboardShortcuts.toggle(mContext, DEVICE_ID); + KeyboardShortcuts.toggle(mContext, DEVICE_ID, mWindowManagerProvider); emitAppShortcuts(singletonList(group), DEVICE_ID); emitImeShortcuts(/* groups= */ null, DEVICE_ID); @@ -170,7 +172,7 @@ public class KeyboardShortcutsTest extends SysuiTestCase { @Test public void onImeAndAppShortcutsReceived_bothNull_doesNotCrash() { - KeyboardShortcuts.toggle(mContext, DEVICE_ID); + KeyboardShortcuts.toggle(mContext, DEVICE_ID, mWindowManagerProvider); emitImeShortcuts(/* groups= */ null, DEVICE_ID); emitAppShortcuts(/* groups= */ null, DEVICE_ID); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java index a7f3fdcb517e..0c5cbc299aee 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java @@ -93,7 +93,6 @@ import android.view.WindowMetrics; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.compose.animation.scene.ObservableTransitionState; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.logging.UiEventLogger; @@ -214,6 +213,7 @@ import com.android.systemui.util.settings.FakeGlobalSettings; import com.android.systemui.util.settings.FakeSettings; import com.android.systemui.util.settings.SystemSettings; import com.android.systemui.util.time.FakeSystemClock; +import com.android.systemui.utils.windowmanager.WindowManagerProvider; import com.android.systemui.volume.VolumeComponent; import com.android.systemui.wallet.controller.QuickAccessWalletController; import com.android.wm.shell.bubbles.Bubbles; @@ -372,9 +372,10 @@ public class CentralSurfacesImplTest extends SysuiTestCase { @Mock private GlanceableHubContainerController mGlanceableHubContainerController; @Mock private EmergencyGestureIntentFactory mEmergencyGestureIntentFactory; @Mock private NotificationSettingsInteractor mNotificationSettingsInteractor; - @Mock private ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; @Mock private StatusBarLongPressGestureDetector mStatusBarLongPressGestureDetector; @Mock private QuickAccessWalletController mQuickAccessWalletController; + @Mock private WindowManager mWindowManager; + @Mock private WindowManagerProvider mWindowManagerProvider; private ShadeController mShadeController; private final FakeSystemClock mFakeSystemClock = new FakeSystemClock(); private final FakeGlobalSettings mFakeGlobalSettings = new FakeGlobalSettings(); @@ -642,8 +643,9 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mBrightnessMirrorShowingRepository, mGlanceableHubContainerController, mEmergencyGestureIntentFactory, - mViewCaptureAwareWindowManager, - mQuickAccessWalletController + mQuickAccessWalletController, + mWindowManager, + mWindowManagerProvider ); mScreenLifecycle.addObserver(mCentralSurfaces.mScreenObserver); mCentralSurfaces.initShadeVisibilityListener(); @@ -1363,15 +1365,13 @@ public class CentralSurfacesImplTest extends SysuiTestCase { private void switchToScreenSize(int widthDp, int heightDp) { WindowMetrics windowMetrics = Mockito.mock(WindowMetrics.class); - WindowManager windowManager = Mockito.mock(WindowManager.class); Configuration configuration = new Configuration(); configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT; mContext.getOrCreateTestableResources().overrideConfiguration(configuration); when(windowMetrics.getBounds()).thenReturn(new Rect(0, 0, widthDp, heightDp)); - when(windowManager.getCurrentWindowMetrics()).thenReturn(windowMetrics); - mContext.addMockSystemService(WindowManager.class, windowManager); + when(mWindowManager.getCurrentWindowMetrics()).thenReturn(windowMetrics); } /** diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt index 68f66611c981..574b2c010a37 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt @@ -471,6 +471,51 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() { } @Test + @EnableFlags(ShadeWindowGoesAround.FLAG_NAME) + fun onTouch_withMouseOnEndSideIcons_flagOn_propagatedToShadeDisplayPolicy() { + val view = createViewMock() + InstrumentationRegistry.getInstrumentation().runOnMainSync { + controller = createAndInitController(view) + } + val event = getActionUpEventFromSource(InputDevice.SOURCE_MOUSE) + + val statusContainer = view.requireViewById<View>(R.id.system_icons) + statusContainer.dispatchTouchEvent(event) + + verify(statusBarTouchShadeDisplayPolicy).onStatusBarTouched(eq(event), any()) + } + + @Test + @EnableFlags(ShadeWindowGoesAround.FLAG_NAME) + fun onTouch_withMouseOnStartSideIcons_flagOn_propagatedToShadeDisplayPolicy() { + val view = createViewMock() + InstrumentationRegistry.getInstrumentation().runOnMainSync { + controller = createAndInitController(view) + } + val event = getActionUpEventFromSource(InputDevice.SOURCE_MOUSE) + + val statusContainer = view.requireViewById<View>(R.id.status_bar_start_side_content) + statusContainer.dispatchTouchEvent(event) + + verify(statusBarTouchShadeDisplayPolicy).onStatusBarTouched(eq(event), any()) + } + + @Test + @DisableFlags(ShadeWindowGoesAround.FLAG_NAME) + fun onTouch_withMouseOnSystemIcons_flagOff_notPropagatedToShadeDisplayPolicy() { + val view = createViewMock() + InstrumentationRegistry.getInstrumentation().runOnMainSync { + controller = createAndInitController(view) + } + val event = getActionUpEventFromSource(InputDevice.SOURCE_MOUSE) + + val statusContainer = view.requireViewById<View>(R.id.system_icons) + statusContainer.dispatchTouchEvent(event) + + verify(statusBarTouchShadeDisplayPolicy, never()).onStatusBarTouched(eq(event), any()) + } + + @Test fun shadeIsExpandedOnStatusIconMouseClick() { val view = createViewMock() InstrumentationRegistry.getInstrumentation().runOnMainSync { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java index 3247a1ab6eb0..8ff8fe6cc3d6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java @@ -44,6 +44,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.R; import com.android.internal.view.RotationPolicy; +import com.android.settingslib.devicestate.AndroidSecureSettings; import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; @@ -117,7 +118,8 @@ public class DeviceStateRotationLockSettingControllerTest extends SysuiTestCase ArgumentCaptor.forClass(DeviceStateManager.DeviceStateCallback.class); mContentResolver = mContext.getContentResolver(); - mSettingsManager = DeviceStateRotationLockSettingsManager.getInstance(mContext); + mSettingsManager = new DeviceStateRotationLockSettingsManager(mContext, + new AndroidSecureSettings(mContentResolver)); mDeviceStateRotationLockSettingController = new DeviceStateRotationLockSettingController( mFakeRotationPolicy, diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt index 54df9e99baa5..bb6ba46f1a0b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt @@ -25,13 +25,12 @@ import android.view.WindowManager import android.view.accessibility.AccessibilityManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.internal.logging.InstanceId import com.android.internal.logging.testing.UiEventLoggerFake +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager -import com.android.systemui.res.R import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener import com.android.systemui.util.concurrency.DelayableExecutor @@ -78,7 +77,7 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() { @Mock private lateinit var dumpManager: DumpManager @Mock - private lateinit var windowManager: ViewCaptureAwareWindowManager + private lateinit var windowManager: WindowManager @Mock private lateinit var powerManager: PowerManager @@ -1143,7 +1142,7 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() { inner class TestController( context: Context, logger: TemporaryViewLogger<ViewInfo>, - viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager, + windowManager: WindowManager, @Main mainExecutor: DelayableExecutor, accessibilityManager: AccessibilityManager, configurationController: ConfigurationController, @@ -1155,7 +1154,7 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() { ) : TemporaryViewDisplayController<ViewInfo, TemporaryViewLogger<ViewInfo>>( context, logger, - viewCaptureAwareWindowManager, + windowManager, mainExecutor, accessibilityManager, configurationController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt index 4260b6558950..664f2df62782 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt @@ -30,8 +30,6 @@ import android.widget.TextView import androidx.core.animation.doOnCancel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.app.viewcapture.ViewCapture -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.internal.logging.InstanceId import com.android.internal.logging.testing.UiEventLoggerFake import com.android.systemui.SysuiTestCase @@ -86,7 +84,6 @@ class ChipbarCoordinatorTest : SysuiTestCase() { @Mock private lateinit var viewUtil: ViewUtil @Mock private lateinit var vibratorHelper: VibratorHelper @Mock private lateinit var swipeGestureHandler: SwipeChipbarAwayGestureHandler - @Mock private lateinit var lazyViewCapture: Lazy<ViewCapture> private lateinit var chipbarAnimator: TestChipbarAnimator private lateinit var fakeWakeLockBuilder: WakeLockFake.Builder private lateinit var fakeWakeLock: WakeLockFake @@ -115,8 +112,7 @@ class ChipbarCoordinatorTest : SysuiTestCase() { ChipbarCoordinator( context, logger, - ViewCaptureAwareWindowManager(windowManager, lazyViewCapture, - isViewCaptureEnabled = false), + windowManager, fakeExecutor, accessibilityManager, configurationController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/WindowManagerProviderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/utils/WindowManagerProviderImplTest.kt new file mode 100644 index 000000000000..7b52237f0a01 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/utils/WindowManagerProviderImplTest.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2025 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.utils + +import android.platform.test.annotations.DisableFlags +import android.platform.test.annotations.EnableFlags +import android.view.WindowManager +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.Flags +import com.android.systemui.SysuiTestCase +import com.android.systemui.utils.windowmanager.WindowManagerProviderImpl +import com.google.common.truth.Truth.assertThat +import org.junit.runner.RunWith +import org.junit.Test + +@RunWith(AndroidJUnit4::class) +@SmallTest +class WindowManagerProviderImplTest : SysuiTestCase() { + + private val windowManagerProvider = WindowManagerProviderImpl() + private val windowManagerFromSystemService = mContext.getSystemService(WindowManager::class.java) + + @Test + @EnableFlags(Flags.FLAG_ENABLE_VIEW_CAPTURE_TRACING) + fun viewCaptureTracingEnabled_verifyWMInstanceDoesNotMatchContextOne() { + val windowManagerFromProvider = windowManagerProvider.getWindowManager(mContext) + assertThat(windowManagerFromProvider).isNotEqualTo(windowManagerFromSystemService) + } + + @Test + @DisableFlags(Flags.FLAG_ENABLE_VIEW_CAPTURE_TRACING) + fun viewCaptureTracingDisabled_verifyWMInstanceMatchesContextOne() { + mContext.addMockSystemService(WindowManager::class.java, windowManagerFromSystemService) + + val windowManagerFromProvider = windowManagerProvider.getWindowManager(mContext) + assertThat(windowManagerFromProvider).isEqualTo(windowManagerFromSystemService) + } +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index 0d7ce5353cd4..f89571f2db2d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -101,8 +101,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.test.filters.SmallTest; -import com.android.app.viewcapture.ViewCapture; -import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.logging.UiEventLogger; import com.android.internal.protolog.ProtoLog; @@ -358,8 +356,6 @@ public class BubblesTest extends SysuiTestCase { @Mock private Display mDefaultDisplay; @Mock - private Lazy<ViewCapture> mLazyViewCapture; - @Mock private SyncTransactionQueue mSyncQueue; private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this); @@ -429,8 +425,7 @@ public class BubblesTest extends SysuiTestCase { mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl( mContext, new FakeWindowRootViewComponent.Factory(mNotificationShadeWindowView), - new ViewCaptureAwareWindowManager(mWindowManager, mLazyViewCapture, - /* isViewCaptureEnabled= */ false), + mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController, diff --git a/packages/SystemUI/tests/utils/src/com/android/app/viewcapture/ViewCaptureAwareWindowManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/app/viewcapture/ViewCaptureAwareWindowManagerKosmos.kt deleted file mode 100644 index 021c7bbb44cd..000000000000 --- a/packages/SystemUI/tests/utils/src/com/android/app/viewcapture/ViewCaptureAwareWindowManagerKosmos.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2024 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.app.viewcapture - -import android.view.fakeWindowManager -import com.android.systemui.kosmos.Kosmos -import org.mockito.kotlin.mock - -val Kosmos.mockViewCaptureAwareWindowManager by - Kosmos.Fixture { mock<ViewCaptureAwareWindowManager>() } - -val Kosmos.realCaptureAwareWindowManager by - Kosmos.Fixture { - ViewCaptureAwareWindowManager( - fakeWindowManager, - lazyViewCapture = lazy { mock<ViewCapture>() }, - isViewCaptureEnabled = false, - ) - } - -var Kosmos.viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager by - Kosmos.Fixture { mockViewCaptureAwareWindowManager } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStoreKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStoreKosmos.kt index aae32cfaafa6..f83fcb32aafe 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStoreKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStoreKosmos.kt @@ -16,8 +16,6 @@ package com.android.systemui.statusbar.data.repository -import android.view.WindowManager -import com.android.app.viewcapture.ViewCaptureAwareWindowManager import com.android.systemui.display.data.repository.displayRepository import com.android.systemui.display.data.repository.displayWindowPropertiesRepository import com.android.systemui.kosmos.Kosmos @@ -35,14 +33,6 @@ val Kosmos.privacyDotWindowControllerStoreImpl by windowControllerFactory = { _, _, _, _ -> mock() }, displayWindowPropertiesRepository = displayWindowPropertiesRepository, privacyDotViewControllerStore = privacyDotViewControllerStore, - viewCaptureAwareWindowManagerFactory = - object : ViewCaptureAwareWindowManager.Factory { - override fun create( - windowManager: WindowManager - ): ViewCaptureAwareWindowManager { - return mock() - } - }, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/PrivacyDotWindowControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/PrivacyDotWindowControllerKosmos.kt index c73838708a7a..da4027e46783 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/PrivacyDotWindowControllerKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/PrivacyDotWindowControllerKosmos.kt @@ -17,8 +17,8 @@ package com.android.systemui.statusbar.events import android.content.testableContext +import android.view.fakeWindowManager import android.view.layoutInflater -import com.android.app.viewcapture.realCaptureAwareWindowManager import com.android.systemui.concurrency.fakeExecutor import com.android.systemui.decor.privacyDotDecorProviderFactory import com.android.systemui.kosmos.Kosmos @@ -28,7 +28,7 @@ var Kosmos.privacyDotWindowController by PrivacyDotWindowController( testableContext.displayId, privacyDotViewController, - realCaptureAwareWindowManager, + fakeWindowManager, layoutInflater, fakeExecutor, privacyDotDecorProviderFactory, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/FakeStatusBarWindowControllerFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/FakeStatusBarWindowControllerFactory.kt index 3a19547f0713..f20fb3bf1779 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/FakeStatusBarWindowControllerFactory.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/FakeStatusBarWindowControllerFactory.kt @@ -17,14 +17,14 @@ package com.android.systemui.statusbar.window import android.content.Context -import com.android.app.viewcapture.ViewCaptureAwareWindowManager +import android.view.WindowManager import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController import com.android.systemui.statusbar.layout.StatusBarContentInsetsProvider class FakeStatusBarWindowControllerFactory : StatusBarWindowController.Factory { override fun create( context: Context, - viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager, + windowManager: WindowManager, statusBarConfigurationController: StatusBarConfigurationController, contentInsetsProvider: StatusBarContentInsetsProvider, ) = FakeStatusBarWindowController() diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/StatusBarWindowControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/StatusBarWindowControllerKosmos.kt index f595aef41e2d..b0214769362f 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/StatusBarWindowControllerKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/StatusBarWindowControllerKosmos.kt @@ -17,8 +17,8 @@ package com.android.systemui.statusbar.window import android.content.testableContext +import android.view.fakeWindowManager import android.view.windowManagerService -import com.android.app.viewcapture.realCaptureAwareWindowManager import com.android.systemui.concurrency.fakeExecutor import com.android.systemui.fragments.fragmentService import com.android.systemui.kosmos.Kosmos @@ -33,7 +33,7 @@ val Kosmos.statusBarWindowControllerImpl by StatusBarWindowControllerImpl( testableContext, statusBarWindowViewInflater, - realCaptureAwareWindowManager, + fakeWindowManager, statusBarConfigurationController, windowManagerService, statusBarContentInsetsProvider, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStoreKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStoreKosmos.kt index 4941ceb7991d..0f9310376b2a 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStoreKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStoreKosmos.kt @@ -16,9 +16,6 @@ package com.android.systemui.statusbar.window -import android.view.WindowManager -import com.android.app.viewcapture.ViewCaptureAwareWindowManager -import com.android.app.viewcapture.realCaptureAwareWindowManager import com.android.systemui.display.data.repository.displayRepository import com.android.systemui.display.data.repository.displayWindowPropertiesRepository import com.android.systemui.kosmos.Kosmos @@ -33,14 +30,6 @@ val Kosmos.multiDisplayStatusBarWindowControllerStore by backgroundApplicationScope = applicationCoroutineScope, controllerFactory = { _, _, _, _ -> mock() }, displayWindowPropertiesRepository = displayWindowPropertiesRepository, - viewCaptureAwareWindowManagerFactory = - object : ViewCaptureAwareWindowManager.Factory { - override fun create( - windowManager: WindowManager - ): ViewCaptureAwareWindowManager { - return realCaptureAwareWindowManager - } - }, statusBarConfigurationControllerStore = statusBarConfigurationControllerStore, statusBarContentInsetsProviderStore = statusBarContentInsetsProviderStore, displayRepository = displayRepository, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/windowmanager/FakeWindowManagerProvider.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/windowmanager/FakeWindowManagerProvider.kt new file mode 100644 index 000000000000..5c8eae3183c7 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/windowmanager/FakeWindowManagerProvider.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2025 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.utils.windowmanager + +import android.content.Context +import android.view.WindowManager + +/** Fake implementation of [WindowManagerProvider], to be used in tests only. */ +class FakeWindowManagerProvider(private val windowManager: WindowManager) : WindowManagerProvider { + + override fun getWindowManager(context: Context): WindowManager { + return windowManager + } +}
\ No newline at end of file diff --git a/packages/SystemUI/utils/Android.bp b/packages/SystemUI/utils/Android.bp index 1efb11b436ff..8b63c07b270f 100644 --- a/packages/SystemUI/utils/Android.bp +++ b/packages/SystemUI/utils/Android.bp @@ -26,6 +26,8 @@ java_library { "src/**/*.kt", ], static_libs: [ + "//frameworks/libs/systemui:view_capture", + "com_android_systemui_flags_lib", "kotlin-stdlib", "kotlinx_coroutines", ], diff --git a/packages/SystemUI/utils/src/com/android/systemui/utils/windowmanager/WindowManagerProvider.kt b/packages/SystemUI/utils/src/com/android/systemui/utils/windowmanager/WindowManagerProvider.kt new file mode 100644 index 000000000000..4e6eacbc8808 --- /dev/null +++ b/packages/SystemUI/utils/src/com/android/systemui/utils/windowmanager/WindowManagerProvider.kt @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2025 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.utils.windowmanager + +import android.content.Context +import android.view.WindowManager + +/** + * Provider for [WindowManager] in SystemUI. + * + * Use this class over [WindowManagerUtils] in cases where + * a [WindowManager] is needed for a context created inside the class. [WindowManagerUtils] should + * only be used in a class where the [WindowManager] is needed for a custom context inside the + * class, and the class is not part of the dagger graph. Example usage: + * ```kotlin + * class Sample { + * private final WindowManager mWindowManager; + * + * @Inject + * public Sample(WindowManagerProvider windowManagerProvider) { + * Context context = getCustomContext(); + * mWindowManager = windowManagerProvider.getWindowManager(context); + * } + * // use mWindowManager + * } + * + * class SampleTest { + * + * @Mock + * WindowManager mWindowManager; + * + * FakeWindowManagerProvider fakeProvider = new FakeWindowManagerProvider(mWindowManager); + * + * // define the behaviour of mWindowManager to get required WindowManager instance in tests. + * } + * ``` + */ +interface WindowManagerProvider { + + /** Method to return the required [WindowManager]. */ + fun getWindowManager(context: Context): WindowManager +} diff --git a/packages/SystemUI/utils/src/com/android/systemui/utils/windowmanager/WindowManagerProviderImpl.kt b/packages/SystemUI/utils/src/com/android/systemui/utils/windowmanager/WindowManagerProviderImpl.kt new file mode 100644 index 000000000000..5e965ed47403 --- /dev/null +++ b/packages/SystemUI/utils/src/com/android/systemui/utils/windowmanager/WindowManagerProviderImpl.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2025 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.utils.windowmanager + +import android.content.Context +import android.view.WindowManager + +/** Implementation of [WindowManagerProvider]. */ +class WindowManagerProviderImpl : WindowManagerProvider { + + override fun getWindowManager(context: Context): WindowManager { + return WindowManagerUtils.getWindowManager(context) + } +} diff --git a/packages/SystemUI/utils/src/com/android/systemui/utils/windowmanager/WindowManagerUtils.kt b/packages/SystemUI/utils/src/com/android/systemui/utils/windowmanager/WindowManagerUtils.kt new file mode 100644 index 000000000000..643e93422294 --- /dev/null +++ b/packages/SystemUI/utils/src/com/android/systemui/utils/windowmanager/WindowManagerUtils.kt @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2025 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.utils.windowmanager + +import android.content.Context +import android.view.WindowManager +import com.android.app.viewcapture.ViewCaptureAwareWindowManagerFactory +import com.android.systemui.Flags.enableViewCaptureTracing + +/** + * Provides [WindowManager] in SystemUI. Use [WindowManagerProvider] unless [WindowManager] instance + * needs to be created in a class that is not part of the dagger dependency graph. + */ +object WindowManagerUtils { + + /** Method to return the required [WindowManager]. */ + @JvmStatic + fun getWindowManager(context: Context): WindowManager { + return if (!enableViewCaptureTracing()) { + context.getSystemService(WindowManager::class.java) + } else { + /** + * We use this token to supply windowContextToken to [WindowManager] for + * [WindowContext]. + */ + val windowContextToken = context.windowContextToken + + ViewCaptureAwareWindowManagerFactory.getInstance( + context, + parent = null, + windowContextToken, + ) + } + } +} diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 29e04e744759..fa18d96d0dab 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -750,7 +750,8 @@ public class InputManagerService extends IInputManager.Stub * @return True if the lookup was successful, false otherwise. */ @Override // Binder call - public boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists) { + public boolean hasKeys(int deviceId, int sourceMask, @NonNull int[] keyCodes, + @NonNull boolean[] keyExists) { Objects.requireNonNull(keyCodes, "keyCodes must not be null"); Objects.requireNonNull(keyExists, "keyExists must not be null"); if (keyExists.length < keyCodes.length) { @@ -791,7 +792,7 @@ public class InputManagerService extends IInputManager.Stub * @deprecated Use {@link #transferTouchGesture(IBinder, IBinder)} */ @Deprecated - public boolean transferTouch(IBinder destChannelToken, int displayId) { + public boolean transferTouch(@NonNull IBinder destChannelToken, int displayId) { // TODO(b/162194035): Replace this with a SPY window Objects.requireNonNull(destChannelToken, "destChannelToken must not be null"); return mNative.transferTouch(destChannelToken, displayId); @@ -803,7 +804,7 @@ public class InputManagerService extends IInputManager.Stub * @param displayId Target display id. * @return The input channel. */ - public InputChannel monitorInput(String inputChannelName, int displayId) { + public InputChannel monitorInput(@NonNull String inputChannelName, int displayId) { Objects.requireNonNull(inputChannelName, "inputChannelName not be null"); if (displayId < Display.DEFAULT_DISPLAY) { @@ -835,7 +836,7 @@ public class InputManagerService extends IInputManager.Stub return outInputChannel; } - private void removeSpyWindowGestureMonitor(IBinder inputChannelToken) { + private void removeSpyWindowGestureMonitor(@NonNull IBinder inputChannelToken) { final GestureMonitorSpyWindow monitor; synchronized (mInputMonitors) { monitor = mInputMonitors.remove(inputChannelToken); @@ -854,8 +855,8 @@ public class InputManagerService extends IInputManager.Stub * @return The input channel. */ @Override // Binder call - public InputMonitor monitorGestureInput(IBinder monitorToken, @NonNull String requestedName, - int displayId) { + public InputMonitor monitorGestureInput(@NonNull IBinder monitorToken, + @NonNull String requestedName, int displayId) { if (!checkCallingPermission(android.Manifest.permission.MONITOR_INPUT, "monitorGestureInput()")) { throw new SecurityException("Requires MONITOR_INPUT permission"); @@ -902,7 +903,7 @@ public class InputManagerService extends IInputManager.Stub * Removes an input channel. * @param connectionToken The input channel to unregister. */ - public void removeInputChannel(IBinder connectionToken) { + public void removeInputChannel(@NonNull IBinder connectionToken) { Objects.requireNonNull(connectionToken, "connectionToken must not be null"); mNative.removeInputChannel(connectionToken); } @@ -977,12 +978,12 @@ public class InputManagerService extends IInputManager.Stub } @Override // Binder call - public boolean injectInputEvent(InputEvent event, int mode) { + public boolean injectInputEvent(@NonNull InputEvent event, int mode) { return injectInputEventToTarget(event, mode, Process.INVALID_UID); } @Override // Binder call - public boolean injectInputEventToTarget(InputEvent event, int mode, int targetUid) { + public boolean injectInputEventToTarget(@NonNull InputEvent event, int mode, int targetUid) { if (!checkCallingPermission(android.Manifest.permission.INJECT_EVENTS, "injectInputEvent()", true /*checkInstrumentationSource*/)) { throw new SecurityException( @@ -1032,7 +1033,7 @@ public class InputManagerService extends IInputManager.Stub } @Override // Binder call - public VerifiedInputEvent verifyInputEvent(InputEvent event) { + public VerifiedInputEvent verifyInputEvent(@NonNull InputEvent event) { Objects.requireNonNull(event, "event must not be null"); return mNative.verifyInputEvent(event); } @@ -1106,7 +1107,8 @@ public class InputManagerService extends IInputManager.Stub } @Override // Binder call - public void registerInputDevicesChangedListener(IInputDevicesChangedListener listener) { + public void registerInputDevicesChangedListener( + @NonNull IInputDevicesChangedListener listener) { Objects.requireNonNull(listener, "listener must not be null"); synchronized (mInputDevicesLock) { @@ -1176,7 +1178,7 @@ public class InputManagerService extends IInputManager.Stub } @Override // Binder call & native callback - public TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor, + public TouchCalibration getTouchCalibrationForInputDevice(@NonNull String inputDeviceDescriptor, int surfaceRotation) { Objects.requireNonNull(inputDeviceDescriptor, "inputDeviceDescriptor must not be null"); @@ -1186,8 +1188,8 @@ public class InputManagerService extends IInputManager.Stub } @Override // Binder call - public void setTouchCalibrationForInputDevice(String inputDeviceDescriptor, int surfaceRotation, - TouchCalibration calibration) { + public void setTouchCalibrationForInputDevice(@NonNull String inputDeviceDescriptor, + int surfaceRotation, @NonNull TouchCalibration calibration) { if (!checkCallingPermission(android.Manifest.permission.SET_INPUT_CALIBRATION, "setTouchCalibrationForInputDevice()")) { throw new SecurityException("Requires SET_INPUT_CALIBRATION permission"); @@ -1225,7 +1227,7 @@ public class InputManagerService extends IInputManager.Stub } @Override // Binder call - public void registerTabletModeChangedListener(ITabletModeChangedListener listener) { + public void registerTabletModeChangedListener(@NonNull ITabletModeChangedListener listener) { if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE, "registerTabletModeChangedListener()")) { throw new SecurityException("Requires TABLET_MODE_LISTENER permission"); @@ -1341,7 +1343,7 @@ public class InputManagerService extends IInputManager.Stub } @Override - public void requestPointerCapture(IBinder inputChannelToken, boolean enabled) { + public void requestPointerCapture(@NonNull IBinder inputChannelToken, boolean enabled) { Objects.requireNonNull(inputChannelToken, "inputChannelToken must not be null"); mNative.requestPointerCapture(inputChannelToken, enabled); @@ -1664,7 +1666,8 @@ public class InputManagerService extends IInputManager.Stub } @Override // Binder call - public boolean registerVibratorStateListener(int deviceId, IVibratorStateListener listener) { + public boolean registerVibratorStateListener(int deviceId, + @NonNull IVibratorStateListener listener) { Objects.requireNonNull(listener, "listener must not be null"); RemoteCallbackList<IVibratorStateListener> listeners; @@ -1717,8 +1720,8 @@ public class InputManagerService extends IInputManager.Stub // Binder call @Override - public boolean setPointerIcon(PointerIcon icon, int displayId, int deviceId, int pointerId, - IBinder inputToken) { + public boolean setPointerIcon(@NonNull PointerIcon icon, int displayId, int deviceId, + int pointerId, IBinder inputToken) { Objects.requireNonNull(icon); return mNative.setPointerIcon(icon, displayId, deviceId, pointerId, inputToken); } @@ -1896,7 +1899,7 @@ public class InputManagerService extends IInputManager.Stub } @Override // Binder call - public boolean registerSensorListener(IInputSensorEventListener listener) { + public boolean registerSensorListener(@NonNull IInputSensorEventListener listener) { if (DEBUG) { Slog.d(TAG, "registerSensorListener: listener=" + listener + " callingPid=" + Binder.getCallingPid()); @@ -1927,7 +1930,7 @@ public class InputManagerService extends IInputManager.Stub } @Override // Binder call - public void unregisterSensorListener(IInputSensorEventListener listener) { + public void unregisterSensorListener(@NonNull IInputSensorEventListener listener) { if (DEBUG) { Slog.d(TAG, "unregisterSensorListener: listener=" + listener + " callingPid=" + Binder.getCallingPid()); @@ -2016,7 +2019,8 @@ public class InputManagerService extends IInputManager.Stub /** * Set specified light state with for a specific input device. */ - private void setLightStateInternal(int deviceId, Light light, LightState lightState) { + private void setLightStateInternal(int deviceId, @NonNull Light light, + @NonNull LightState lightState) { Objects.requireNonNull(light, "light does not exist"); if (DEBUG) { Slog.d(TAG, "setLightStateInternal device " + deviceId + " light " + light @@ -2079,7 +2083,7 @@ public class InputManagerService extends IInputManager.Stub } @Override - public void openLightSession(int deviceId, String opPkg, IBinder token) { + public void openLightSession(int deviceId, String opPkg, @NonNull IBinder token) { Objects.requireNonNull(token); synchronized (mLightLock) { Preconditions.checkState(mLightSessions.get(token) == null, "already registered"); @@ -2098,7 +2102,7 @@ public class InputManagerService extends IInputManager.Stub } @Override - public void closeLightSession(int deviceId, IBinder token) { + public void closeLightSession(int deviceId, @NonNull IBinder token) { Objects.requireNonNull(token); synchronized (mLightLock) { LightSession lightSession = mLightSessions.get(token); @@ -2128,13 +2132,15 @@ public class InputManagerService extends IInputManager.Stub } @Override - public void registerBatteryListener(int deviceId, IInputDeviceBatteryListener listener) { + public void registerBatteryListener(int deviceId, + @NonNull IInputDeviceBatteryListener listener) { Objects.requireNonNull(listener); mBatteryController.registerBatteryListener(deviceId, listener, Binder.getCallingPid()); } @Override - public void unregisterBatteryListener(int deviceId, IInputDeviceBatteryListener listener) { + public void unregisterBatteryListener(int deviceId, + @NonNull IInputDeviceBatteryListener listener) { Objects.requireNonNull(listener); mBatteryController.unregisterBatteryListener(deviceId, listener, Binder.getCallingPid()); } @@ -2155,7 +2161,7 @@ public class InputManagerService extends IInputManager.Stub @EnforcePermission(Manifest.permission.MONITOR_INPUT) @Override - public void pilferPointers(IBinder inputChannelToken) { + public void pilferPointers(@NonNull IBinder inputChannelToken) { super.pilferPointers_enforcePermission(); Objects.requireNonNull(inputChannelToken); @@ -2164,7 +2170,7 @@ public class InputManagerService extends IInputManager.Stub @Override @EnforcePermission(Manifest.permission.MONITOR_KEYBOARD_BACKLIGHT) - public void registerKeyboardBacklightListener(IKeyboardBacklightListener listener) { + public void registerKeyboardBacklightListener(@NonNull IKeyboardBacklightListener listener) { super.registerKeyboardBacklightListener_enforcePermission(); Objects.requireNonNull(listener); mKeyboardBacklightController.registerKeyboardBacklightListener(listener, @@ -2173,7 +2179,7 @@ public class InputManagerService extends IInputManager.Stub @Override @EnforcePermission(Manifest.permission.MONITOR_KEYBOARD_BACKLIGHT) - public void unregisterKeyboardBacklightListener(IKeyboardBacklightListener listener) { + public void unregisterKeyboardBacklightListener(@NonNull IKeyboardBacklightListener listener) { super.unregisterKeyboardBacklightListener_enforcePermission(); Objects.requireNonNull(listener); mKeyboardBacklightController.unregisterKeyboardBacklightListener(listener, @@ -3429,7 +3435,7 @@ public class InputManagerService extends IInputManager.Stub } @Override - public void sendInputEvent(InputEvent event, int policyFlags) { + public void sendInputEvent(@NonNull InputEvent event, int policyFlags) { if (!checkCallingPermission(android.Manifest.permission.INJECT_EVENTS, "sendInputEvent()")) { throw new SecurityException( @@ -3451,9 +3457,9 @@ public class InputManagerService extends IInputManager.Stub * Interface for the system to handle request from InputMonitors. */ private final class InputMonitorHost extends IInputMonitorHost.Stub { - private final IBinder mInputChannelToken; + private final @NonNull IBinder mInputChannelToken; - InputMonitorHost(IBinder inputChannelToken) { + InputMonitorHost(@NonNull IBinder inputChannelToken) { mInputChannelToken = inputChannelToken; } diff --git a/services/core/java/com/android/server/media/projection/TEST_MAPPING b/services/core/java/com/android/server/media/projection/TEST_MAPPING index b33097c50002..7061044aaeee 100644 --- a/services/core/java/com/android/server/media/projection/TEST_MAPPING +++ b/services/core/java/com/android/server/media/projection/TEST_MAPPING @@ -2,6 +2,34 @@ "presubmit": [ { "name": "MediaProjectionTests" + }, + { + "name": "CtsMediaProjectionTestCases" + }, + { + "name": "CtsMediaProjectionSDK33TestCases" + }, + { + "name": "CtsMediaProjectionSDK34TestCases" + }, + { + "name": "CtsMediaAudioTestCases", + "options": [ + { + "include-filter": "android.media.audio.cts.RemoteSubmixTest" + }, + { + "include-filter": "android.media.audio.cts.AudioPlaybackCaptureTest" + } + ] + }, + { + "name": "CtsStatsdAtomHostTestCases", + "options": [ + { + "include-filter": "android.cts.statsdatom.media.projection.MediaProjectionAtomsTests" + } + ] } ] } diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index 8d787fe99e3a..651111e431c3 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -985,8 +985,8 @@ public final class OverlayManagerService extends SystemService { final String pkgName = request.overlay.getPackageName(); if (callingUid != Process.ROOT_UID && !ArrayUtils.contains( mPackageManager.getPackagesForUid(callingUid), pkgName)) { - throw new IllegalArgumentException("UID " + callingUid + " does own package" - + "name " + pkgName); + throw new IllegalArgumentException("UID " + callingUid + " does not own " + + "packageName " + pkgName); } } else { // Enforce actor requirements for enabling, disabling, and reordering overlays. diff --git a/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java b/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java index e989d6875d15..4c14e96e6c98 100644 --- a/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java +++ b/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java @@ -36,6 +36,7 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.SparseArray; +import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; import com.android.internal.util.function.DodecFunction; import com.android.internal.util.function.HexConsumer; @@ -141,150 +142,191 @@ public interface AccessCheckDelegate extends CheckPermissionDelegate, CheckOpsDe class AccessCheckDelegateImpl implements AccessCheckDelegate { public static final String SHELL_PKG = "com.android.shell"; + + private final Object mLock = new Object(); + + @GuardedBy("mLock") private int mDelegateAndOwnerUid = INVALID_UID; @Nullable + @GuardedBy("mLock") private String mDelegatePackage; @Nullable + @GuardedBy("mLock") private String[] mDelegatePermissions; + @GuardedBy("mLock") boolean mDelegateAllPermissions; @Nullable + @GuardedBy("mLock") private SparseArray<ArrayMap<String, Integer>> mOverridePermissionStates; @Override public void setShellPermissionDelegate(int uid, @NonNull String packageName, @Nullable String[] permissions) { - mDelegateAndOwnerUid = uid; - mDelegatePackage = packageName; - mDelegatePermissions = permissions; - mDelegateAllPermissions = permissions == null; + synchronized (mLock) { + mDelegateAndOwnerUid = uid; + mDelegatePackage = packageName; + mDelegatePermissions = permissions; + mDelegateAllPermissions = permissions == null; + } PackageManager.invalidatePackageInfoCache(); } @Override public void removeShellPermissionDelegate() { - mDelegatePackage = null; - mDelegatePermissions = null; - mDelegateAllPermissions = false; + synchronized (mLock) { + mDelegatePackage = null; + mDelegatePermissions = null; + mDelegateAllPermissions = false; + } PackageManager.invalidatePackageInfoCache(); } @Override public void addOverridePermissionState(int ownerUid, int uid, @NonNull String permission, int state) { - if (mOverridePermissionStates == null) { - mDelegateAndOwnerUid = ownerUid; - mOverridePermissionStates = new SparseArray<>(); - } + synchronized (mLock) { + if (mOverridePermissionStates == null) { + mDelegateAndOwnerUid = ownerUid; + mOverridePermissionStates = new SparseArray<>(); + } - int uidIdx = mOverridePermissionStates.indexOfKey(uid); - ArrayMap<String, Integer> perUidOverrides; - if (uidIdx < 0) { - perUidOverrides = new ArrayMap<>(); - mOverridePermissionStates.put(uid, perUidOverrides); - } else { - perUidOverrides = mOverridePermissionStates.valueAt(uidIdx); - } + int uidIdx = mOverridePermissionStates.indexOfKey(uid); + ArrayMap<String, Integer> perUidOverrides; + if (uidIdx < 0) { + perUidOverrides = new ArrayMap<>(); + mOverridePermissionStates.put(uid, perUidOverrides); + } else { + perUidOverrides = mOverridePermissionStates.valueAt(uidIdx); + } - perUidOverrides.put(permission, state); + perUidOverrides.put(permission, state); + } PackageManager.invalidatePackageInfoCache(); } @Override public void removeOverridePermissionState(int uid, @NonNull String permission) { - if (mOverridePermissionStates == null) { - return; - } + synchronized (mLock) { + if (mOverridePermissionStates == null) { + return; + } - ArrayMap<String, Integer> perUidOverrides = mOverridePermissionStates.get(uid); + ArrayMap<String, Integer> perUidOverrides = mOverridePermissionStates.get(uid); - if (perUidOverrides == null) { - return; - } + if (perUidOverrides == null) { + return; + } - perUidOverrides.remove(permission); - PackageManager.invalidatePackageInfoCache(); + perUidOverrides.remove(permission); - if (perUidOverrides.isEmpty()) { - mOverridePermissionStates.remove(uid); - } - if (mOverridePermissionStates.size() == 0) { - mOverridePermissionStates = null; + if (perUidOverrides.isEmpty()) { + mOverridePermissionStates.remove(uid); + } + if (mOverridePermissionStates.size() == 0) { + mOverridePermissionStates = null; + } } + PackageManager.invalidatePackageInfoCache(); } @Override public void clearOverridePermissionStates(int uid) { - if (mOverridePermissionStates == null) { - return; - } + synchronized (mLock) { + if (mOverridePermissionStates == null) { + return; + } - mOverridePermissionStates.remove(uid); - PackageManager.invalidatePackageInfoCache(); + mOverridePermissionStates.remove(uid); - if (mOverridePermissionStates.size() == 0) { - mOverridePermissionStates = null; + if (mOverridePermissionStates.size() == 0) { + mOverridePermissionStates = null; + } } + PackageManager.invalidatePackageInfoCache(); } @Override public void clearAllOverridePermissionStates() { - mOverridePermissionStates = null; + synchronized (mLock) { + mOverridePermissionStates = null; + } PackageManager.invalidatePackageInfoCache(); } @Override public List<String> getDelegatedPermissionNames() { - return mDelegatePermissions == null ? null : List.of(mDelegatePermissions); + synchronized (mLock) { + return mDelegatePermissions == null ? null : List.of(mDelegatePermissions); + } } @Override public boolean hasShellPermissionDelegate() { - return mDelegateAllPermissions || mDelegatePermissions != null; + synchronized (mLock) { + return mDelegateAllPermissions || mDelegatePermissions != null; + } } @Override public boolean isDelegatePackage(int uid, @NonNull String packageName) { - return mDelegateAndOwnerUid == uid && TextUtils.equals(mDelegatePackage, packageName); + synchronized (mLock) { + return mDelegateAndOwnerUid == uid + && TextUtils.equals(mDelegatePackage, packageName); + } } @Override public boolean hasOverriddenPermissions() { - return mOverridePermissionStates != null; + synchronized (mLock) { + return mOverridePermissionStates != null; + } } @Override public boolean isDelegateAndOwnerUid(int uid) { - return uid == mDelegateAndOwnerUid; + synchronized (mLock) { + return uid == mDelegateAndOwnerUid; + } } @Override public boolean hasDelegateOrOverrides() { - return hasShellPermissionDelegate() || hasOverriddenPermissions(); + synchronized (mLock) { + return hasShellPermissionDelegate() || hasOverriddenPermissions(); + } } @Override public int checkPermission(@NonNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId, @UserIdInt int userId, @NonNull QuadFunction<String, String, String, Integer, Integer> superImpl) { - if (TextUtils.equals(mDelegatePackage, packageName) && !SHELL_PKG.equals(packageName)) { - if (isDelegatePermission(permissionName)) { - final long identity = Binder.clearCallingIdentity(); - try { - return checkPermission(SHELL_PKG, permissionName, persistentDeviceId, - userId, superImpl); - } finally { - Binder.restoreCallingIdentity(identity); + boolean useShellDelegate; + + synchronized (mLock) { + useShellDelegate = !SHELL_PKG.equals(packageName) + && TextUtils.equals(mDelegatePackage, packageName) + && isDelegatePermission(permissionName); + + if (!useShellDelegate && mOverridePermissionStates != null) { + int uid = LocalServices.getService(PackageManagerInternal.class) + .getPackageUid(packageName, 0, userId); + if (uid >= 0) { + Map<String, Integer> permissionGrants = mOverridePermissionStates.get(uid); + if (permissionGrants != null + && permissionGrants.containsKey(permissionName)) { + return permissionGrants.get(permissionName); + } } } } - if (mOverridePermissionStates != null) { - int uid = LocalServices.getService(PackageManagerInternal.class) - .getPackageUid(packageName, 0, userId); - if (uid >= 0) { - Map<String, Integer> permissionGrants = mOverridePermissionStates.get(uid); - if (permissionGrants != null && permissionGrants.containsKey(permissionName)) { - return permissionGrants.get(permissionName); - } + + if (useShellDelegate) { + final long identity = Binder.clearCallingIdentity(); + try { + return checkPermission(SHELL_PKG, permissionName, persistentDeviceId, userId, + superImpl); + } finally { + Binder.restoreCallingIdentity(identity); } } return superImpl.apply(packageName, permissionName, persistentDeviceId, userId); @@ -294,21 +336,27 @@ public interface AccessCheckDelegate extends CheckPermissionDelegate, CheckOpsDe public int checkUidPermission(int uid, @NonNull String permissionName, @NonNull String persistentDeviceId, @NonNull TriFunction<Integer, String, String, Integer> superImpl) { - if (uid == mDelegateAndOwnerUid && uid != Process.SHELL_UID) { - if (isDelegatePermission(permissionName)) { - final long identity = Binder.clearCallingIdentity(); - try { - return checkUidPermission(Process.SHELL_UID, permissionName, - persistentDeviceId, superImpl); - } finally { - Binder.restoreCallingIdentity(identity); + boolean useShellDelegate; + + synchronized (mLock) { + useShellDelegate = uid != Process.SHELL_UID && uid == mDelegateAndOwnerUid + && isDelegatePermission(permissionName); + + if (!useShellDelegate && mOverridePermissionStates != null) { + Map<String, Integer> permissionGrants = mOverridePermissionStates.get(uid); + if (permissionGrants != null && permissionGrants.containsKey(permissionName)) { + return permissionGrants.get(permissionName); } } } - if (mOverridePermissionStates != null) { - Map<String, Integer> permissionGrants = mOverridePermissionStates.get(uid); - if (permissionGrants != null && permissionGrants.containsKey(permissionName)) { - return permissionGrants.get(permissionName); + + if (useShellDelegate) { + final long identity = Binder.clearCallingIdentity(); + try { + return checkUidPermission(Process.SHELL_UID, permissionName, persistentDeviceId, + superImpl); + } finally { + Binder.restoreCallingIdentity(identity); } } return superImpl.apply(uid, permissionName, persistentDeviceId); @@ -319,7 +367,13 @@ public interface AccessCheckDelegate extends CheckPermissionDelegate, CheckOpsDe @Nullable String attributionTag, int virtualDeviceId, boolean raw, @NonNull HexFunction<Integer, Integer, String, String, Integer, Boolean, Integer> superImpl) { - if (uid == mDelegateAndOwnerUid && isDelegateOp(code)) { + boolean useShellDelegate; + + synchronized (mLock) { + useShellDelegate = uid == mDelegateAndOwnerUid && isDelegateOp(code); + } + + if (useShellDelegate) { final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid), Process.SHELL_UID); final long identity = Binder.clearCallingIdentity(); @@ -335,7 +389,13 @@ public interface AccessCheckDelegate extends CheckPermissionDelegate, CheckOpsDe @Override public int checkAudioOperation(int code, int usage, int uid, @Nullable String packageName, @NonNull QuadFunction<Integer, Integer, Integer, String, Integer> superImpl) { - if (uid == mDelegateAndOwnerUid && isDelegateOp(code)) { + boolean useShellDelegate; + + synchronized (mLock) { + useShellDelegate = uid == mDelegateAndOwnerUid && isDelegateOp(code); + } + + if (useShellDelegate) { final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid), Process.SHELL_UID); final long identity = Binder.clearCallingIdentity(); @@ -354,7 +414,13 @@ public interface AccessCheckDelegate extends CheckPermissionDelegate, CheckOpsDe @Nullable String message, boolean shouldCollectMessage, int notedCount, @NonNull NonaFunction<Integer, Integer, String, String, Integer, Boolean, String, Boolean, Integer, SyncNotedAppOp> superImpl) { - if (uid == mDelegateAndOwnerUid && isDelegateOp(code)) { + boolean useShellDelegate; + + synchronized (mLock) { + useShellDelegate = uid == mDelegateAndOwnerUid && isDelegateOp(code); + } + + if (useShellDelegate) { final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid), Process.SHELL_UID); final long identity = Binder.clearCallingIdentity(); @@ -375,21 +441,29 @@ public interface AccessCheckDelegate extends CheckPermissionDelegate, CheckOpsDe @Nullable String message, boolean shouldCollectMessage, boolean skiProxyOperation, @NonNull HexFunction<Integer, AttributionSource, Boolean, String, Boolean, Boolean, SyncNotedAppOp> superImpl) { - if (!isDelegateOp(code)) { - return superImpl.apply(code, attributionSource, shouldCollectAsyncNotedOp, - message, shouldCollectMessage, skiProxyOperation); + boolean isDelegateOp; + int delegateAndOwnerUid; + + synchronized (mLock) { + isDelegateOp = isDelegateOp(code); + delegateAndOwnerUid = mDelegateAndOwnerUid; + } + + if (!isDelegateOp) { + return superImpl.apply(code, attributionSource, shouldCollectAsyncNotedOp, message, + shouldCollectMessage, skiProxyOperation); } final int shellUid = UserHandle.getUid( UserHandle.getUserId(attributionSource.getUid()), Process.SHELL_UID); AttributionSource next = attributionSource.getNext(); - if (next != null && next.getUid() == mDelegateAndOwnerUid) { + if (next != null && next.getUid() == delegateAndOwnerUid) { next = new AttributionSource(shellUid, Process.INVALID_PID, SHELL_PKG, next.getAttributionTag(), next.getToken(), /*renouncedPermissions*/ null, next.getDeviceId(), next.getNext()); attributionSource = new AttributionSource(attributionSource, next); } - if (attributionSource.getUid() == mDelegateAndOwnerUid) { + if (attributionSource.getUid() == delegateAndOwnerUid) { attributionSource = new AttributionSource(shellUid, Process.INVALID_PID, SHELL_PKG, attributionSource.getAttributionTag(), attributionSource.getToken(), /*renouncedPermissions*/ null, @@ -397,9 +471,8 @@ public interface AccessCheckDelegate extends CheckPermissionDelegate, CheckOpsDe } final long identity = Binder.clearCallingIdentity(); try { - return superImpl.apply(code, attributionSource, - shouldCollectAsyncNotedOp, message, shouldCollectMessage, - skiProxyOperation); + return superImpl.apply(code, attributionSource, shouldCollectAsyncNotedOp, message, + shouldCollectMessage, skiProxyOperation); } finally { Binder.restoreCallingIdentity(identity); } @@ -413,7 +486,13 @@ public interface AccessCheckDelegate extends CheckPermissionDelegate, CheckOpsDe @AttributionFlags int attributionFlags, int attributionChainId, @NonNull DodecFunction<IBinder, Integer, Integer, String, String, Integer, Boolean, Boolean, String, Boolean, Integer, Integer, SyncNotedAppOp> superImpl) { - if (uid == mDelegateAndOwnerUid && isDelegateOp(code)) { + boolean useShellDelegate; + + synchronized (mLock) { + useShellDelegate = uid == mDelegateAndOwnerUid && isDelegateOp(code); + } + + if (useShellDelegate) { final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid), Process.SHELL_UID); final long identity = Binder.clearCallingIdentity(); @@ -440,7 +519,14 @@ public interface AccessCheckDelegate extends CheckPermissionDelegate, CheckOpsDe @NonNull UndecFunction<IBinder, Integer, AttributionSource, Boolean, Boolean, String, Boolean, Boolean, Integer, Integer, Integer, SyncNotedAppOp> superImpl) { - if (attributionSource.getUid() == mDelegateAndOwnerUid && isDelegateOp(code)) { + boolean useShellDelegate; + + synchronized (mLock) { + useShellDelegate = attributionSource.getUid() == mDelegateAndOwnerUid + && isDelegateOp(code); + } + + if (useShellDelegate) { final int shellUid = UserHandle.getUid(UserHandle.getUserId( attributionSource.getUid()), Process.SHELL_UID); final long identity = Binder.clearCallingIdentity(); @@ -467,7 +553,14 @@ public interface AccessCheckDelegate extends CheckPermissionDelegate, CheckOpsDe @NonNull AttributionSource attributionSource, boolean skipProxyOperation, @NonNull QuadFunction<IBinder, Integer, AttributionSource, Boolean, Void> superImpl) { - if (attributionSource.getUid() == mDelegateAndOwnerUid && isDelegateOp(code)) { + boolean useShellDelegate; + + synchronized (mLock) { + useShellDelegate = attributionSource.getUid() == mDelegateAndOwnerUid + && isDelegateOp(code); + } + + if (useShellDelegate) { final int shellUid = UserHandle.getUid(UserHandle.getUserId( attributionSource.getUid()), Process.SHELL_UID); final long identity = Binder.clearCallingIdentity(); @@ -490,7 +583,13 @@ public interface AccessCheckDelegate extends CheckPermissionDelegate, CheckOpsDe public void finishOperation(IBinder clientId, int code, int uid, String packageName, String attributionTag, int virtualDeviceId, @NonNull HexConsumer<IBinder, Integer, Integer, String, String, Integer> superImpl) { - if (uid == mDelegateAndOwnerUid && isDelegateOp(code)) { + boolean useShellDelegate; + + synchronized (mLock) { + useShellDelegate = uid == mDelegateAndOwnerUid && isDelegateOp(code); + } + + if (useShellDelegate) { final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid), Process.SHELL_UID); final long identity = Binder.clearCallingIdentity(); diff --git a/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java b/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java index cb82f480d73b..d152a1dbe17d 100644 --- a/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java +++ b/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java @@ -35,6 +35,7 @@ import static com.android.server.wm.AppCompatUtils.isChangeEnabled; import android.annotation.NonNull; import android.annotation.Nullable; +import android.window.DesktopModeFlags; import com.android.server.wm.utils.OptPropFactory; import com.android.window.flags.Flags; @@ -177,7 +178,7 @@ class AppCompatCameraOverrides { * </ul> */ boolean shouldApplyFreeformTreatmentForCameraCompat() { - return Flags.enableCameraCompatForDesktopWindowing() + return DesktopModeFlags.ENABLE_CAMERA_COMPAT_SIMULATE_REQUESTED_ORIENTATION.isTrue() && (shouldEnableCameraCompatFreeformTreatmentForApp() || shouldEnableCameraCompatFreeformTreatmentForAllApps()); } diff --git a/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java b/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java index 276c7d2cbaa0..e7a0803df916 100644 --- a/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java +++ b/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java @@ -26,9 +26,9 @@ import android.app.CameraCompatTaskInfo; import android.content.pm.ActivityInfo.ScreenOrientation; import android.content.res.Configuration; import android.widget.Toast; +import android.window.DesktopModeFlags; import com.android.internal.annotations.VisibleForTesting; -import com.android.window.flags.Flags; /** * Encapsulate policy logic related to app compat display rotation. @@ -53,7 +53,7 @@ class AppCompatCameraPolicy { final boolean needsDisplayRotationCompatPolicy = wmService.mAppCompatConfiguration.isCameraCompatTreatmentEnabledAtBuildTime(); final boolean needsCameraCompatFreeformPolicy = - Flags.enableCameraCompatForDesktopWindowing() + DesktopModeFlags.ENABLE_CAMERA_COMPAT_SIMULATE_REQUESTED_ORIENTATION.isTrue() && DesktopModeHelper.canEnterDesktopMode(wmService.mContext); if (needsDisplayRotationCompatPolicy || needsCameraCompatFreeformPolicy) { mCameraStateMonitor = new CameraStateMonitor(displayContent, wmService.mH); diff --git a/services/core/java/com/android/server/wm/DeviceStateAutoRotateSettingIssueLogger.java b/services/core/java/com/android/server/wm/DeviceStateAutoRotateSettingIssueLogger.java index 937039d838e5..a7d03485058f 100644 --- a/services/core/java/com/android/server/wm/DeviceStateAutoRotateSettingIssueLogger.java +++ b/services/core/java/com/android/server/wm/DeviceStateAutoRotateSettingIssueLogger.java @@ -29,13 +29,13 @@ import java.util.function.LongSupplier; /** * Logs potential race conditions that lead to incorrect auto-rotate setting. * - * Before go/auto-rotate-refactor, there is a race condition that happen during device state + * <p>Before go/auto-rotate-refactor, there is a race condition that happen during device state * changes, as a result, incorrect auto-rotate setting are written for a device state in * DEVICE_STATE_ROTATION_LOCK. Realistically, users shouldn’t be able to change * DEVICE_STATE_ROTATION_LOCK while the device folds/unfolds. * - * This class monitors the time between a device state change and a subsequent change to the device - * state based auto-rotate setting. If the duration is less than a threshold + * <p>This class monitors the time between a device state change and a subsequent change to the + * device state based auto-rotate setting. If the duration is less than a threshold * (DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_THRESHOLD), a potential issue is logged. The logging of * the atom is not expected to occur often, realistically estimated once a month on few devices. * But the number could be bigger, as that's what this metric is set to reveal. @@ -72,23 +72,33 @@ public class DeviceStateAutoRotateSettingIssueLogger { } private void onStateChange() { - // Only move forward if both of the events have occurred already - if (mLastDeviceStateChangeTime != TIME_NOT_SET - && mLastDeviceStateAutoRotateSettingChangeTime != TIME_NOT_SET) { - final long duration = - mLastDeviceStateAutoRotateSettingChangeTime - mLastDeviceStateChangeTime; - boolean isDeviceStateChangeFirst = duration > 0; + // Only move forward if both of the events have occurred already. + if (mLastDeviceStateChangeTime == TIME_NOT_SET + || mLastDeviceStateAutoRotateSettingChangeTime == TIME_NOT_SET) { + return; + } + final long duration = + mLastDeviceStateAutoRotateSettingChangeTime - mLastDeviceStateChangeTime; + boolean isDeviceStateChangeFirst = duration > 0; - if (abs(duration) - < DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_THRESHOLD_MILLIS) { - FrameworkStatsLog.write( - FrameworkStatsLog.DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_REPORTED, - (int) abs(duration), - isDeviceStateChangeFirst); - } + if (abs(duration) + < DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_THRESHOLD_MILLIS) { + FrameworkStatsLog.write( + FrameworkStatsLog.DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_REPORTED, + (int) abs(duration), + isDeviceStateChangeFirst); + // This pair is logged, reset both timestamps. mLastDeviceStateAutoRotateSettingChangeTime = TIME_NOT_SET; mLastDeviceStateChangeTime = TIME_NOT_SET; + } else { + // This pair was not logged, reset the earlier timestamp. + if (isDeviceStateChangeFirst) { + mLastDeviceStateChangeTime = TIME_NOT_SET; + } else { + mLastDeviceStateAutoRotateSettingChangeTime = TIME_NOT_SET; + } } + } } diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java index 3289d70b89ac..fe4baeb80ee7 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java @@ -79,7 +79,8 @@ import java.util.ArrayList; public class ApplicationStartInfoTest { private static final String TAG = ApplicationStartInfoTest.class.getSimpleName(); - private static final ComponentName COMPONENT = new ComponentName("com.android.test", ".Foo"); + private static final ComponentName COMPONENT = + new ComponentName("com.android.test", "com.android.test.Foo"); private static final int APP_1_UID = 10123; private static final int APP_1_PID_1 = 12345; diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java index e0bc3e76f31d..457d8a96fea4 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java @@ -87,6 +87,9 @@ import android.content.res.XmlResourceParser; import android.graphics.drawable.Icon; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerGlobal; +import android.hardware.input.IInputManager; +import android.hardware.input.InputManager; +import android.hardware.input.InputManagerGlobal; import android.hardware.input.KeyGestureEvent; import android.net.Uri; import android.os.Build; @@ -237,6 +240,9 @@ public class AccessibilityManagerServiceTest { @Mock private HearingDevicePhoneCallNotificationController mMockHearingDevicePhoneCallNotificationController; + @Mock + private IInputManager mMockInputManagerService; + private InputManagerGlobal.TestSession mInputManagerTestSession; @Spy private IUserInitializationCompleteCallback mUserInitializationCompleteCallback; @Captor private ArgumentCaptor<Intent> mIntentArgumentCaptor; private IAccessibilityManager mA11yManagerServiceOnDevice; @@ -270,6 +276,10 @@ public class AccessibilityManagerServiceTest { mInputFilter = mock(FakeInputFilter.class); mTestableContext.addMockSystemService(DevicePolicyManager.class, mDevicePolicyManager); + mInputManagerTestSession = InputManagerGlobal.createTestSession(mMockInputManagerService); + InputManager mockInputManager = new InputManager(mTestableContext); + mTestableContext.addMockSystemService(InputManager.class, mockInputManager); + when(mMockPackageManagerInternal.getSystemUiServiceComponent()).thenReturn( new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService")); when(mMockPackageManagerInternal.getPackageUid(eq("com.android.systemui"), anyLong(), @@ -334,6 +344,9 @@ public class AccessibilityManagerServiceTest { FieldSetter.setField( am, AccessibilityManager.class.getDeclaredField("mService"), mA11yManagerServiceOnDevice); + if (mInputManagerTestSession != null) { + mInputManagerTestSession.close(); + } } private void setupAccessibilityServiceConnection(int serviceInfoFlag) { diff --git a/services/tests/wmtests/src/com/android/server/wm/DeviceStateAutoRotateSettingIssueLoggerTests.java b/services/tests/wmtests/src/com/android/server/wm/DeviceStateAutoRotateSettingIssueLoggerTests.java index f76a9cdbb894..ba9bf1bf8045 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DeviceStateAutoRotateSettingIssueLoggerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DeviceStateAutoRotateSettingIssueLoggerTests.java @@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import android.platform.test.annotations.Presubmit; @@ -143,4 +144,46 @@ public class DeviceStateAutoRotateSettingIssueLoggerTests { anyInt(), anyBoolean()), never()); } + + @Test + public void onStateChange_issueOccurredSettingChangedTwice_reportOnlyOnce() { + mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); + mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateChange(); + mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); + + verify(() -> + FrameworkStatsLog.write( + eq(FrameworkStatsLog.DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_REPORTED), + anyInt(), + anyBoolean()), times(1)); + } + + @Test + public void onStateChange_issueOccurredDeviceStateChangedTwice_reportOnlyOnce() { + mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateChange(); + mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); + mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateChange(); + + verify(() -> + FrameworkStatsLog.write( + eq(FrameworkStatsLog.DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_REPORTED), + anyInt(), + anyBoolean()), times(1)); + } + + @Test + public void onStateChange_issueOccurredAfterDelay_reportOnce() { + mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); + mTestTimeSupplier.delay( + DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_THRESHOLD_MILLIS + DELAY); + mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateChange(); + mTestTimeSupplier.delay(DELAY); + mDeviceStateAutoRotateSettingIssueLogger.onDeviceStateAutoRotateSettingChange(); + + verify(() -> + FrameworkStatsLog.write( + eq(FrameworkStatsLog.DEVICE_STATE_AUTO_ROTATE_SETTING_ISSUE_REPORTED), + eq(DELAY), + anyBoolean()), times(1)); + } } |