diff options
73 files changed, 1495 insertions, 2224 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 51cdfc538663..8a08c024de76 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -23779,6 +23779,8 @@ package android.media { field public static final int TYPE_DOCK = 13; // 0xd field public static final int TYPE_GROUP = 2000; // 0x7d0 field public static final int TYPE_HDMI = 9; // 0x9 + field @FlaggedApi("com.android.media.flags.enable_audio_policies_device_and_bluetooth_controller") public static final int TYPE_HDMI_ARC = 10; // 0xa + field @FlaggedApi("com.android.media.flags.enable_audio_policies_device_and_bluetooth_controller") public static final int TYPE_HDMI_EARC = 29; // 0x1d field public static final int TYPE_HEARING_AID = 23; // 0x17 field public static final int TYPE_REMOTE_AUDIO_VIDEO_RECEIVER = 1003; // 0x3eb field public static final int TYPE_REMOTE_CAR = 1008; // 0x3f0 diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl index a3b82e935673..d7d654672abc 100644 --- a/core/java/android/app/IWallpaperManager.aidl +++ b/core/java/android/app/IWallpaperManager.aidl @@ -161,12 +161,6 @@ interface IWallpaperManager { */ boolean isWallpaperBackupEligible(int which, int userId); - /* - * Keyguard: register a callback for being notified that lock-state relevant - * wallpaper content has changed. - */ - boolean setLockWallpaperCallback(IWallpaperManagerCallback cb); - /** * Returns the colors used by the lock screen or system wallpaper. * @@ -253,13 +247,6 @@ interface IWallpaperManager { boolean isStaticWallpaper(int which); /** - * Temporary method for project b/197814683. - * Return true if the lockscreen wallpaper always uses a WallpaperService, not a static image. - * @hide - */ - boolean isLockscreenLiveWallpaperEnabled(); - - /** * Temporary method for project b/270726737. * Return true if the wallpaper supports different crops for different display dimensions. * @hide diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index e7a5b72eafc5..d660078a9ae7 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -313,7 +313,6 @@ public class WallpaperManager { private final Context mContext; private final boolean mWcgEnabled; private final ColorManagementProxy mCmProxy; - private static Boolean sIsLockscreenLiveWallpaperEnabled = null; private static Boolean sIsMultiCropEnabled = null; /** @@ -841,29 +840,14 @@ public class WallpaperManager { } /** + * TODO (b/305908217) remove * Temporary method for project b/197814683. * @return true if the lockscreen wallpaper always uses a wallpaperService, not a static image * @hide */ @TestApi public boolean isLockscreenLiveWallpaperEnabled() { - return isLockscreenLiveWallpaperEnabledHelper(); - } - - private static boolean isLockscreenLiveWallpaperEnabledHelper() { - if (sGlobals == null) { - sIsLockscreenLiveWallpaperEnabled = SystemProperties.getBoolean( - "persist.wm.debug.lockscreen_live_wallpaper", true); - } - if (sIsLockscreenLiveWallpaperEnabled == null) { - try { - sIsLockscreenLiveWallpaperEnabled = - sGlobals.mService.isLockscreenLiveWallpaperEnabled(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - return sIsLockscreenLiveWallpaperEnabled; + return true; } /** @@ -2446,12 +2430,7 @@ public class WallpaperManager { */ @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public void clearWallpaper() { - if (isLockscreenLiveWallpaperEnabled()) { - clearWallpaper(FLAG_LOCK | FLAG_SYSTEM, mContext.getUserId()); - return; - } - clearWallpaper(FLAG_LOCK, mContext.getUserId()); - clearWallpaper(FLAG_SYSTEM, mContext.getUserId()); + clearWallpaper(FLAG_LOCK | FLAG_SYSTEM, mContext.getUserId()); } /** @@ -2787,11 +2766,7 @@ public class WallpaperManager { */ @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public void clear() throws IOException { - if (isLockscreenLiveWallpaperEnabled()) { - clear(FLAG_SYSTEM | FLAG_LOCK); - return; - } - setStream(openDefaultWallpaper(mContext, FLAG_SYSTEM), null, false); + clear(FLAG_SYSTEM | FLAG_LOCK); } /** @@ -2816,16 +2791,7 @@ public class WallpaperManager { */ @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public void clear(@SetWallpaperFlags int which) throws IOException { - if (isLockscreenLiveWallpaperEnabled()) { - clearWallpaper(which, mContext.getUserId()); - return; - } - if ((which & FLAG_SYSTEM) != 0) { - clear(); - } - if ((which & FLAG_LOCK) != 0) { - clearWallpaper(FLAG_LOCK, mContext.getUserId()); - } + clearWallpaper(which, mContext.getUserId()); } /** @@ -2840,16 +2806,12 @@ public class WallpaperManager { public static InputStream openDefaultWallpaper(Context context, @SetWallpaperFlags int which) { final String whichProp; final int defaultResId; - if (which == FLAG_LOCK && !isLockscreenLiveWallpaperEnabledHelper()) { - /* Factory-default lock wallpapers are not yet supported - whichProp = PROP_LOCK_WALLPAPER; - defaultResId = com.android.internal.R.drawable.default_lock_wallpaper; - */ - return null; - } else { - whichProp = PROP_WALLPAPER; - defaultResId = com.android.internal.R.drawable.default_wallpaper; - } + /* Factory-default lock wallpapers are not yet supported. + whichProp = which == FLAG_LOCK ? PROP_LOCK_WALLPAPER : PROP_WALLPAPER; + defaultResId = which == FLAG_LOCK ? R.drawable.default_lock_wallpaper : .... + */ + whichProp = PROP_WALLPAPER; + defaultResId = R.drawable.default_wallpaper; final String path = SystemProperties.get(whichProp); final InputStream wallpaperInputStream = getWallpaperInputStream(path); if (wallpaperInputStream != null) { @@ -2988,25 +2950,6 @@ public class WallpaperManager { } /** - * Register a callback for lock wallpaper observation. Only the OS may use this. - * - * @return true on success; false on error. - * @hide - */ - public boolean setLockWallpaperCallback(IWallpaperManagerCallback callback) { - if (sGlobals.mService == null) { - Log.w(TAG, "WallpaperService not running"); - throw new RuntimeException(new DeadSystemException()); - } - - try { - return sGlobals.mService.setLockWallpaperCallback(callback); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** * Is the current system wallpaper eligible for backup? * * Only the OS itself may use this method. diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp index e111edc96580..acfb259d7359 100644 --- a/libs/WindowManager/Shell/tests/flicker/Android.bp +++ b/libs/WindowManager/Shell/tests/flicker/Android.bp @@ -220,19 +220,6 @@ android_test { } android_test { - name: "WMShellFlickerTestsPip", - defaults: ["WMShellFlickerTestsDefault"], - additional_manifests: ["manifests/AndroidManifestPip.xml"], - package_name: "com.android.wm.shell.flicker.pip", - instrumentation_target_package: "com.android.wm.shell.flicker.pip", - srcs: [ - ":WMShellFlickerTestsBase-src", - ":WMShellFlickerTestsPip3-src", - ":WMShellFlickerTestsPipCommon-src", - ], -} - -android_test { name: "WMShellFlickerTestsPip1", defaults: ["WMShellFlickerTestsDefault"], additional_manifests: ["manifests/AndroidManifestPip.xml"], diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java index 91fa873078fc..cccf6f1caca7 100644 --- a/media/java/android/media/MediaRoute2Info.java +++ b/media/java/android/media/MediaRoute2Info.java @@ -18,6 +18,9 @@ package android.media; import static android.media.MediaRouter2Utils.toUniqueId; +import static com.android.media.flags.Flags.FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER; + +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -141,6 +144,8 @@ public final class MediaRoute2Info implements Parcelable { TYPE_WIRED_HEADPHONES, TYPE_BLUETOOTH_A2DP, TYPE_HDMI, + TYPE_HDMI_ARC, + TYPE_HDMI_EARC, TYPE_USB_DEVICE, TYPE_USB_ACCESSORY, TYPE_DOCK, @@ -206,6 +211,22 @@ public final class MediaRoute2Info implements Parcelable { public static final int TYPE_HDMI = AudioDeviceInfo.TYPE_HDMI; /** + * Indicates the route is an Audio Return Channel of an HDMI connection. + * + * @see #getType + */ + @FlaggedApi(FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER) + public static final int TYPE_HDMI_ARC = AudioDeviceInfo.TYPE_HDMI_ARC; + + /** + * Indicates the route is an Enhanced Audio Return Channel of an HDMI connection. + * + * @see #getType + */ + @FlaggedApi(FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER) + public static final int TYPE_HDMI_EARC = AudioDeviceInfo.TYPE_HDMI_EARC; + + /** * Indicates the route is a USB audio device. * * @see #getType @@ -907,6 +928,10 @@ public final class MediaRoute2Info implements Parcelable { return "BLUETOOTH_A2DP"; case TYPE_HDMI: return "HDMI"; + case TYPE_HDMI_ARC: + return "HDMI_ARC"; + case TYPE_HDMI_EARC: + return "HDMI_EARC"; case TYPE_DOCK: return "DOCK"; case TYPE_USB_DEVICE: diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java index 159427bc2796..76a00acfa1c4 100644 --- a/media/java/android/media/MediaRouter2.java +++ b/media/java/android/media/MediaRouter2.java @@ -310,8 +310,11 @@ public final class MediaRouter2 { IMediaRouterService.Stub.asInterface( ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE)); + mSystemController = + new SystemRoutingController( + ProxyMediaRouter2Impl.getSystemSessionInfoImpl( + mMediaRouterService, clientPackageName)); mImpl = new ProxyMediaRouter2Impl(context, clientPackageName); - mSystemController = new SystemRoutingController(mImpl.getSystemSessionInfo()); } /** @@ -2057,13 +2060,7 @@ public final class MediaRouter2 { @Override public RoutingSessionInfo getSystemSessionInfo() { - RoutingSessionInfo result; - try { - result = mMediaRouterService.getSystemSessionInfoForPackage(mClientPackageName); - } catch (RemoteException ex) { - throw ex.rethrowFromSystemServer(); - } - return ensureClientPackageNameForSystemSession(result); + return getSystemSessionInfoImpl(mMediaRouterService, mClientPackageName); } /** @@ -2428,6 +2425,23 @@ public final class MediaRouter2 { } /** + * Retrieves the system session info for the given package. + * + * <p>The returned routing session is guaranteed to have a non-null {@link + * RoutingSessionInfo#getClientPackageName() client package name}. + * + * <p>Extracted into a static method to allow calling this from the constructor. + */ + /* package */ static RoutingSessionInfo getSystemSessionInfoImpl( + @NonNull IMediaRouterService service, @NonNull String clientPackageName) { + try { + return service.getSystemSessionInfoForPackage(clientPackageName); + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } + } + + /** * Sets the routing session's {@linkplain RoutingSessionInfo#getClientPackageName() client * package name} to {@link #mClientPackageName} if empty and returns the session. * diff --git a/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java b/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java index e38e041a87dc..2a2841745fa0 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java @@ -39,39 +39,50 @@ public class DeviceIconUtil { @DrawableRes private static final int DEFAULT_ICON = R.drawable.ic_smartphone; public DeviceIconUtil() { - List<Device> deviceList = Arrays.asList( - new Device( - AudioDeviceInfo.TYPE_USB_DEVICE, - MediaRoute2Info.TYPE_USB_DEVICE, - R.drawable.ic_headphone), - new Device( - AudioDeviceInfo.TYPE_USB_HEADSET, - MediaRoute2Info.TYPE_USB_HEADSET, - R.drawable.ic_headphone), - new Device( - AudioDeviceInfo.TYPE_USB_ACCESSORY, - MediaRoute2Info.TYPE_USB_ACCESSORY, - R.drawable.ic_headphone), - new Device( - AudioDeviceInfo.TYPE_DOCK, - MediaRoute2Info.TYPE_DOCK, - R.drawable.ic_dock_device), - new Device( - AudioDeviceInfo.TYPE_HDMI, - MediaRoute2Info.TYPE_HDMI, - R.drawable.ic_headphone), - new Device( - AudioDeviceInfo.TYPE_WIRED_HEADSET, - MediaRoute2Info.TYPE_WIRED_HEADSET, - R.drawable.ic_headphone), - new Device( - AudioDeviceInfo.TYPE_WIRED_HEADPHONES, - MediaRoute2Info.TYPE_WIRED_HEADPHONES, - R.drawable.ic_headphone), - new Device( - AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, - MediaRoute2Info.TYPE_BUILTIN_SPEAKER, - R.drawable.ic_smartphone)); + List<Device> deviceList = + Arrays.asList( + new Device( + AudioDeviceInfo.TYPE_USB_DEVICE, + MediaRoute2Info.TYPE_USB_DEVICE, + R.drawable.ic_headphone), + new Device( + AudioDeviceInfo.TYPE_USB_HEADSET, + MediaRoute2Info.TYPE_USB_HEADSET, + R.drawable.ic_headphone), + new Device( + AudioDeviceInfo.TYPE_USB_ACCESSORY, + MediaRoute2Info.TYPE_USB_ACCESSORY, + R.drawable.ic_headphone), + new Device( + AudioDeviceInfo.TYPE_DOCK, + MediaRoute2Info.TYPE_DOCK, + R.drawable.ic_dock_device), + new Device( + AudioDeviceInfo.TYPE_HDMI, + MediaRoute2Info.TYPE_HDMI, + R.drawable.ic_headphone), + // TODO: b/306359110 - Put proper iconography for HDMI_ARC type. + new Device( + AudioDeviceInfo.TYPE_HDMI_ARC, + MediaRoute2Info.TYPE_HDMI_ARC, + R.drawable.ic_headphone), + // TODO: b/306359110 - Put proper iconography for HDMI_EARC type. + new Device( + AudioDeviceInfo.TYPE_HDMI_EARC, + MediaRoute2Info.TYPE_HDMI_EARC, + R.drawable.ic_headphone), + new Device( + AudioDeviceInfo.TYPE_WIRED_HEADSET, + MediaRoute2Info.TYPE_WIRED_HEADSET, + R.drawable.ic_headphone), + new Device( + AudioDeviceInfo.TYPE_WIRED_HEADPHONES, + MediaRoute2Info.TYPE_WIRED_HEADPHONES, + R.drawable.ic_headphone), + new Device( + AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, + MediaRoute2Info.TYPE_BUILTIN_SPEAKER, + R.drawable.ic_smartphone)); for (int i = 0; i < deviceList.size(); i++) { Device device = deviceList.get(i); mAudioDeviceTypeToIconMap.put(device.mAudioDeviceType, device); diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java index e2ba4eba6394..5dacba5357cd 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java @@ -21,6 +21,8 @@ import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER; import static android.media.MediaRoute2Info.TYPE_DOCK; import static android.media.MediaRoute2Info.TYPE_GROUP; import static android.media.MediaRoute2Info.TYPE_HDMI; +import static android.media.MediaRoute2Info.TYPE_HDMI_ARC; +import static android.media.MediaRoute2Info.TYPE_HDMI_EARC; import static android.media.MediaRoute2Info.TYPE_HEARING_AID; import static android.media.MediaRoute2Info.TYPE_REMOTE_AUDIO_VIDEO_RECEIVER; import static android.media.MediaRoute2Info.TYPE_REMOTE_CAR; @@ -635,6 +637,8 @@ public abstract class InfoMediaManager extends MediaManager { case TYPE_USB_ACCESSORY: case TYPE_DOCK: case TYPE_HDMI: + case TYPE_HDMI_ARC: + case TYPE_HDMI_EARC: case TYPE_WIRED_HEADSET: case TYPE_WIRED_HEADPHONES: mediaDevice = @@ -672,8 +676,8 @@ public abstract class InfoMediaManager extends MediaManager { default: Log.w(TAG, "addMediaDevice() unknown device type : " + deviceType); break; - } + if (mediaDevice != null && !TextUtils.isEmpty(mPackageName) && getRoutingSessionInfo().getSelectedRoutes().contains(route.getId())) { mediaDevice.setState(STATE_SELECTED); diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java index 147412d08d2c..8085c998abea 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java @@ -21,6 +21,8 @@ import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER; import static android.media.MediaRoute2Info.TYPE_DOCK; import static android.media.MediaRoute2Info.TYPE_GROUP; import static android.media.MediaRoute2Info.TYPE_HDMI; +import static android.media.MediaRoute2Info.TYPE_HDMI_ARC; +import static android.media.MediaRoute2Info.TYPE_HDMI_EARC; import static android.media.MediaRoute2Info.TYPE_HEARING_AID; import static android.media.MediaRoute2Info.TYPE_REMOTE_AUDIO_VIDEO_RECEIVER; import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER; @@ -140,7 +142,6 @@ public abstract class MediaDevice implements Comparable<MediaDevice> { mType = MediaDeviceType.TYPE_BLUETOOTH_DEVICE; return; } - switch (info.getType()) { case TYPE_GROUP: mType = MediaDeviceType.TYPE_CAST_GROUP_DEVICE; @@ -157,6 +158,8 @@ public abstract class MediaDevice implements Comparable<MediaDevice> { case TYPE_USB_ACCESSORY: case TYPE_DOCK: case TYPE_HDMI: + case TYPE_HDMI_ARC: + case TYPE_HDMI_EARC: mType = MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE; break; case TYPE_HEARING_AID: diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java index a63bbdf36fa8..c44f66e99d00 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java @@ -18,6 +18,8 @@ package com.android.settingslib.media; import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER; import static android.media.MediaRoute2Info.TYPE_DOCK; import static android.media.MediaRoute2Info.TYPE_HDMI; +import static android.media.MediaRoute2Info.TYPE_HDMI_ARC; +import static android.media.MediaRoute2Info.TYPE_HDMI_EARC; import static android.media.MediaRoute2Info.TYPE_USB_ACCESSORY; import static android.media.MediaRoute2Info.TYPE_USB_DEVICE; import static android.media.MediaRoute2Info.TYPE_USB_HEADSET; @@ -71,6 +73,8 @@ public class PhoneMediaDevice extends MediaDevice { name = context.getString(R.string.media_transfer_this_device_name); break; case TYPE_HDMI: + case TYPE_HDMI_ARC: + case TYPE_HDMI_EARC: name = context.getString(R.string.media_transfer_external_device_name); break; default: @@ -144,6 +148,8 @@ public class PhoneMediaDevice extends MediaDevice { case TYPE_USB_ACCESSORY: case TYPE_DOCK: case TYPE_HDMI: + case TYPE_HDMI_ARC: + case TYPE_HDMI_EARC: id = USB_HEADSET_ID; break; case TYPE_BUILTIN_SPEAKER: diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml index 8957903b29d4..0a2bd632e64a 100644 --- a/packages/SystemUI/res/layout/super_notification_shade.xml +++ b/packages/SystemUI/res/layout/super_notification_shade.xml @@ -26,24 +26,6 @@ android:layout_height="match_parent" android:fitsSystemWindows="true"> - <com.android.systemui.statusbar.BackDropView - android:id="@+id/backdrop" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:visibility="gone" - sysui:ignoreRightInset="true" - > - <ImageView android:id="@+id/backdrop_back" - android:layout_width="match_parent" - android:scaleType="centerCrop" - android:layout_height="match_parent" /> - <ImageView android:id="@+id/backdrop_front" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:scaleType="centerCrop" - android:visibility="invisible" /> - </com.android.systemui.statusbar.BackDropView> - <com.android.systemui.scrim.ScrimView android:id="@+id/scrim_behind" android:layout_width="match_parent" diff --git a/packages/SystemUI/res/values-land/config.xml b/packages/SystemUI/res/values-land/config.xml index 587caaf3ecf3..db526b187d38 100644 --- a/packages/SystemUI/res/values-land/config.xml +++ b/packages/SystemUI/res/values-land/config.xml @@ -46,4 +46,7 @@ For now, this value has effect only when flag lockscreen.enable_landscape is enabled. TODO (b/293252410) - change this comment/resource when flag is enabled --> <bool name="force_config_use_split_notification_shade">true</bool> + + <!-- Whether to show bottom sheets edge to edge --> + <bool name="config_edgeToEdgeBottomSheetDialog">false</bool> </resources> diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateRepository.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateRepository.kt new file mode 100644 index 000000000000..f219cece3ff8 --- /dev/null +++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateRepository.kt @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2023 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.unfold.system + +import com.android.systemui.unfold.dagger.UnfoldMain +import com.android.systemui.unfold.updates.FoldProvider +import com.android.systemui.unfold.updates.FoldProvider.FoldCallback +import java.util.concurrent.Executor +import javax.inject.Inject +import javax.inject.Singleton +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.buffer +import kotlinx.coroutines.flow.callbackFlow + +/** Provides whether the device is folded. */ +interface DeviceStateRepository { + val isFolded: Flow<Boolean> +} + +@Singleton +class DeviceStateRepositoryImpl +@Inject +constructor( + private val foldProvider: FoldProvider, + @UnfoldMain private val executor: Executor, +) : DeviceStateRepository { + + override val isFolded: Flow<Boolean> + get() = + callbackFlow { + val callback = FoldCallback { isFolded -> trySend(isFolded) } + foldProvider.registerCallback(callback, executor) + awaitClose { foldProvider.unregisterCallback(callback) } + } + .buffer(capacity = Channel.CONFLATED) +} diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt index fe607e16661c..7b67e3f3c920 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt @@ -48,6 +48,9 @@ abstract class SystemUnfoldSharedModule { abstract fun foldState(provider: DeviceStateManagerFoldProvider): FoldProvider @Binds + abstract fun deviceStateRepository(provider: DeviceStateRepositoryImpl): DeviceStateRepository + + @Binds @UnfoldMain abstract fun mainExecutor(@Main executor: Executor): Executor diff --git a/packages/SystemUI/shared/src/com/android/systemui/util/TraceStateLogger.kt b/packages/SystemUI/shared/src/com/android/systemui/util/TraceStateLogger.kt new file mode 100644 index 000000000000..63ea1165ee04 --- /dev/null +++ b/packages/SystemUI/shared/src/com/android/systemui/util/TraceStateLogger.kt @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2023 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.util + +import android.os.Trace + +/** + * Utility class used to log state changes easily in a track with a custom name. + * + * Example of usage: + * ```kotlin + * class MyClass { + * val screenStateLogger = TraceStateLogger("Screen state") + * + * fun onTurnedOn() { screenStateLogger.log("on") } + * fun onTurnedOff() { screenStateLogger.log("off") } + * } + * ``` + * + * This creates a new slice in a perfetto trace only if the state is different than the previous + * one. + */ +class TraceStateLogger( + private val trackName: String, + private val logOnlyIfDifferent: Boolean = true, + private val instantEvent: Boolean = true +) { + + private var previousValue: String? = null + + /** If needed, logs the value to a track with name [trackName]. */ + fun log(newValue: String) { + if (instantEvent) { + Trace.instantForTrack(Trace.TRACE_TAG_APP, trackName, newValue) + } + if (logOnlyIfDifferent && previousValue == newValue) return + Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, trackName, 0) + Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_APP, trackName, newValue, 0) + previousValue = newValue + } +} diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java index 0bf50693344a..7d73896bb370 100644 --- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java +++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java @@ -19,7 +19,6 @@ package com.android.systemui.colorextraction; import android.app.WallpaperColors; import android.app.WallpaperManager; import android.content.Context; -import android.graphics.Color; import android.os.UserHandle; import com.android.internal.annotations.VisibleForTesting; @@ -47,9 +46,7 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable, ConfigurationController.ConfigurationListener { private static final String TAG = "SysuiColorExtractor"; private final Tonal mTonal; - private boolean mHasMediaArtwork; private final GradientColors mNeutralColorsLock; - private final GradientColors mBackdropColors; private Lazy<SelectedUserInteractor> mUserInteractor; @Inject @@ -82,9 +79,6 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable, mNeutralColorsLock = new GradientColors(); configurationController.addCallback(this); dumpManager.registerDumpable(getClass().getSimpleName(), this); - - mBackdropColors = new GradientColors(); - mBackdropColors.setMainColor(Color.BLACK); mUserInteractor = userInteractor; // Listen to all users instead of only the current one. @@ -123,14 +117,6 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable, triggerColorsChanged(WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK); } - @Override - public GradientColors getColors(int which, int type) { - if (mHasMediaArtwork && (which & WallpaperManager.FLAG_LOCK) != 0) { - return mBackdropColors; - } - return super.getColors(which, type); - } - /** * Colors that should be using for scrims. * @@ -140,14 +126,7 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable, * - Black otherwise */ public GradientColors getNeutralColors() { - return mHasMediaArtwork ? mBackdropColors : mNeutralColorsLock; - } - - public void setHasMediaArtwork(boolean hasBackdrop) { - if (mHasMediaArtwork != hasBackdrop) { - mHasMediaArtwork = hasBackdrop; - triggerColorsChanged(WallpaperManager.FLAG_LOCK); - } + return mNeutralColorsLock; } @Override @@ -164,7 +143,5 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable, pw.println(" system: " + Arrays.toString(system)); pw.println(" lock: " + Arrays.toString(lock)); pw.println(" Neutral colors: " + mNeutralColorsLock); - pw.println(" Has media backdrop: " + mHasMediaArtwork); - } } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index 5d6949b3e87f..d8ff535ffd78 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -57,7 +57,6 @@ import com.android.systemui.statusbar.ImmersiveModeConfirmation import com.android.systemui.statusbar.gesture.GesturePointerEventListener import com.android.systemui.statusbar.notification.InstantAppNotifier import com.android.systemui.statusbar.phone.KeyguardLiftController -import com.android.systemui.statusbar.phone.LockscreenWallpaper import com.android.systemui.statusbar.phone.ScrimController import com.android.systemui.statusbar.phone.StatusBarHeadsUpChangeListener import com.android.systemui.stylus.StylusUsiPowerStartable @@ -344,11 +343,6 @@ abstract class SystemUICoreStartableModule { @Binds @IntoMap - @ClassKey(LockscreenWallpaper::class) - abstract fun bindLockscreenWallpaper(impl: LockscreenWallpaper): CoreStartable - - @Binds - @IntoMap @ClassKey(ScrimController::class) abstract fun bindScrimController(impl: ScrimController): CoreStartable diff --git a/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt b/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt index d19efbdd8026..3f215333382e 100644 --- a/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt @@ -21,6 +21,7 @@ import android.view.View import android.widget.TextView import com.android.systemui.res.R import com.android.systemui.statusbar.phone.SystemUIBottomSheetDialog +import com.android.systemui.statusbar.policy.ConfigurationController /** * Dialog used to decide what to do with a connected display. @@ -32,8 +33,9 @@ class MirroringConfirmationDialog( context: Context, private val onStartMirroringClickListener: View.OnClickListener, private val onCancelMirroring: View.OnClickListener, + configurationController: ConfigurationController? = null, theme: Int = R.style.Theme_SystemUI_Dialog, -) : SystemUIBottomSheetDialog(context, theme) { +) : SystemUIBottomSheetDialog(context, configurationController, theme) { private lateinit var mirrorButton: TextView private lateinit var dismissButton: TextView diff --git a/packages/SystemUI/src/com/android/systemui/display/ui/viewmodel/ConnectingDisplayViewModel.kt b/packages/SystemUI/src/com/android/systemui/display/ui/viewmodel/ConnectingDisplayViewModel.kt index 86ef439361b0..91f535df586a 100644 --- a/packages/SystemUI/src/com/android/systemui/display/ui/viewmodel/ConnectingDisplayViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/display/ui/viewmodel/ConnectingDisplayViewModel.kt @@ -23,6 +23,7 @@ import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor.PendingDisplay import com.android.systemui.display.ui.view.MirroringConfirmationDialog +import com.android.systemui.statusbar.policy.ConfigurationController import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope @@ -41,7 +42,8 @@ constructor( private val context: Context, private val connectedDisplayInteractor: ConnectedDisplayInteractor, @Application private val scope: CoroutineScope, - @Background private val bgDispatcher: CoroutineDispatcher + @Background private val bgDispatcher: CoroutineDispatcher, + private val configurationController: ConfigurationController ) { private var dialog: Dialog? = null @@ -71,7 +73,8 @@ constructor( onCancelMirroring = { scope.launch(bgDispatcher) { pendingDisplay.ignore() } hideDialog() - } + }, + configurationController ) .apply { show() } } diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index c91c9ac119af..10fac4d328e0 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -549,12 +549,6 @@ object Flags { val LOCKSCREEN_ENABLE_LANDSCAPE = unreleasedFlag("lockscreen.enable_landscape") - // TODO(b/273443374): Tracking Bug - @Keep - @JvmField - val LOCKSCREEN_LIVE_WALLPAPER = - sysPropBooleanFlag("persist.wm.debug.lockscreen_live_wallpaper", default = true) - // TODO(b/281648899): Tracking bug @Keep @JvmField diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index 47798955b43d..2b1cdc2ff026 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -202,7 +202,7 @@ public class KeyguardService extends Service { // Wrap Keyguard going away animation. // Note: Also used for wrapping occlude by Dream animation. It works (with some redundancy). public static IRemoteTransition wrap(final KeyguardViewMediator keyguardViewMediator, - final IRemoteAnimationRunner runner, final boolean lockscreenLiveWallpaperEnabled) { + final IRemoteAnimationRunner runner) { return new IRemoteTransition.Stub() { @GuardedBy("mLeashMap") @@ -236,9 +236,8 @@ public class KeyguardService extends Service { } } initAlphaForAnimationTargets(t, apps); - if (lockscreenLiveWallpaperEnabled) { - initAlphaForAnimationTargets(t, wallpapers); - } + initAlphaForAnimationTargets(t, wallpapers); + t.apply(); runner.onAnimationStart( diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt index 0bac40bcbcc1..c8c06ae65d45 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt @@ -707,8 +707,7 @@ class KeyguardUnlockAnimationController @Inject constructor( return@postDelayed } - if ((wallpaperTargets?.isNotEmpty() == true) && - wallpaperManager.isLockscreenLiveWallpaperEnabled()) { + if ((wallpaperTargets?.isNotEmpty() == true)) { fadeInWallpaper() hideKeyguardViewAfterRemoteAnimation() } else { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index e893c6305dee..4e6a872cb3f7 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -184,8 +184,6 @@ import java.util.Objects; import java.util.concurrent.Executor; import java.util.function.Consumer; - - import kotlinx.coroutines.CoroutineDispatcher; /** @@ -1517,12 +1515,11 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, setShowingLocked(false /* showing */, true /* forceCallbacks */); } - boolean isLLwpEnabled = getWallpaperManager().isLockscreenLiveWallpaperEnabled(); mKeyguardTransitions.register( - KeyguardService.wrap(this, getExitAnimationRunner(), isLLwpEnabled), - KeyguardService.wrap(this, getOccludeAnimationRunner(), isLLwpEnabled), - KeyguardService.wrap(this, getOccludeByDreamAnimationRunner(), isLLwpEnabled), - KeyguardService.wrap(this, getUnoccludeAnimationRunner(), isLLwpEnabled)); + KeyguardService.wrap(this, getExitAnimationRunner()), + KeyguardService.wrap(this, getOccludeAnimationRunner()), + KeyguardService.wrap(this, getOccludeByDreamAnimationRunner()), + KeyguardService.wrap(this, getUnoccludeAnimationRunner())); final ContentResolver cr = mContext.getContentResolver(); 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 d06f31fed8db..7e360cfad66d 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 @@ -26,13 +26,13 @@ import com.android.systemui.util.kotlin.Utils.Companion.toQuad import com.android.systemui.util.kotlin.Utils.Companion.toQuint import com.android.systemui.util.kotlin.sample import com.android.wm.shell.animation.Interpolators +import javax.inject.Inject +import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import javax.inject.Inject -import kotlin.time.Duration.Companion.milliseconds @SysUISingleton class FromAlternateBouncerTransitionInteractor @@ -130,11 +130,16 @@ constructor( override fun getDefaultAnimatorForTransitionsToState(toState: KeyguardState): ValueAnimator { return ValueAnimator().apply { interpolator = Interpolators.LINEAR - duration = TRANSITION_DURATION_MS.inWholeMilliseconds + duration = + when (toState) { + KeyguardState.GONE -> TO_GONE_DURATION + else -> TRANSITION_DURATION_MS + }.inWholeMilliseconds } } companion object { val TRANSITION_DURATION_MS = 300.milliseconds + val TO_GONE_DURATION = 500.milliseconds } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt index fbe26de4e9ba..b0b857729c77 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt @@ -143,6 +143,11 @@ constructor( val dozingToLockscreenTransition: Flow<TransitionStep> = repository.transition(DOZING, LOCKSCREEN) + /** Receive all [TransitionStep] matching a filter of [from]->[to] */ + fun transition(from: KeyguardState, to: KeyguardState): Flow<TransitionStep> { + return repository.transition(from, to) + } + /** * AOD<->LOCKSCREEN transition information, mapped to dozeAmount range of AOD (1f) <-> * Lockscreen (0f). diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModel.kt new file mode 100644 index 000000000000..023d16cab013 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModel.kt @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 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.keyguard.ui.viewmodel + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.keyguard.domain.interactor.FromAlternateBouncerTransitionInteractor.Companion.TO_GONE_DURATION +import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER +import com.android.systemui.keyguard.shared.model.ScrimAlpha +import javax.inject.Inject +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow + +/** + * Breaks down ALTERNATE_BOUNCER->GONE transition into discrete steps for corresponding views to + * consume. + */ +@OptIn(ExperimentalCoroutinesApi::class) +@SysUISingleton +class AlternateBouncerToGoneTransitionViewModel +@Inject +constructor( + bouncerToGoneFlows: BouncerToGoneFlows, +) { + + /** Scrim alpha values */ + val scrimAlpha: Flow<ScrimAlpha> = + bouncerToGoneFlows.scrimAlpha(TO_GONE_DURATION, ALTERNATE_BOUNCER) +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt new file mode 100644 index 000000000000..da74f2fa061e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2023 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.keyguard.ui.viewmodel + +import com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE +import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor +import com.android.systemui.flags.FeatureFlagsClassic +import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.KeyguardState.GONE +import com.android.systemui.keyguard.shared.model.ScrimAlpha +import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow +import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.statusbar.SysuiStatusBarStateController +import dagger.Lazy +import javax.inject.Inject +import kotlin.time.Duration +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.map + +/** ALTERNATE and PRIMARY bouncers common animations */ +@OptIn(ExperimentalCoroutinesApi::class) +class BouncerToGoneFlows +@Inject +constructor( + private val interactor: KeyguardTransitionInteractor, + private val statusBarStateController: SysuiStatusBarStateController, + private val primaryBouncerInteractor: PrimaryBouncerInteractor, + private val keyguardDismissActionInteractor: Lazy<KeyguardDismissActionInteractor>, + private val featureFlags: FeatureFlagsClassic, + private val shadeInteractor: ShadeInteractor, +) { + /** Common fade for scrim alpha values during *BOUNCER->GONE */ + fun scrimAlpha(duration: Duration, fromState: KeyguardState): Flow<ScrimAlpha> { + return if (featureFlags.isEnabled(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT)) { + keyguardDismissActionInteractor + .get() + .willAnimateDismissActionOnLockscreen + .flatMapLatest { createScrimAlphaFlow(duration, fromState) { it } } + } else { + createScrimAlphaFlow( + duration, + fromState, + primaryBouncerInteractor::willRunDismissFromKeyguard + ) + } + } + + private fun createScrimAlphaFlow( + duration: Duration, + fromState: KeyguardState, + willRunAnimationOnKeyguard: () -> Boolean + ): Flow<ScrimAlpha> { + var isShadeExpanded = false + var leaveShadeOpen: Boolean = false + var willRunDismissFromKeyguard: Boolean = false + val transitionAnimation = + KeyguardTransitionAnimationFlow( + transitionDuration = duration, + transitionFlow = interactor.transition(fromState, GONE) + ) + + return shadeInteractor.shadeExpansion.flatMapLatest { shadeExpansion -> + transitionAnimation + .createFlow( + duration = duration, + interpolator = EMPHASIZED_ACCELERATE, + onStart = { + leaveShadeOpen = statusBarStateController.leaveOpenOnKeyguardHide() + willRunDismissFromKeyguard = willRunAnimationOnKeyguard() + isShadeExpanded = shadeExpansion > 0f + }, + onStep = { 1f - it }, + ) + .map { + if (willRunDismissFromKeyguard) { + if (isShadeExpanded) { + ScrimAlpha( + behindAlpha = it, + notificationsAlpha = it, + ) + } else { + ScrimAlpha() + } + } else if (leaveShadeOpen) { + ScrimAlpha( + behindAlpha = 1f, + notificationsAlpha = 1f, + ) + } else { + ScrimAlpha(behindAlpha = it) + } + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt index 078318196883..0e95be20d059 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt @@ -16,7 +16,6 @@ package com.android.systemui.keyguard.ui.viewmodel -import com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlagsClassic @@ -24,6 +23,8 @@ import com.android.systemui.flags.Flags import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor.Companion.TO_GONE_DURATION import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState.GONE +import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER import com.android.systemui.keyguard.shared.model.ScrimAlpha import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow import com.android.systemui.statusbar.SysuiStatusBarStateController @@ -33,7 +34,6 @@ import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.map /** * Breaks down PRIMARY_BOUNCER->GONE transition into discrete steps for corresponding views to @@ -49,11 +49,12 @@ constructor( private val primaryBouncerInteractor: PrimaryBouncerInteractor, keyguardDismissActionInteractor: Lazy<KeyguardDismissActionInteractor>, featureFlags: FeatureFlagsClassic, + bouncerToGoneFlows: BouncerToGoneFlows, ) { private val transitionAnimation = KeyguardTransitionAnimationFlow( transitionDuration = TO_GONE_DURATION, - transitionFlow = interactor.primaryBouncerToGoneTransition, + transitionFlow = interactor.transition(PRIMARY_BOUNCER, GONE) ) private var leaveShadeOpen: Boolean = false @@ -110,38 +111,6 @@ constructor( ) } - /** Scrim alpha values */ val scrimAlpha: Flow<ScrimAlpha> = - if (featureFlags.isEnabled(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT)) { - keyguardDismissActionInteractor - .get() - .willAnimateDismissActionOnLockscreen - .flatMapLatest { createScrimAlphaFlow { it } } - } else { - createScrimAlphaFlow(primaryBouncerInteractor::willRunDismissFromKeyguard) - } - private fun createScrimAlphaFlow(willRunAnimationOnKeyguard: () -> Boolean): Flow<ScrimAlpha> { - return transitionAnimation - .createFlow( - duration = TO_GONE_DURATION, - interpolator = EMPHASIZED_ACCELERATE, - onStart = { - leaveShadeOpen = statusBarStateController.leaveOpenOnKeyguardHide() - willRunDismissFromKeyguard = willRunAnimationOnKeyguard() - }, - onStep = { 1f - it }, - ) - .map { - if (willRunDismissFromKeyguard) { - ScrimAlpha() - } else if (leaveShadeOpen) { - ScrimAlpha( - behindAlpha = 1f, - notificationsAlpha = 1f, - ) - } else { - ScrimAlpha(behindAlpha = it) - } - } - } + bouncerToGoneFlows.scrimAlpha(TO_GONE_DURATION, PRIMARY_BOUNCER) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BackDropView.java b/packages/SystemUI/src/com/android/systemui/statusbar/BackDropView.java deleted file mode 100644 index f1eb9febfb33..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BackDropView.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2014 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.statusbar; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.View; -import android.widget.FrameLayout; - -/** - * A view who contains media artwork. - */ -public class BackDropView extends FrameLayout -{ - private Runnable mOnVisibilityChangedRunnable; - - public BackDropView(Context context) { - super(context); - } - - public BackDropView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public BackDropView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public BackDropView(Context context, AttributeSet attrs, int defStyleAttr, - int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - @Override - public boolean hasOverlappingRendering() { - return false; - } - - @Override - protected void onVisibilityChanged(View changedView, int visibility) { - super.onVisibilityChanged(changedView, visibility); - if (changedView == this && mOnVisibilityChangedRunnable != null) { - mOnVisibilityChangedRunnable.run(); - } - } - - public void setOnVisibilityChangedRunnable(Runnable runnable) { - mOnVisibilityChangedRunnable = runnable; - } - -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java index f32f1c2dcd25..710e59d91c6b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java @@ -21,6 +21,7 @@ import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_ import static android.os.UserHandle.USER_NULL; import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS; import static android.provider.Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS; +import static android.os.Flags.allowPrivateProfile; import static com.android.systemui.DejankUtils.whitelistIpcs; @@ -79,6 +80,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.Executor; +import java.util.Objects; import javax.inject.Inject; @@ -177,57 +179,50 @@ public class NotificationLockscreenUserManagerImpl implements @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - switch (action) { - case Intent.ACTION_USER_REMOVED: - int removedUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); - if (removedUserId != -1) { - for (UserChangedListener listener : mListeners) { - listener.onUserRemoved(removedUserId); - } - } - updateCurrentProfilesCache(); - break; - case Intent.ACTION_USER_ADDED: - updateCurrentProfilesCache(); - if (mFeatureFlags.isEnabled(Flags.NOTIF_LS_BACKGROUND_THREAD)) { - final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL); - mBackgroundHandler.post(() -> { - initValuesForUser(userId); - }); - } - break; - case Intent.ACTION_MANAGED_PROFILE_AVAILABLE: - case Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE: - updateCurrentProfilesCache(); - break; - case Intent.ACTION_USER_UNLOCKED: - // Start the overview connection to the launcher service - // Connect if user hasn't connected yet - if (mOverviewProxyServiceLazy.get().getProxy() == null) { - mOverviewProxyServiceLazy.get().startConnectionToCurrentUser(); - } - break; - case NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION: - final IntentSender intentSender = intent.getParcelableExtra( - Intent.EXTRA_INTENT); - final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX); - if (intentSender != null) { - try { - ActivityOptions options = ActivityOptions.makeBasic(); - options.setPendingIntentBackgroundActivityStartMode( - ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED); - mContext.startIntentSender(intentSender, null, 0, 0, 0, - options.toBundle()); - } catch (IntentSender.SendIntentException e) { - /* ignore */ - } + if (Objects.equals(action, Intent.ACTION_USER_REMOVED)) { + int removedUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); + if (removedUserId != -1) { + for (UserChangedListener listener : mListeners) { + listener.onUserRemoved(removedUserId); } - if (notificationKey != null) { - final NotificationVisibility nv = mVisibilityProviderLazy.get() - .obtain(notificationKey, true); - mClickNotifier.onNotificationClick(notificationKey, nv); + } + updateCurrentProfilesCache(); + } else if (Objects.equals(action, Intent.ACTION_USER_ADDED)){ + updateCurrentProfilesCache(); + if (mFeatureFlags.isEnabled(Flags.NOTIF_LS_BACKGROUND_THREAD)) { + final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL); + mBackgroundHandler.post(() -> { + initValuesForUser(userId); + }); + } + } else if (profileAvailabilityActions(action)) { + updateCurrentProfilesCache(); + } else if (Objects.equals(action, Intent.ACTION_USER_UNLOCKED)) { + // Start the overview connection to the launcher service + // Connect if user hasn't connected yet + if (mOverviewProxyServiceLazy.get().getProxy() == null) { + mOverviewProxyServiceLazy.get().startConnectionToCurrentUser(); + } + } else if (Objects.equals(action, NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION)) { + final IntentSender intentSender = intent.getParcelableExtra( + Intent.EXTRA_INTENT); + final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX); + if (intentSender != null) { + try { + ActivityOptions options = ActivityOptions.makeBasic(); + options.setPendingIntentBackgroundActivityStartMode( + ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED); + mContext.startIntentSender(intentSender, null, 0, 0, 0, + options.toBundle()); + } catch (IntentSender.SendIntentException e) { + /* ignore */ } - break; + } + if (notificationKey != null) { + final NotificationVisibility nv = mVisibilityProviderLazy.get() + .obtain(notificationKey, true); + mClickNotifier.onNotificationClick(notificationKey, nv); + } } } }; @@ -403,6 +398,10 @@ public class NotificationLockscreenUserManagerImpl implements filter.addAction(Intent.ACTION_USER_UNLOCKED); filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); + if (allowPrivateProfile()){ + filter.addAction(Intent.ACTION_PROFILE_AVAILABLE); + filter.addAction(Intent.ACTION_PROFILE_UNAVAILABLE); + } mBroadcastDispatcher.registerReceiver(mBaseBroadcastReceiver, filter, null /* executor */, UserHandle.ALL); @@ -814,6 +813,14 @@ public class NotificationLockscreenUserManagerImpl implements } } + private boolean profileAvailabilityActions(String action){ + return allowPrivateProfile()? + Objects.equals(action,Intent.ACTION_PROFILE_AVAILABLE)|| + Objects.equals(action,Intent.ACTION_PROFILE_UNAVAILABLE): + Objects.equals(action,Intent.ACTION_MANAGED_PROFILE_AVAILABLE)|| + Objects.equals(action,Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); + } + @Override public void dump(PrintWriter pw, String[] args) { pw.println("NotificationLockscreenUserManager state:"); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java index 389486f0ada3..9c4625e91110 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java @@ -18,31 +18,21 @@ package com.android.systemui.statusbar; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Notification; -import android.app.WallpaperManager; import android.content.Context; -import android.graphics.Point; import android.graphics.drawable.Icon; -import android.hardware.display.DisplayManager; import android.media.MediaMetadata; import android.media.session.MediaController; import android.media.session.MediaSession; import android.media.session.PlaybackState; -import android.os.Trace; import android.service.notification.NotificationStats; import android.service.notification.StatusBarNotification; import android.util.Log; -import android.view.Display; -import android.view.View; -import android.widget.ImageView; -import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dumpable; -import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dump.DumpManager; import com.android.systemui.media.controls.models.player.MediaData; import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData; import com.android.systemui.media.controls.pipeline.MediaDataManager; -import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.dagger.CentralSurfacesModule; import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifPipeline; @@ -50,21 +40,13 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; -import com.android.systemui.statusbar.phone.BiometricUnlockController; -import com.android.systemui.statusbar.phone.LockscreenWallpaper; -import com.android.systemui.statusbar.phone.ScrimController; -import com.android.systemui.statusbar.policy.KeyguardStateController; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.Comparator; import java.util.HashSet; -import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.stream.Collectors; /** * Handles tasks and state related to media notifications. For example, there is a 'current' media @@ -74,9 +56,6 @@ public class NotificationMediaManager implements Dumpable { private static final String TAG = "NotificationMediaManager"; public static final boolean DEBUG_MEDIA = false; - private final StatusBarStateController mStatusBarStateController; - private final SysuiColorExtractor mColorExtractor; - private final KeyguardStateController mKeyguardStateController; private static final HashSet<Integer> PAUSED_MEDIA_STATES = new HashSet<>(); private static final HashSet<Integer> CONNECTING_MEDIA_STATES = new HashSet<>(); static { @@ -93,15 +72,6 @@ public class NotificationMediaManager implements Dumpable { private final NotifPipeline mNotifPipeline; private final NotifCollection mNotifCollection; - @Nullable - private BiometricUnlockController mBiometricUnlockController; - @Nullable - private ScrimController mScrimController; - @Nullable - private LockscreenWallpaper mLockscreenWallpaper; - @VisibleForTesting - boolean mIsLockscreenLiveWallpaperEnabled; - private final Context mContext; private final ArrayList<MediaListener> mMediaListeners; @@ -110,16 +80,6 @@ public class NotificationMediaManager implements Dumpable { private String mMediaNotificationKey; private MediaMetadata mMediaMetadata; - private BackDropView mBackdrop; - private ImageView mBackdropFront; - private ImageView mBackdropBack; - private final Point mTmpDisplaySize = new Point(); - - private final DisplayManager mDisplayManager; - @Nullable - private List<String> mSmallerInternalDisplayUids; - private Display mCurrentDisplay; - private final MediaController.Callback mMediaListener = new MediaController.Callback() { @Override public void onPlaybackStateChanged(PlaybackState state) { @@ -142,7 +102,7 @@ public class NotificationMediaManager implements Dumpable { Log.v(TAG, "DEBUG_MEDIA: onMetadataChanged: " + metadata); } mMediaMetadata = metadata; - dispatchUpdateMediaMetaData(true /* changed */, true /* allowAnimation */); + dispatchUpdateMediaMetaData(); } }; @@ -155,23 +115,13 @@ public class NotificationMediaManager implements Dumpable { NotifPipeline notifPipeline, NotifCollection notifCollection, MediaDataManager mediaDataManager, - StatusBarStateController statusBarStateController, - SysuiColorExtractor colorExtractor, - KeyguardStateController keyguardStateController, - DumpManager dumpManager, - WallpaperManager wallpaperManager, - DisplayManager displayManager) { + DumpManager dumpManager) { mContext = context; mMediaListeners = new ArrayList<>(); mVisibilityProvider = visibilityProvider; mMediaDataManager = mediaDataManager; mNotifPipeline = notifPipeline; mNotifCollection = notifCollection; - mStatusBarStateController = statusBarStateController; - mColorExtractor = colorExtractor; - mKeyguardStateController = keyguardStateController; - mDisplayManager = displayManager; - mIsLockscreenLiveWallpaperEnabled = wallpaperManager.isLockscreenLiveWallpaperEnabled(); setupNotifPipeline(); @@ -275,7 +225,7 @@ public class NotificationMediaManager implements Dumpable { public void onNotificationRemoved(String key) { if (key.equals(mMediaNotificationKey)) { clearCurrentMediaNotification(); - dispatchUpdateMediaMetaData(true /* changed */, true /* allowEnterAnimation */); + dispatchUpdateMediaMetaData(); } } @@ -309,21 +259,18 @@ public class NotificationMediaManager implements Dumpable { } public void findAndUpdateMediaNotifications() { - boolean metaDataChanged; // TODO(b/169655907): get the semi-filtered notifications for current user Collection<NotificationEntry> allNotifications = mNotifPipeline.getAllNotifs(); - metaDataChanged = findPlayingMediaNotification(allNotifications); - dispatchUpdateMediaMetaData(metaDataChanged, true /* allowEnterAnimation */); + findPlayingMediaNotification(allNotifications); + dispatchUpdateMediaMetaData(); } /** * Find a notification and media controller associated with the playing media session, and * update this manager's internal state. - * @return whether the current MediaMetadata changed (and needs to be announced to listeners). + * TODO(b/273443374) check this method */ - boolean findPlayingMediaNotification( - @NonNull Collection<NotificationEntry> allNotifications) { - boolean metaDataChanged = false; + void findPlayingMediaNotification(@NonNull Collection<NotificationEntry> allNotifications) { // Promote the media notification with a controller in 'playing' state, if any. NotificationEntry mediaNotification = null; MediaController controller = null; @@ -359,8 +306,6 @@ public class NotificationMediaManager implements Dumpable { Log.v(TAG, "DEBUG_MEDIA: insert listener, found new controller: " + mMediaController + ", receive metadata: " + mMediaMetadata); } - - metaDataChanged = true; } if (mediaNotification != null @@ -371,8 +316,6 @@ public class NotificationMediaManager implements Dumpable { + mMediaNotificationKey); } } - - return metaDataChanged; } public void clearCurrentMediaNotification() { @@ -380,10 +323,7 @@ public class NotificationMediaManager implements Dumpable { clearCurrentMediaNotificationSession(); } - private void dispatchUpdateMediaMetaData(boolean changed, boolean allowEnterAnimation) { - if (mPresenter != null) { - mPresenter.updateMediaMetaData(changed, allowEnterAnimation); - } + private void dispatchUpdateMediaMetaData() { @PlaybackState.State int state = getMediaControllerPlaybackState(mMediaController); ArrayList<MediaListener> callbacks = new ArrayList<>(mMediaListeners); for (int i = 0; i < callbacks.size(); i++) { @@ -446,125 +386,6 @@ public class NotificationMediaManager implements Dumpable { mMediaController = null; } - /** - * Notify lockscreen wallpaper drawable the current internal display. - */ - public void onDisplayUpdated(Display display) { - Trace.beginSection("NotificationMediaManager#onDisplayUpdated"); - mCurrentDisplay = display; - Trace.endSection(); - } - - private boolean isOnSmallerInternalDisplays() { - if (mSmallerInternalDisplayUids == null) { - mSmallerInternalDisplayUids = findSmallerInternalDisplayUids(); - } - return mSmallerInternalDisplayUids.contains(mCurrentDisplay.getUniqueId()); - } - - private List<String> findSmallerInternalDisplayUids() { - if (mSmallerInternalDisplayUids != null) { - return mSmallerInternalDisplayUids; - } - List<Display> internalDisplays = Arrays.stream(mDisplayManager.getDisplays( - DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)) - .filter(display -> display.getType() == Display.TYPE_INTERNAL) - .collect(Collectors.toList()); - if (internalDisplays.isEmpty()) { - return List.of(); - } - Display largestDisplay = internalDisplays.stream() - .max(Comparator.comparingInt(this::getRealDisplayArea)) - .orElse(internalDisplays.get(0)); - internalDisplays.remove(largestDisplay); - return internalDisplays.stream().map(Display::getUniqueId).collect(Collectors.toList()); - } - - private int getRealDisplayArea(Display display) { - display.getRealSize(mTmpDisplaySize); - return mTmpDisplaySize.x * mTmpDisplaySize.y; - } - - /** - * Update media state of lockscreen media views and controllers . - */ - public void updateMediaMetaData(boolean metaDataChanged) { - - if (mIsLockscreenLiveWallpaperEnabled) return; - - Trace.beginSection("CentralSurfaces#updateMediaMetaData"); - if (getBackDropView() == null) { - Trace.endSection(); - return; // called too early - } - - boolean wakeAndUnlock = mBiometricUnlockController != null - && mBiometricUnlockController.isWakeAndUnlock(); - if (mKeyguardStateController.isLaunchTransitionFadingAway() || wakeAndUnlock) { - mBackdrop.setVisibility(View.INVISIBLE); - Trace.endSection(); - return; - } - - MediaMetadata mediaMetadata = getMediaMetadata(); - - if (DEBUG_MEDIA) { - Log.v(TAG, "DEBUG_MEDIA: updating album art for notification " - + getMediaNotificationKey() - + " metadata=" + mediaMetadata - + " metaDataChanged=" + metaDataChanged - + " state=" + mStatusBarStateController.getState()); - } - - mColorExtractor.setHasMediaArtwork(false); - if (mScrimController != null) { - mScrimController.setHasBackdrop(false); - } - - Trace.endSection(); - } - - public void setup(BackDropView backdrop, ImageView backdropFront, ImageView backdropBack, - ScrimController scrimController, LockscreenWallpaper lockscreenWallpaper) { - mBackdrop = backdrop; - mBackdropFront = backdropFront; - mBackdropBack = backdropBack; - mScrimController = scrimController; - mLockscreenWallpaper = lockscreenWallpaper; - } - - public void setBiometricUnlockController(BiometricUnlockController biometricUnlockController) { - mBiometricUnlockController = biometricUnlockController; - } - - /** - * Hide the album artwork that is fading out and release its bitmap. - */ - protected final Runnable mHideBackdropFront = new Runnable() { - @Override - public void run() { - if (DEBUG_MEDIA) { - Log.v(TAG, "DEBUG_MEDIA: removing fade layer"); - } - mBackdropFront.setVisibility(View.INVISIBLE); - mBackdropFront.animate().cancel(); - mBackdropFront.setImageDrawable(null); - } - }; - - // TODO(b/273443374): remove - public boolean isLockscreenWallpaperOnNotificationShade() { - return mBackdrop != null && mLockscreenWallpaper != null - && !mLockscreenWallpaper.isLockscreenLiveWallpaperEnabled() - && (mBackdropFront.isVisibleToUser() || mBackdropBack.isVisibleToUser()); - } - - // TODO(b/273443374) temporary test helper; remove - @VisibleForTesting - BackDropView getBackDropView() { - return mBackdrop; - } - public interface MediaListener { /** * Called whenever there's new metadata or playback state. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java index 5dcf6d1d8f28..f3b5ab6968a0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java @@ -32,11 +32,6 @@ public interface NotificationPresenter extends ExpandableNotificationRow.OnExpan boolean isPresenterFullyCollapsed(); /** - * Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper. - */ - void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation); - - /** * Called when the current user changes. * @param newUserId new user id */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java index 125c8efe1884..1fe6b83b47b1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java @@ -16,9 +16,7 @@ package com.android.systemui.statusbar.dagger; -import android.app.WallpaperManager; import android.content.Context; -import android.hardware.display.DisplayManager; import android.os.RemoteException; import android.service.dreams.IDreamManager; import android.util.Log; @@ -29,7 +27,6 @@ import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.AnimationFeatureFlags; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; -import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpHandler; import com.android.systemui.dump.DumpManager; @@ -121,24 +118,14 @@ public interface CentralSurfacesDependenciesModule { NotifPipeline notifPipeline, NotifCollection notifCollection, MediaDataManager mediaDataManager, - StatusBarStateController statusBarStateController, - SysuiColorExtractor colorExtractor, - KeyguardStateController keyguardStateController, - DumpManager dumpManager, - WallpaperManager wallpaperManager, - DisplayManager displayManager) { + DumpManager dumpManager) { return new NotificationMediaManager( context, visibilityProvider, notifPipeline, notifCollection, mediaDataManager, - statusBarStateController, - colorExtractor, - keyguardStateController, - dumpManager, - wallpaperManager, - displayManager); + dumpManager); } /** */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java index 59f10aed4145..daa4f1807625 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java @@ -511,7 +511,6 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp case MODE_WAKE_AND_UNLOCK: if (mMode == MODE_WAKE_AND_UNLOCK_PULSING) { Trace.beginSection("MODE_WAKE_AND_UNLOCK_PULSING"); - mMediaManager.updateMediaMetaData(false /* metaDataChanged */); } else if (mMode == MODE_WAKE_AND_UNLOCK){ Trace.beginSection("MODE_WAKE_AND_UNLOCK"); } else { 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 8d9fd12356a6..7cd32f977422 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -76,7 +76,6 @@ import android.util.DisplayMetrics; import android.util.EventLog; import android.util.IndentingPrintWriter; import android.util.Log; -import android.util.MathUtils; import android.view.Display; import android.view.IRemoteAnimationRunner; import android.view.IWindowManager; @@ -176,7 +175,6 @@ import com.android.systemui.shade.ShadeSurface; import com.android.systemui.shade.ShadeViewController; import com.android.systemui.shared.recents.utilities.Utilities; import com.android.systemui.statusbar.AutoHideUiElement; -import com.android.systemui.statusbar.BackDropView; import com.android.systemui.statusbar.CircleReveal; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.GestureRecorder; @@ -237,10 +235,10 @@ import com.android.wm.shell.bubbles.Bubbles; import com.android.wm.shell.startingsurface.SplashscreenContentDrawer; import com.android.wm.shell.startingsurface.StartingSurface; -import dagger.Lazy; - import dalvik.annotation.optimization.NeverCompile; +import dagger.Lazy; + import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; @@ -376,9 +374,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { private boolean mBrightnessMirrorVisible; private BiometricUnlockController mBiometricUnlockController; private final LightBarController mLightBarController; - private final Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy; - @Nullable - protected LockscreenWallpaper mLockscreenWallpaper; private final AutoHideController mAutoHideController; private final Point mCurrentDisplaySize = new Point(); @@ -658,7 +653,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { NotificationExpansionRepository notificationExpansionRepository, DozeParameters dozeParameters, ScrimController scrimController, - Lazy<LockscreenWallpaper> lockscreenWallpaperLazy, Lazy<BiometricUnlockController> biometricUnlockControllerLazy, AuthRippleController authRippleController, DozeServiceHost dozeServiceHost, @@ -770,7 +764,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mPowerManager = powerManager; mDozeParameters = dozeParameters; mScrimController = scrimController; - mLockscreenWallpaperLazy = lockscreenWallpaperLazy; mDozeScrimController = dozeScrimController; mBiometricUnlockControllerLazy = biometricUnlockControllerLazy; mAuthRippleController = authRippleController; @@ -1198,10 +1191,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { createNavigationBar(result); - if (ENABLE_LOCKSCREEN_WALLPAPER && mWallpaperSupported) { - mLockscreenWallpaper = mLockscreenWallpaperLazy.get(); - } - mAmbientIndicationContainer = getNotificationShadeWindowView().findViewById( R.id.ambient_indication_container); @@ -1268,24 +1257,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mNotificationShelfController, mHeadsUpManager); - BackDropView backdrop = getNotificationShadeWindowView().findViewById(R.id.backdrop); - if (mWallpaperManager.isLockscreenLiveWallpaperEnabled()) { - mMediaManager.setup(null, null, null, mScrimController, null); - } else { - mMediaManager.setup(backdrop, backdrop.findViewById(R.id.backdrop_front), - backdrop.findViewById(R.id.backdrop_back), mScrimController, - mLockscreenWallpaper); - } - float maxWallpaperZoom = mContext.getResources().getFloat( - com.android.internal.R.dimen.config_wallpaperMaxScale); - mNotificationShadeDepthControllerLazy.get().addListener(depth -> { - float scale = MathUtils.lerp(maxWallpaperZoom, 1f, depth); - backdrop.setPivotX(backdrop.getWidth() / 2f); - backdrop.setPivotY(backdrop.getHeight() / 2f); - backdrop.setScaleX(scale); - backdrop.setScaleY(scale); - }); - // Set up the quick settings tile panel final View container = getNotificationShadeWindowView().findViewById(R.id.qs_frame); if (container != null) { @@ -1357,14 +1328,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { // receive broadcasts registerBroadcastReceiver(); - IntentFilter demoFilter = new IntentFilter(); - if (DEBUG_MEDIA_FAKE_ARTWORK) { - demoFilter.addAction(ACTION_FAKE_ARTWORK); - } - mContext.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter, - android.Manifest.permission.DUMP, null, - Context.RECEIVER_EXPORTED_UNAUDITED); - // listen for USER_SETUP_COMPLETE setting (per-user) mDeviceProvisionedController.addCallback(mUserSetupObserver); mUserSetupObserver.onUserSetupChanged(); @@ -1583,7 +1546,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mRemoteInputManager.addControllerCallback(mStatusBarKeyguardViewManager); mLightBarController.setBiometricUnlockController(mBiometricUnlockController); - mMediaManager.setBiometricUnlockController(mBiometricUnlockController); Trace.endSection(); } @@ -1870,7 +1832,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { void updateDisplaySize() { mDisplay.getMetrics(mDisplayMetrics); mDisplay.getSize(mCurrentDisplaySize); - mMediaManager.onDisplayUpdated(mDisplay); if (DEBUG_GESTURES) { mGestureRec.tag("display", String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels)); @@ -1944,19 +1905,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { } }; - private final BroadcastReceiver mDemoReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (DEBUG) Log.v(TAG, "onReceive: " + intent); - String action = intent.getAction(); - if (ACTION_FAKE_ARTWORK.equals(action)) { - if (DEBUG_MEDIA_FAKE_ARTWORK) { - mPresenterLazy.get().updateMediaMetaData(true, true); - } - } - } - }; - /** * Reload some of our resources when the configuration changes. * @@ -2139,7 +2087,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { releaseGestureWakeLock(); runLaunchTransitionEndRunnable(); mKeyguardStateController.setLaunchTransitionFadingAway(false); - mPresenterLazy.get().updateMediaMetaData(true /* metaDataChanged */, true); } /** @@ -2163,7 +2110,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { beforeFading.run(); } updateScrimController(); - mPresenterLazy.get().updateMediaMetaData(false, true); mShadeSurface.resetAlpha(); mShadeSurface.fadeOut( FADE_KEYGUARD_START_DELAY, FADE_KEYGUARD_DURATION, @@ -3222,8 +3168,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { updateDozingState(); checkBarModes(); updateScrimController(); - mPresenterLazy.get() - .updateMediaMetaData(false, mState != StatusBarState.KEYGUARD); Trace.endSection(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java index 2960520f00b4..2206be5e614b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java @@ -546,8 +546,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat * (1.0f - mKeyguardHeadsUpShowingAmount); } - if (mSystemEventAnimator.isAnimationRunning() - && !mNotificationMediaManager.isLockscreenWallpaperOnNotificationShade()) { + if (mSystemEventAnimator.isAnimationRunning()) { newAlpha = Math.min(newAlpha, mSystemEventAnimatorAlpha); } else { mView.setTranslationX(0); @@ -704,21 +703,11 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat private StatusBarSystemEventDefaultAnimator getSystemEventAnimator(boolean isAnimationRunning) { return new StatusBarSystemEventDefaultAnimator(getResources(), (alpha) -> { - // TODO(b/273443374): remove if-else condition - if (!mNotificationMediaManager.isLockscreenWallpaperOnNotificationShade()) { - mSystemEventAnimatorAlpha = alpha; - } else { - mSystemEventAnimatorAlpha = 1f; - } + mSystemEventAnimatorAlpha = alpha; updateViewState(); return Unit.INSTANCE; }, (translationX) -> { - // TODO(b/273443374): remove if-else condition - if (!mNotificationMediaManager.isLockscreenWallpaperOnNotificationShade()) { - mView.setTranslationX(translationX); - } else { - mView.setTranslationX(0); - } + mView.setTranslationX(translationX); return Unit.INSTANCE; }, isAnimationRunning); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java deleted file mode 100644 index 00fd9fbfffe3..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright (C) 2016 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.statusbar.phone; - -import android.annotation.Nullable; -import android.app.IWallpaperManager; -import android.app.IWallpaperManagerCallback; -import android.app.WallpaperColors; -import android.app.WallpaperManager; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Rect; -import android.graphics.Xfermode; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.DrawableWrapper; -import android.os.AsyncTask; -import android.os.Handler; -import android.os.ParcelFileDescriptor; -import android.os.RemoteException; -import android.os.UserHandle; -import android.util.Log; - -import androidx.annotation.NonNull; - -import com.android.internal.util.IndentingPrintWriter; -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.CoreStartable; -import com.android.systemui.Dumpable; -import com.android.systemui.dagger.SysUISingleton; -import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.dump.DumpManager; -import com.android.systemui.settings.UserTracker; -import com.android.systemui.statusbar.NotificationMediaManager; -import com.android.systemui.user.data.model.SelectedUserModel; -import com.android.systemui.user.data.model.SelectionStatus; -import com.android.systemui.user.data.repository.UserRepository; -import com.android.systemui.util.kotlin.JavaAdapter; - -import libcore.io.IoUtils; - -import java.io.PrintWriter; -import java.util.Objects; - -import javax.inject.Inject; - -/** - * Manages the lockscreen wallpaper. - */ -@SysUISingleton -public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implements Runnable, - Dumpable, CoreStartable { - - private static final String TAG = "LockscreenWallpaper"; - - // TODO(b/253507223): temporary; remove this - private static final String DISABLED_ERROR_MESSAGE = "Methods from LockscreenWallpaper.java " - + "should not be called in this version. The lock screen wallpaper should be " - + "managed by the WallpaperManagerService and not by this class."; - - private final NotificationMediaManager mMediaManager; - private final WallpaperManager mWallpaperManager; - private final KeyguardUpdateMonitor mUpdateMonitor; - private final Handler mH; - private final JavaAdapter mJavaAdapter; - private final UserRepository mUserRepository; - - private boolean mCached; - private Bitmap mCache; - private int mCurrentUserId; - // The user selected in the UI, or null if no user is selected or UI doesn't support selecting - // users. - private UserHandle mSelectedUser; - private AsyncTask<Void, Void, LoaderResult> mLoader; - - @Inject - public LockscreenWallpaper(WallpaperManager wallpaperManager, - @Nullable IWallpaperManager iWallpaperManager, - KeyguardUpdateMonitor keyguardUpdateMonitor, - DumpManager dumpManager, - NotificationMediaManager mediaManager, - @Main Handler mainHandler, - JavaAdapter javaAdapter, - UserRepository userRepository, - UserTracker userTracker) { - dumpManager.registerDumpable(getClass().getSimpleName(), this); - mWallpaperManager = wallpaperManager; - mCurrentUserId = userTracker.getUserId(); - mUpdateMonitor = keyguardUpdateMonitor; - mMediaManager = mediaManager; - mH = mainHandler; - mJavaAdapter = javaAdapter; - mUserRepository = userRepository; - - if (iWallpaperManager != null && !mWallpaperManager.isLockscreenLiveWallpaperEnabled()) { - // Service is disabled on some devices like Automotive - try { - iWallpaperManager.setLockWallpaperCallback(this); - } catch (RemoteException e) { - Log.e(TAG, "System dead?" + e); - } - } - } - - @Override - public void start() { - if (!isLockscreenLiveWallpaperEnabled()) { - mJavaAdapter.alwaysCollectFlow( - mUserRepository.getSelectedUser(), this::setSelectedUser); - } - } - - public Bitmap getBitmap() { - assertLockscreenLiveWallpaperNotEnabled(); - - if (mCached) { - return mCache; - } - if (!mWallpaperManager.isWallpaperSupported()) { - mCached = true; - mCache = null; - return null; - } - - LoaderResult result = loadBitmap(mCurrentUserId, mSelectedUser); - if (result.success) { - mCached = true; - mCache = result.bitmap; - } - return mCache; - } - - public LoaderResult loadBitmap(int currentUserId, UserHandle selectedUser) { - // May be called on any thread - only use thread safe operations. - - assertLockscreenLiveWallpaperNotEnabled(); - - - if (!mWallpaperManager.isWallpaperSupported()) { - // When wallpaper is not supported, show the system wallpaper - return LoaderResult.success(null); - } - - // Prefer the selected user (when specified) over the current user for the FLAG_SET_LOCK - // wallpaper. - final int lockWallpaperUserId = - selectedUser != null ? selectedUser.getIdentifier() : currentUserId; - ParcelFileDescriptor fd = mWallpaperManager.getWallpaperFile( - WallpaperManager.FLAG_LOCK, lockWallpaperUserId); - - if (fd != null) { - try { - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inPreferredConfig = Bitmap.Config.HARDWARE; - return LoaderResult.success(BitmapFactory.decodeFileDescriptor( - fd.getFileDescriptor(), null, options)); - } catch (OutOfMemoryError e) { - Log.w(TAG, "Can't decode file", e); - return LoaderResult.fail(); - } finally { - IoUtils.closeQuietly(fd); - } - } else { - if (selectedUser != null) { - // Show the selected user's static wallpaper. - return LoaderResult.success(mWallpaperManager.getBitmapAsUser( - selectedUser.getIdentifier(), true /* hardware */)); - - } else { - // When there is no selected user, show the system wallpaper - return LoaderResult.success(null); - } - } - } - - private void setSelectedUser(SelectedUserModel selectedUserModel) { - assertLockscreenLiveWallpaperNotEnabled(); - - if (selectedUserModel.getSelectionStatus().equals(SelectionStatus.SELECTION_IN_PROGRESS)) { - // Wait until the selection has finished before updating. - return; - } - - int user = selectedUserModel.getUserInfo().id; - if (user != mCurrentUserId) { - if (mSelectedUser == null || user != mSelectedUser.getIdentifier()) { - mCached = false; - } - mCurrentUserId = user; - } - } - - public void setSelectedUser(UserHandle selectedUser) { - assertLockscreenLiveWallpaperNotEnabled(); - - if (Objects.equals(selectedUser, mSelectedUser)) { - return; - } - mSelectedUser = selectedUser; - postUpdateWallpaper(); - } - - @Override - public void onWallpaperChanged() { - assertLockscreenLiveWallpaperNotEnabled(); - // Called on Binder thread. - postUpdateWallpaper(); - } - - @Override - public void onWallpaperColorsChanged(WallpaperColors colors, int which, int userId) { - assertLockscreenLiveWallpaperNotEnabled(); - } - - private void postUpdateWallpaper() { - assertLockscreenLiveWallpaperNotEnabled(); - if (mH == null) { - Log.wtfStack(TAG, "Trying to use LockscreenWallpaper before initialization."); - return; - } - mH.removeCallbacks(this); - mH.post(this); - } - @Override - public void run() { - // Called in response to onWallpaperChanged on the main thread. - - assertLockscreenLiveWallpaperNotEnabled(); - - if (mLoader != null) { - mLoader.cancel(false /* interrupt */); - } - - final int currentUser = mCurrentUserId; - final UserHandle selectedUser = mSelectedUser; - mLoader = new AsyncTask<Void, Void, LoaderResult>() { - @Override - protected LoaderResult doInBackground(Void... params) { - return loadBitmap(currentUser, selectedUser); - } - - @Override - protected void onPostExecute(LoaderResult result) { - super.onPostExecute(result); - if (isCancelled()) { - return; - } - if (result.success) { - mCached = true; - mCache = result.bitmap; - mMediaManager.updateMediaMetaData(true /* metaDataChanged */); - } - mLoader = null; - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - - // TODO(b/273443374): remove - public boolean isLockscreenLiveWallpaperEnabled() { - return mWallpaperManager.isLockscreenLiveWallpaperEnabled(); - } - - @Override - public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { - pw.println(getClass().getSimpleName() + ":"); - IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " ").increaseIndent(); - iPw.println("mCached=" + mCached); - iPw.println("mCache=" + mCache); - iPw.println("mCurrentUserId=" + mCurrentUserId); - iPw.println("mSelectedUser=" + mSelectedUser); - } - - private static class LoaderResult { - public final boolean success; - public final Bitmap bitmap; - - LoaderResult(boolean success, Bitmap bitmap) { - this.success = success; - this.bitmap = bitmap; - } - - static LoaderResult success(Bitmap b) { - return new LoaderResult(true, b); - } - - static LoaderResult fail() { - return new LoaderResult(false, null); - } - } - - /** - * Drawable that aligns left horizontally and center vertically (like ImageWallpaper). - * - * <p>Aligns to the center when showing on the smaller internal display of a multi display - * device. - */ - public static class WallpaperDrawable extends DrawableWrapper { - - private final ConstantState mState; - private final Rect mTmpRect = new Rect(); - private boolean mIsOnSmallerInternalDisplays; - - public WallpaperDrawable(Resources r, Bitmap b, boolean isOnSmallerInternalDisplays) { - this(r, new ConstantState(b), isOnSmallerInternalDisplays); - } - - private WallpaperDrawable(Resources r, ConstantState state, - boolean isOnSmallerInternalDisplays) { - super(new BitmapDrawable(r, state.mBackground)); - mState = state; - mIsOnSmallerInternalDisplays = isOnSmallerInternalDisplays; - } - - @Override - public void setXfermode(@Nullable Xfermode mode) { - // DrawableWrapper does not call this for us. - getDrawable().setXfermode(mode); - } - - @Override - public int getIntrinsicWidth() { - return -1; - } - - @Override - public int getIntrinsicHeight() { - return -1; - } - - @Override - protected void onBoundsChange(Rect bounds) { - int vwidth = getBounds().width(); - int vheight = getBounds().height(); - int dwidth = mState.mBackground.getWidth(); - int dheight = mState.mBackground.getHeight(); - float scale; - float dx = 0, dy = 0; - - if (dwidth * vheight > vwidth * dheight) { - scale = (float) vheight / (float) dheight; - } else { - scale = (float) vwidth / (float) dwidth; - } - - if (scale <= 1f) { - scale = 1f; - } - dy = (vheight - dheight * scale) * 0.5f; - - int offsetX = 0; - // Offset to show the center area of the wallpaper on a smaller display for multi - // display device - if (mIsOnSmallerInternalDisplays) { - offsetX = bounds.centerX() - (Math.round(dwidth * scale) / 2); - } - - mTmpRect.set( - bounds.left + offsetX, - bounds.top + Math.round(dy), - bounds.left + Math.round(dwidth * scale) + offsetX, - bounds.top + Math.round(dheight * scale + dy)); - - super.onBoundsChange(mTmpRect); - } - - @Override - public ConstantState getConstantState() { - return mState; - } - - /** - * Update bounds when the hosting display or the display size has changed. - * - * @param isOnSmallerInternalDisplays true if the drawable is on one of the internal - * displays with the smaller area. - */ - public void onDisplayUpdated(boolean isOnSmallerInternalDisplays) { - mIsOnSmallerInternalDisplays = isOnSmallerInternalDisplays; - onBoundsChange(getBounds()); - } - - static class ConstantState extends Drawable.ConstantState { - - private final Bitmap mBackground; - - ConstantState(Bitmap background) { - mBackground = background; - } - - @Override - public Drawable newDrawable() { - return newDrawable(null); - } - - @Override - public Drawable newDrawable(@Nullable Resources res) { - return new WallpaperDrawable(res, this, /* isOnSmallerInternalDisplays= */ false); - } - - @Override - public int getChangingConfigurations() { - // DrawableWrapper already handles this for us. - return 0; - } - } - } - - /** - * Feature b/253507223 will adapt the logic to always use the - * WallpaperManagerService to render the lock screen wallpaper. - * Methods of this class should not be called at all if the project flag is enabled. - * TODO(b/253507223) temporary assertion; remove this - */ - private void assertLockscreenLiveWallpaperNotEnabled() { - if (mWallpaperManager.isLockscreenLiveWallpaperEnabled()) { - throw new IllegalStateException(DISABLED_ERROR_MESSAGE); - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 5b552640f397..744d70e36972 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.phone; +import static com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER; +import static com.android.systemui.keyguard.shared.model.KeyguardState.GONE; +import static com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER; import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; import static java.lang.Float.isNaN; @@ -51,7 +54,6 @@ import com.android.settingslib.Utils; import com.android.systemui.CoreStartable; import com.android.systemui.DejankUtils; import com.android.systemui.Dumpable; -import com.android.systemui.res.R; import com.android.systemui.animation.ShadeInterpolation; import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants; import com.android.systemui.dagger.SysUISingleton; @@ -62,7 +64,9 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac import com.android.systemui.keyguard.shared.model.ScrimAlpha; import com.android.systemui.keyguard.shared.model.TransitionState; import com.android.systemui.keyguard.shared.model.TransitionStep; +import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToGoneTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel; +import com.android.systemui.res.R; import com.android.systemui.scrim.ScrimView; import com.android.systemui.shade.ShadeViewController; import com.android.systemui.shade.transition.LargeScreenShadeInterpolator; @@ -273,6 +277,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump private CoroutineDispatcher mMainDispatcher; private boolean mIsBouncerToGoneTransitionRunning = false; private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel; + private AlternateBouncerToGoneTransitionViewModel mAlternateBouncerToGoneTransitionViewModel; private final Consumer<ScrimAlpha> mScrimAlphaConsumer = (ScrimAlpha alphas) -> { mInFrontAlpha = alphas.getFrontAlpha(); @@ -285,7 +290,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump mScrimBehind.setViewAlpha(mBehindAlpha); }; - Consumer<TransitionStep> mPrimaryBouncerToGoneTransition; + Consumer<TransitionStep> mBouncerToGoneTransition; @Inject public ScrimController( @@ -304,6 +309,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump KeyguardUnlockAnimationController keyguardUnlockAnimationController, StatusBarKeyguardViewManager statusBarKeyguardViewManager, PrimaryBouncerToGoneTransitionViewModel primaryBouncerToGoneTransitionViewModel, + AlternateBouncerToGoneTransitionViewModel alternateBouncerToGoneTransitionViewModel, KeyguardTransitionInteractor keyguardTransitionInteractor, WallpaperRepository wallpaperRepository, @Main CoroutineDispatcher mainDispatcher, @@ -349,6 +355,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump }); mColors = new GradientColors(); mPrimaryBouncerToGoneTransitionViewModel = primaryBouncerToGoneTransitionViewModel; + mAlternateBouncerToGoneTransitionViewModel = alternateBouncerToGoneTransitionViewModel; mKeyguardTransitionInteractor = keyguardTransitionInteractor; mWallpaperRepository = wallpaperRepository; mMainDispatcher = mainDispatcher; @@ -405,7 +412,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump // Directly control transition to UNLOCKED scrim state from PRIMARY_BOUNCER, and make sure // to report back that keyguard has faded away. This fixes cases where the scrim state was // rapidly switching on unlock, due to shifts in state in CentralSurfacesImpl - mPrimaryBouncerToGoneTransition = + mBouncerToGoneTransition = (TransitionStep step) -> { TransitionState state = step.getTransitionState(); @@ -425,10 +432,17 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump } }; - collectFlow(behindScrim, mKeyguardTransitionInteractor.getPrimaryBouncerToGoneTransition(), - mPrimaryBouncerToGoneTransition, mMainDispatcher); + // PRIMARY_BOUNCER->GONE + collectFlow(behindScrim, mKeyguardTransitionInteractor.transition(PRIMARY_BOUNCER, GONE), + mBouncerToGoneTransition, mMainDispatcher); collectFlow(behindScrim, mPrimaryBouncerToGoneTransitionViewModel.getScrimAlpha(), mScrimAlphaConsumer, mMainDispatcher); + + // ALTERNATE_BOUNCER->GONE + collectFlow(behindScrim, mKeyguardTransitionInteractor.transition(ALTERNATE_BOUNCER, GONE), + mBouncerToGoneTransition, mMainDispatcher); + collectFlow(behindScrim, mAlternateBouncerToGoneTransitionViewModel.getScrimAlpha(), + mScrimAlphaConsumer, mMainDispatcher); } // TODO(b/270984686) recompute scrim height accurately, based on shade contents. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 90fddd9ae22c..267b56378d82 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -964,9 +964,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_STATE_CHANGED, SysUiStatsLog.KEYGUARD_STATE_CHANGED__STATE__SHOWN); } - if (isShowing) { - mMediaManager.updateMediaMetaData(false); - } mNotificationShadeWindowController.setKeyguardOccluded(isOccluded); // setDozing(false) will call reset once we stop dozing. Also, if we're going away, there's diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index 57a8e6fe0d91..a5cd062f6f37 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -205,7 +205,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu // End old BaseStatusBar.userSwitched mCommandQueue.animateCollapsePanels(); mMediaManager.clearCurrentMediaNotification(); - updateMediaMetaData(true, false); } @Override @@ -220,11 +219,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu } @Override - public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) { - mMediaManager.updateMediaMetaData(metaDataChanged); - } - - @Override public void onExpandClicked(NotificationEntry clickedEntry, View clickedView, boolean nowExpanded) { mHeadsUpManager.setExpanded(clickedEntry, nowExpanded); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialog.kt index 85fd2afed9ec..d7f3b0767590 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialog.kt @@ -17,42 +17,71 @@ package com.android.systemui.statusbar.phone import android.app.Dialog import android.content.Context +import android.content.res.Configuration import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.Gravity -import android.view.WindowManager +import android.view.ViewGroup.LayoutParams.WRAP_CONTENT +import android.view.WindowManager.LayoutParams.MATCH_PARENT +import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION +import android.view.WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS +import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL import com.android.systemui.res.R +import com.android.systemui.statusbar.policy.ConfigurationController +import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener /** A dialog shown as a bottom sheet. */ open class SystemUIBottomSheetDialog( context: Context, - theme: Int = R.style.Theme_SystemUI_Dialog, + private val configurationController: ConfigurationController? = null, + theme: Int = R.style.Theme_SystemUI_Dialog ) : Dialog(context, theme) { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + setupWindow() + setupEdgeToEdge() + setCanceledOnTouchOutside(true) + } + private fun setupWindow() { window?.apply { - setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL) - addPrivateFlags(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS) - + setType(TYPE_STATUS_BAR_SUB_PANEL) + addPrivateFlags(SYSTEM_FLAG_SHOW_FOR_ALL_USERS or PRIVATE_FLAG_NO_MOVE_ANIMATION) setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) setGravity(Gravity.BOTTOM) - val edgeToEdgeHorizontally = - context.resources.getBoolean(R.bool.config_edgeToEdgeBottomSheetDialog) - if (edgeToEdgeHorizontally) { - decorView.setPadding(0, 0, 0, 0) - setLayout( - WindowManager.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.WRAP_CONTENT - ) + decorView.setPadding(0, 0, 0, 0) + attributes = + attributes.apply { + fitInsetsSides = 0 + horizontalMargin = 0f + } + } + } + + private fun setupEdgeToEdge() { + val edgeToEdgeHorizontally = + context.resources.getBoolean(R.bool.config_edgeToEdgeBottomSheetDialog) + val width = if (edgeToEdgeHorizontally) MATCH_PARENT else WRAP_CONTENT + val height = WRAP_CONTENT + window?.setLayout(width, height) + } - val lp = attributes - lp.fitInsetsSides = 0 - lp.horizontalMargin = 0f - attributes = lp + override fun onStart() { + super.onStart() + configurationController?.addCallback(onConfigChanged) + } + + override fun onStop() { + super.onStop() + configurationController?.removeCallback(onConfigChanged) + } + + private val onConfigChanged = + object : ConfigurationListener { + override fun onConfigChanged(newConfig: Configuration?) { + super.onConfigChanged(newConfig) + setupEdgeToEdge() } } - setCanceledOnTouchOutside(true) - } } diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLatencyTracker.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLatencyTracker.kt index 9269df31e37e..8c66c2f0fab3 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLatencyTracker.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLatencyTracker.kt @@ -19,6 +19,7 @@ package com.android.systemui.unfold import android.content.ContentResolver import android.content.Context import android.hardware.devicestate.DeviceStateManager +import android.os.Trace import android.util.Log import com.android.internal.util.LatencyTracker import com.android.systemui.dagger.SysUISingleton @@ -57,6 +58,7 @@ constructor( private var folded: Boolean? = null private var isTransitionEnabled: Boolean? = null private val foldStateListener = FoldStateListener(context) + private var unfoldInProgress = false private val isFoldable: Boolean get() = context.resources @@ -95,7 +97,7 @@ constructor( // the unfold animation (e.g. it could be disabled because of battery saver). // When animation is enabled finishing of the tracking will be done in onTransitionStarted. if (folded == false && isTransitionEnabled == false) { - latencyTracker.onActionEnd(LatencyTracker.ACTION_SWITCH_DISPLAY_UNFOLD) + onUnfoldEnded() if (DEBUG) { Log.d(TAG, "onScreenTurnedOn: ending ACTION_SWITCH_DISPLAY_UNFOLD") @@ -116,7 +118,7 @@ constructor( } if (folded == false && isTransitionEnabled == true) { - latencyTracker.onActionEnd(LatencyTracker.ACTION_SWITCH_DISPLAY_UNFOLD) + onUnfoldEnded() if (DEBUG) { Log.d(TAG, "onTransitionStarted: ending ACTION_SWITCH_DISPLAY_UNFOLD") @@ -124,6 +126,22 @@ constructor( } } + private fun onUnfoldStarted() { + if (unfoldInProgress) return + unfoldInProgress = true + // As LatencyTracker might be disabled, let's also log a parallel slice to the trace to be + // able to debug all cases. + latencyTracker.onActionStart(LatencyTracker.ACTION_SWITCH_DISPLAY_UNFOLD) + Trace.asyncTraceBegin(Trace.TRACE_TAG_APP, UNFOLD_IN_PROGRESS_TRACE_NAME, /* cookie= */ 0) + } + + private fun onUnfoldEnded() { + if (!unfoldInProgress) return + unfoldInProgress = false + latencyTracker.onActionEnd(LatencyTracker.ACTION_SWITCH_DISPLAY_UNFOLD) + Trace.endAsyncSection(UNFOLD_IN_PROGRESS_TRACE_NAME, 0) + } + private fun onFoldEvent(folded: Boolean) { val oldFolded = this.folded @@ -139,7 +157,7 @@ constructor( // unfolding the device. if (oldFolded != null && !folded) { // Unfolding started - latencyTracker.onActionStart(LatencyTracker.ACTION_SWITCH_DISPLAY_UNFOLD) + onUnfoldStarted() isTransitionEnabled = transitionProgressProvider.isPresent && contentResolver.areAnimationsEnabled() @@ -159,4 +177,5 @@ constructor( } private const val TAG = "UnfoldLatencyTracker" +private const val UNFOLD_IN_PROGRESS_TRACE_NAME = "Switch displays during unfold" private val DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE) diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTraceLogger.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTraceLogger.kt new file mode 100644 index 000000000000..ed960f31228a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTraceLogger.kt @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2023 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.unfold + +import android.content.Context +import android.os.Trace +import com.android.systemui.CoreStartable +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.unfold.system.DeviceStateRepository +import com.android.systemui.unfold.updates.FoldStateRepository +import com.android.systemui.util.TraceStateLogger +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch + +/** + * Logs several unfold related details in a trace. Mainly used for debugging and investigate + * droidfooders traces. + */ +@SysUISingleton +class UnfoldTraceLogger +@Inject +constructor( + private val context: Context, + private val foldStateRepository: FoldStateRepository, + @Application private val applicationScope: CoroutineScope, + private val deviceStateRepository: DeviceStateRepository +) : CoreStartable { + private val isFoldable: Boolean + get() = + context.resources + .getIntArray(com.android.internal.R.array.config_foldedDeviceStates) + .isNotEmpty() + + override fun start() { + if (!isFoldable) return + + applicationScope.launch { + val foldUpdateLogger = TraceStateLogger("FoldUpdate") + foldStateRepository.foldUpdate.collect { foldUpdateLogger.log(it.name) } + } + + applicationScope.launch { + foldStateRepository.hingeAngle.collect { + Trace.traceCounter(Trace.TRACE_TAG_APP, "hingeAngle", it.toInt()) + } + } + applicationScope.launch { + val foldedStateLogger = TraceStateLogger("FoldedState") + deviceStateRepository.isFolded.collect { isFolded -> + foldedStateLogger.log( + if (isFolded) { + "folded" + } else { + "unfolded" + } + ) + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt index ed3eacd27c0a..71314f1f1775 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt @@ -19,6 +19,7 @@ package com.android.systemui.unfold import android.content.Context import android.hardware.devicestate.DeviceStateManager import android.os.SystemProperties +import com.android.systemui.CoreStartable import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.LifecycleScreenStatusProvider @@ -34,16 +35,26 @@ import com.android.systemui.unfold.util.UnfoldOnlyProgressProvider import com.android.systemui.unfold.util.UnfoldTransitionATracePrefix import com.android.systemui.util.time.SystemClockImpl import com.android.wm.shell.unfold.ShellUnfoldProgressProvider +import dagger.Binds import dagger.Lazy import dagger.Module import dagger.Provides +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap import java.util.Optional import java.util.concurrent.Executor import javax.inject.Named import javax.inject.Provider import javax.inject.Singleton -@Module(includes = [UnfoldSharedModule::class, SystemUnfoldSharedModule::class]) +@Module( + includes = + [ + UnfoldSharedModule::class, + SystemUnfoldSharedModule::class, + UnfoldTransitionModule.Bindings::class + ] +) class UnfoldTransitionModule { @Provides @UnfoldTransitionATracePrefix fun tracingTagPrefix() = "systemui" @@ -136,13 +147,22 @@ class UnfoldTransitionModule { null } - return resultingProvider?.get()?.orElse(null)?.let { - unfoldProgressProvider -> UnfoldProgressProvider(unfoldProgressProvider, foldProvider) - } ?: ShellUnfoldProgressProvider.NO_PROVIDER + return resultingProvider?.get()?.orElse(null)?.let { unfoldProgressProvider -> + UnfoldProgressProvider(unfoldProgressProvider, foldProvider) + } + ?: ShellUnfoldProgressProvider.NO_PROVIDER } @Provides fun screenStatusProvider(impl: LifecycleScreenStatusProvider): ScreenStatusProvider = impl + + @Module + interface Bindings { + @Binds + @IntoMap + @ClassKey(UnfoldTraceLogger::class) + fun bindUnfoldTraceLogger(impl: UnfoldTraceLogger): CoreStartable + } } const val UNFOLD_STATUS_BAR = "unfold_status_bar" diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java index aea3030967d2..fdf5966419b4 100644 --- a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java @@ -126,8 +126,6 @@ public class ImageWallpaper extends WallpaperService { private int mBitmapUsages = 0; private final Object mLock = new Object(); - private boolean mIsLockscreenLiveWallpaperEnabled; - CanvasEngine() { super(); setFixedSizeAllowed(true); @@ -171,12 +169,8 @@ public class ImageWallpaper extends WallpaperService { Log.d(TAG, "onCreate"); } mWallpaperManager = getDisplayContext().getSystemService(WallpaperManager.class); - mIsLockscreenLiveWallpaperEnabled = mWallpaperManager - .isLockscreenLiveWallpaperEnabled(); mSurfaceHolder = surfaceHolder; - Rect dimensions = mIsLockscreenLiveWallpaperEnabled - ? mWallpaperManager.peekBitmapDimensions(getSourceFlag(), true) - : mWallpaperManager.peekBitmapDimensions(); + Rect dimensions = mWallpaperManager.peekBitmapDimensions(getSourceFlag(), true); int width = Math.max(MIN_SURFACE_WIDTH, dimensions.width()); int height = Math.max(MIN_SURFACE_HEIGHT, dimensions.height()); mSurfaceHolder.setFixedSize(width, height); @@ -327,10 +321,8 @@ public class ImageWallpaper extends WallpaperService { boolean loadSuccess = false; Bitmap bitmap; try { - bitmap = mIsLockscreenLiveWallpaperEnabled - ? mWallpaperManager.getBitmapAsUser( - mUserTracker.getUserId(), false, getSourceFlag(), true) - : mWallpaperManager.getBitmapAsUser(mUserTracker.getUserId(), false); + bitmap = mWallpaperManager.getBitmapAsUser( + mUserTracker.getUserId(), false, getSourceFlag(), true); if (bitmap != null && bitmap.getByteCount() > RecordingCanvas.MAX_BITMAP_SIZE) { throw new RuntimeException("Wallpaper is too large to draw!"); @@ -341,18 +333,11 @@ public class ImageWallpaper extends WallpaperService { // be loaded, we will go into a cycle. Don't do a build where the // default wallpaper can't be loaded. Log.w(TAG, "Unable to load wallpaper!", exception); - if (mIsLockscreenLiveWallpaperEnabled) { - mWallpaperManager.clearWallpaper(getWallpaperFlags(), mUserTracker.getUserId()); - } else { - mWallpaperManager.clearWallpaper( - WallpaperManager.FLAG_SYSTEM, mUserTracker.getUserId()); - } + mWallpaperManager.clearWallpaper(getWallpaperFlags(), mUserTracker.getUserId()); try { - bitmap = mIsLockscreenLiveWallpaperEnabled - ? mWallpaperManager.getBitmapAsUser( - mUserTracker.getUserId(), false, getSourceFlag(), true) - : mWallpaperManager.getBitmapAsUser(mUserTracker.getUserId(), false); + bitmap = mWallpaperManager.getBitmapAsUser( + mUserTracker.getUserId(), false, getSourceFlag(), true); } catch (RuntimeException | OutOfMemoryError e) { Log.w(TAG, "Unable to load default wallpaper!", e); bitmap = null; @@ -373,9 +358,7 @@ public class ImageWallpaper extends WallpaperService { mBitmap.recycle(); } mBitmap = bitmap; - mWideColorGamut = mIsLockscreenLiveWallpaperEnabled - ? mWallpaperManager.wallpaperSupportsWcg(getSourceFlag()) - : mWallpaperManager.wallpaperSupportsWcg(WallpaperManager.FLAG_SYSTEM); + mWideColorGamut = mWallpaperManager.wallpaperSupportsWcg(getSourceFlag()); // +2 usages for the color extraction and the delayed unload. mBitmapUsages += 2; diff --git a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java index 80b281e458d0..882bcab5fab6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java +++ b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java @@ -17,7 +17,6 @@ package com.android.systemui.colorextraction; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -105,21 +104,6 @@ public class SysuiColorExtractorTests extends SysuiTestCase { } @Test - public void getColors_fallbackWhenMediaIsVisible() { - simulateEvent(mColorExtractor); - mColorExtractor.setHasMediaArtwork(true); - - ColorExtractor.GradientColors fallbackColors = mColorExtractor.getNeutralColors(); - - for (int type : sTypes) { - assertEquals("Not using fallback!", - mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, type), fallbackColors); - assertNotEquals("Media visibility should not affect system wallpaper.", - mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM, type), fallbackColors); - } - } - - @Test public void onUiModeChanged_reloadsColors() { Tonal tonal = mock(Tonal.class); ConfigurationController configurationController = mock(ConfigurationController.class); diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt index 7a13a0a96ee6..489665cd130a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt @@ -106,7 +106,6 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { whenever(keyguardViewController.viewRootImpl).thenReturn(mock(ViewRootImpl::class.java)) whenever(powerManager.isInteractive).thenReturn(true) - whenever(wallpaperManager.isLockscreenLiveWallpaperEnabled).thenReturn(false) // All of these fields are final, so we can't mock them, but are needed so that the surface // appear amount setter doesn't short circuit. diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsTest.kt new file mode 100644 index 000000000000..1ff46db99624 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsTest.kt @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2023 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.keyguard.ui.viewmodel + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor +import com.android.systemui.coroutines.collectValues +import com.android.systemui.flags.FakeFeatureFlags +import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository +import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER +import com.android.systemui.keyguard.shared.model.ScrimAlpha +import com.android.systemui.keyguard.shared.model.TransitionState +import com.android.systemui.keyguard.shared.model.TransitionStep +import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.statusbar.SysuiStatusBarStateController +import com.android.systemui.util.mockito.whenever +import com.google.common.collect.Range +import com.google.common.truth.Truth.assertThat +import dagger.Lazy +import kotlin.time.Duration.Companion.milliseconds +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidJUnit4::class) +class BouncerToGoneFlowsTest : SysuiTestCase() { + private lateinit var underTest: BouncerToGoneFlows + private lateinit var repository: FakeKeyguardTransitionRepository + private lateinit var featureFlags: FakeFeatureFlags + @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController + @Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor + @Mock + private lateinit var keyguardDismissActionInteractor: Lazy<KeyguardDismissActionInteractor> + @Mock private lateinit var shadeInteractor: ShadeInteractor + + private val shadeExpansionStateFlow = MutableStateFlow(0.1f) + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + whenever(shadeInteractor.shadeExpansion).thenReturn(shadeExpansionStateFlow) + + repository = FakeKeyguardTransitionRepository() + val featureFlags = + FakeFeatureFlags().apply { set(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT, false) } + val interactor = + KeyguardTransitionInteractorFactory.create( + scope = TestScope().backgroundScope, + repository = repository, + ) + .keyguardTransitionInteractor + underTest = + BouncerToGoneFlows( + interactor, + statusBarStateController, + primaryBouncerInteractor, + keyguardDismissActionInteractor, + featureFlags, + shadeInteractor, + ) + + whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(false) + whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false) + } + + @Test + fun scrimAlpha_runDimissFromKeyguard_shadeExpanded() = + runTest(UnconfinedTestDispatcher()) { + val values by collectValues(underTest.scrimAlpha(500.milliseconds, PRIMARY_BOUNCER)) + shadeExpansionStateFlow.value = 1f + whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(true) + + repository.sendTransitionStep(step(0f, TransitionState.STARTED)) + repository.sendTransitionStep(step(0.3f)) + repository.sendTransitionStep(step(0.6f)) + repository.sendTransitionStep(step(1f)) + + assertThat(values.size).isEqualTo(4) + values.forEach { assertThat(it.frontAlpha).isEqualTo(0f) } + values.forEach { assertThat(it.behindAlpha).isIn(Range.closed(0f, 1f)) } + values.forEach { assertThat(it.notificationsAlpha).isIn(Range.closed(0f, 1f)) } + } + + @Test + fun scrimAlpha_runDimissFromKeyguard_shadeNotExpanded() = + runTest(UnconfinedTestDispatcher()) { + val values by collectValues(underTest.scrimAlpha(500.milliseconds, PRIMARY_BOUNCER)) + shadeExpansionStateFlow.value = 0f + + whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(true) + + repository.sendTransitionStep(step(0f, TransitionState.STARTED)) + repository.sendTransitionStep(step(0.3f)) + repository.sendTransitionStep(step(0.6f)) + repository.sendTransitionStep(step(1f)) + + assertThat(values.size).isEqualTo(4) + values.forEach { assertThat(it).isEqualTo(ScrimAlpha()) } + } + + @Test + fun scrimBehindAlpha_leaveShadeOpen() = + runTest(UnconfinedTestDispatcher()) { + val values by collectValues(underTest.scrimAlpha(500.milliseconds, PRIMARY_BOUNCER)) + + whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(true) + + repository.sendTransitionStep(step(0f, TransitionState.STARTED)) + repository.sendTransitionStep(step(0.3f)) + repository.sendTransitionStep(step(0.6f)) + repository.sendTransitionStep(step(1f)) + + assertThat(values.size).isEqualTo(4) + values.forEach { + assertThat(it).isEqualTo(ScrimAlpha(notificationsAlpha = 1f, behindAlpha = 1f)) + } + } + + @Test + fun scrimBehindAlpha_doNotLeaveShadeOpen() = + runTest(UnconfinedTestDispatcher()) { + val values by collectValues(underTest.scrimAlpha(500.milliseconds, PRIMARY_BOUNCER)) + + whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false) + + repository.sendTransitionStep(step(0f, TransitionState.STARTED)) + repository.sendTransitionStep(step(0.3f)) + repository.sendTransitionStep(step(0.6f)) + repository.sendTransitionStep(step(1f)) + + assertThat(values.size).isEqualTo(4) + values.forEach { assertThat(it.notificationsAlpha).isEqualTo(0f) } + values.forEach { assertThat(it.frontAlpha).isEqualTo(0f) } + values.forEach { assertThat(it.behindAlpha).isIn(Range.closed(0f, 1f)) } + assertThat(values[3].behindAlpha).isEqualTo(0f) + } + + private fun step( + value: Float, + state: TransitionState = TransitionState.RUNNING + ): TransitionStep { + return TransitionStep( + from = KeyguardState.PRIMARY_BOUNCER, + to = KeyguardState.GONE, + value = value, + transitionState = state, + ownerName = "PrimaryBouncerToGoneTransitionViewModelTest" + ) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt index d7802aabb298..6cab023d59b0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt @@ -27,7 +27,6 @@ import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepos import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory import com.android.systemui.keyguard.shared.model.KeyguardState -import com.android.systemui.keyguard.shared.model.ScrimAlpha import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.statusbar.SysuiStatusBarStateController @@ -35,6 +34,7 @@ import com.android.systemui.util.mockito.whenever import com.google.common.collect.Range import com.google.common.truth.Truth.assertThat import dagger.Lazy +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest @@ -52,12 +52,16 @@ class PrimaryBouncerToGoneTransitionViewModelTest : SysuiTestCase() { private lateinit var featureFlags: FakeFeatureFlags @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController @Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor + @Mock private lateinit var bouncerToGoneFlows: BouncerToGoneFlows @Mock private lateinit var keyguardDismissActionInteractor: Lazy<KeyguardDismissActionInteractor> + private val shadeExpansionStateFlow = MutableStateFlow(0.1f) + @Before fun setUp() { MockitoAnnotations.initMocks(this) + repository = FakeKeyguardTransitionRepository() val featureFlags = FakeFeatureFlags().apply { set(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT, false) } @@ -74,6 +78,7 @@ class PrimaryBouncerToGoneTransitionViewModelTest : SysuiTestCase() { primaryBouncerInteractor, keyguardDismissActionInteractor, featureFlags, + bouncerToGoneFlows, ) whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(false) @@ -148,59 +153,6 @@ class PrimaryBouncerToGoneTransitionViewModelTest : SysuiTestCase() { values.forEach { assertThat(it).isEqualTo(1f) } } - @Test - fun scrimAlpha_runDimissFromKeyguard() = - runTest(UnconfinedTestDispatcher()) { - val values by collectValues(underTest.scrimAlpha) - - whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(true) - - repository.sendTransitionStep(step(0f, TransitionState.STARTED)) - repository.sendTransitionStep(step(0.3f)) - repository.sendTransitionStep(step(0.6f)) - repository.sendTransitionStep(step(1f)) - - assertThat(values.size).isEqualTo(4) - values.forEach { assertThat(it).isEqualTo(ScrimAlpha()) } - } - - @Test - fun scrimBehindAlpha_leaveShadeOpen() = - runTest(UnconfinedTestDispatcher()) { - val values by collectValues(underTest.scrimAlpha) - - whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(true) - - repository.sendTransitionStep(step(0f, TransitionState.STARTED)) - repository.sendTransitionStep(step(0.3f)) - repository.sendTransitionStep(step(0.6f)) - repository.sendTransitionStep(step(1f)) - - assertThat(values.size).isEqualTo(4) - values.forEach { - assertThat(it).isEqualTo(ScrimAlpha(notificationsAlpha = 1f, behindAlpha = 1f)) - } - } - - @Test - fun scrimBehindAlpha_doNotLeaveShadeOpen() = - runTest(UnconfinedTestDispatcher()) { - val values by collectValues(underTest.scrimAlpha) - - whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false) - - repository.sendTransitionStep(step(0f, TransitionState.STARTED)) - repository.sendTransitionStep(step(0.3f)) - repository.sendTransitionStep(step(0.6f)) - repository.sendTransitionStep(step(1f)) - - assertThat(values.size).isEqualTo(4) - values.forEach { assertThat(it.notificationsAlpha).isEqualTo(0f) } - values.forEach { assertThat(it.frontAlpha).isEqualTo(0f) } - values.forEach { assertThat(it.behindAlpha).isIn(Range.closed(0f, 1f)) } - assertThat(values[3].behindAlpha).isEqualTo(0f) - } - private fun step( value: Float, state: TransitionState = TransitionState.RUNNING diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java index a5f5fc7e36f2..43adc69be13f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java @@ -22,14 +22,18 @@ import static android.app.NotificationManager.VISIBILITY_NO_OVERRIDE; import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED; import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS; import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS; +import static android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE; import static android.os.UserHandle.USER_ALL; import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS; import static android.provider.Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS; +import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertTrue; +import static org.junit.Assume.assumeFalse; +import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -99,6 +103,7 @@ import java.util.concurrent.Executor; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class NotificationLockscreenUserManagerTest extends SysuiTestCase { + private static final int TEST_PROFILE_USERHANDLE = 12; @Mock private NotificationPresenter mPresenter; @Mock @@ -701,6 +706,60 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { assertFalse(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(newUserId)); } + @Test + public void testProfileAvailabilityIntent() { + mSetFlagsRule.enableFlags(FLAG_ALLOW_PRIVATE_PROFILE); + mLockscreenUserManager.mCurrentProfiles.clear(); + assertEquals(0, mLockscreenUserManager.mCurrentProfiles.size()); + mLockscreenUserManager.mCurrentProfiles.append(0, mock(UserInfo.class)); + simulateProfileAvailabilityActions(Intent.ACTION_PROFILE_AVAILABLE); + assertEquals(2, mLockscreenUserManager.mCurrentProfiles.size()); + } + + @Test + public void testProfileUnAvailabilityIntent() { + mSetFlagsRule.enableFlags(FLAG_ALLOW_PRIVATE_PROFILE); + mLockscreenUserManager.mCurrentProfiles.clear(); + assertEquals(0, mLockscreenUserManager.mCurrentProfiles.size()); + mLockscreenUserManager.mCurrentProfiles.append(0, mock(UserInfo.class)); + simulateProfileAvailabilityActions(Intent.ACTION_PROFILE_UNAVAILABLE); + assertEquals(2, mLockscreenUserManager.mCurrentProfiles.size()); + } + + @Test + public void testManagedProfileAvailabilityIntent() { + mSetFlagsRule.disableFlags(FLAG_ALLOW_PRIVATE_PROFILE); + mLockscreenUserManager.mCurrentProfiles.clear(); + mLockscreenUserManager.mCurrentManagedProfiles.clear(); + assertEquals(0, mLockscreenUserManager.mCurrentProfiles.size()); + assertEquals(0, mLockscreenUserManager.mCurrentManagedProfiles.size()); + mLockscreenUserManager.mCurrentProfiles.append(0, mock(UserInfo.class)); + simulateProfileAvailabilityActions(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); + assertEquals(2, mLockscreenUserManager.mCurrentProfiles.size()); + assertEquals(1, mLockscreenUserManager.mCurrentManagedProfiles.size()); + } + + @Test + public void testManagedProfileUnAvailabilityIntent() { + mSetFlagsRule.disableFlags(FLAG_ALLOW_PRIVATE_PROFILE); + mLockscreenUserManager.mCurrentProfiles.clear(); + mLockscreenUserManager.mCurrentManagedProfiles.clear(); + assertEquals(0, mLockscreenUserManager.mCurrentProfiles.size()); + assertEquals(0, mLockscreenUserManager.mCurrentManagedProfiles.size()); + mLockscreenUserManager.mCurrentProfiles.append(0, mock(UserInfo.class)); + simulateProfileAvailabilityActions(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); + assertEquals(2, mLockscreenUserManager.mCurrentProfiles.size()); + assertEquals(1, mLockscreenUserManager.mCurrentManagedProfiles.size()); + } + + private void simulateProfileAvailabilityActions(String intentAction) { + BroadcastReceiver broadcastReceiver = + mLockscreenUserManager.getBaseBroadcastReceiverForTest(); + final Intent intent = new Intent(intentAction); + intent.putExtra(Intent.EXTRA_USER_HANDLE, TEST_PROFILE_USERHANDLE); + broadcastReceiver.onReceive(mContext, intent); + } + private class TestNotificationLockscreenUserManager extends NotificationLockscreenUserManagerImpl { public TestNotificationLockscreenUserManager(Context context) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt deleted file mode 100644 index cfcf4257ce28..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2023 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.statusbar - -import android.testing.AndroidTestingRunner -import androidx.test.filters.SmallTest -import com.android.systemui.SysuiTestCase -import com.android.systemui.util.mockito.whenever -import org.junit.After -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.Mockito.anyBoolean -import org.mockito.Mockito.doCallRealMethod -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.never -import org.mockito.Mockito.verify -import org.mockito.MockitoAnnotations - -/** - * Temporary test for the lock screen live wallpaper project. - * - * TODO(b/273443374): remove this test - */ -@RunWith(AndroidTestingRunner::class) -@SmallTest -class NotificationMediaManagerTest : SysuiTestCase() { - - @Mock private lateinit var notificationMediaManager: NotificationMediaManager - - @Mock private lateinit var mockBackDropView: BackDropView - - @Before - fun setUp() { - MockitoAnnotations.initMocks(this) - doCallRealMethod().whenever(notificationMediaManager).updateMediaMetaData(anyBoolean()) - doReturn(mockBackDropView).whenever(notificationMediaManager).backDropView - } - - @After fun tearDown() {} - - /** Check that updateMediaMetaData is a no-op with mIsLockscreenLiveWallpaperEnabled = true */ - @Test - fun testUpdateMediaMetaDataDisabled() { - notificationMediaManager.mIsLockscreenLiveWallpaperEnabled = true - for (metaDataChanged in listOf(true, false)) { - for (allowEnterAnimation in listOf(true, false)) { - notificationMediaManager.updateMediaMetaData(metaDataChanged) - verify(notificationMediaManager, never()).mediaMetadata - } - } - } -} 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 c8cbe42fb0d5..a59cd87d78da 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 @@ -277,8 +277,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mNotificationShadeWindowViewControllerLazy; @Mock private NotificationShelfController mNotificationShelfController; @Mock private DozeParameters mDozeParameters; - @Mock private Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy; - @Mock private LockscreenWallpaper mLockscreenWallpaper; @Mock private DozeServiceHost mDozeServiceHost; @Mock private BackActionInteractor mBackActionInteractor; @Mock private ViewMediatorCallback mKeyguardVieMediatorCallback; @@ -404,7 +402,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase { when(mGradientColors.supportsDarkText()).thenReturn(true); when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors); - when(mLockscreenWallpaperLazy.get()).thenReturn(mLockscreenWallpaper); when(mBiometricUnlockControllerLazy.get()).thenReturn(mBiometricUnlockController); when(mCameraLauncherLazy.get()).thenReturn(mCameraLauncher); when(mNotificationShadeWindowViewControllerLazy.get()) @@ -508,7 +505,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase { new NotificationExpansionRepository(), mDozeParameters, mScrimController, - mLockscreenWallpaperLazy, mBiometricUnlockControllerLazy, mAuthRippleController, mDozeServiceHost, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenWallpaperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenWallpaperTest.kt deleted file mode 100644 index 47671fbadd0a..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenWallpaperTest.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2023 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.statusbar.phone - -import android.app.WallpaperManager -import android.content.pm.UserInfo -import android.os.Looper -import androidx.test.filters.SmallTest -import com.android.systemui.SysuiTestCase -import com.android.systemui.user.data.model.SelectionStatus -import com.android.systemui.user.data.repository.FakeUserRepository -import com.android.systemui.util.kotlin.JavaAdapter -import com.android.systemui.util.mockito.any -import com.android.systemui.util.mockito.mock -import com.android.systemui.util.mockito.whenever -import com.android.systemui.utils.os.FakeHandler -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.StandardTestDispatcher -import kotlinx.coroutines.test.TestScope -import kotlinx.coroutines.test.runTest -import org.junit.Before -import org.junit.Test -import org.mockito.ArgumentMatchers.eq -import org.mockito.Mockito.verify - -@SmallTest -@OptIn(ExperimentalCoroutinesApi::class) -class LockscreenWallpaperTest : SysuiTestCase() { - - private lateinit var underTest: LockscreenWallpaper - - private val testScope = TestScope(StandardTestDispatcher()) - private val userRepository = FakeUserRepository() - - private val wallpaperManager: WallpaperManager = mock() - - @Before - fun setUp() { - whenever(wallpaperManager.isLockscreenLiveWallpaperEnabled).thenReturn(false) - whenever(wallpaperManager.isWallpaperSupported).thenReturn(true) - underTest = - LockscreenWallpaper( - /* wallpaperManager= */ wallpaperManager, - /* iWallpaperManager= */ mock(), - /* keyguardUpdateMonitor= */ mock(), - /* dumpManager= */ mock(), - /* mediaManager= */ mock(), - /* mainHandler= */ FakeHandler(Looper.getMainLooper()), - /* javaAdapter= */ JavaAdapter(testScope.backgroundScope), - /* userRepository= */ userRepository, - /* userTracker= */ mock(), - ) - underTest.start() - } - - @Test - fun getBitmap_matchesUserIdFromUserRepo() = - testScope.runTest { - val info = UserInfo(/* id= */ 5, /* name= */ "id5", /* flags= */ 0) - userRepository.setUserInfos(listOf(info)) - userRepository.setSelectedUserInfo(info) - - underTest.bitmap - - verify(wallpaperManager).getWallpaperFile(any(), eq(5)) - } - - @Test - fun getBitmap_usesOldUserIfNewUserInProgress() = - testScope.runTest { - val info5 = UserInfo(/* id= */ 5, /* name= */ "id5", /* flags= */ 0) - val info6 = UserInfo(/* id= */ 6, /* name= */ "id6", /* flags= */ 0) - userRepository.setUserInfos(listOf(info5, info6)) - userRepository.setSelectedUserInfo(info5) - - // WHEN the selection of user 6 is only in progress - userRepository.setSelectedUserInfo( - info6, - selectionStatus = SelectionStatus.SELECTION_IN_PROGRESS - ) - - underTest.bitmap - - // THEN we still use user 5 for wallpaper selection - verify(wallpaperManager).getWallpaperFile(any(), eq(5)) - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java index 6b3bd22d5e62..15c09b53938f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java @@ -70,6 +70,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac import com.android.systemui.keyguard.shared.model.KeyguardState; import com.android.systemui.keyguard.shared.model.TransitionState; import com.android.systemui.keyguard.shared.model.TransitionStep; +import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToGoneTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel; import com.android.systemui.scrim.ScrimView; import com.android.systemui.shade.transition.LargeScreenShadeInterpolator; @@ -141,6 +142,8 @@ public class ScrimControllerTest extends SysuiTestCase { @Mock private ScreenOffAnimationController mScreenOffAnimationController; @Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController; @Mock private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel; + @Mock private AlternateBouncerToGoneTransitionViewModel + mAlternateBouncerToGoneTransitionViewModel; @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor; private final FakeWallpaperRepository mWallpaperRepository = new FakeWallpaperRepository(); @Mock private CoroutineDispatcher mMainDispatcher; @@ -264,10 +267,12 @@ public class ScrimControllerTest extends SysuiTestCase { when(mDelayedWakeLockBuilder.build()).thenReturn(mWakeLock); when(mDockManager.isDocked()).thenReturn(false); - when(mKeyguardTransitionInteractor.getPrimaryBouncerToGoneTransition()) + when(mKeyguardTransitionInteractor.transition(any(), any())) .thenReturn(emptyFlow()); when(mPrimaryBouncerToGoneTransitionViewModel.getScrimAlpha()) .thenReturn(emptyFlow()); + when(mAlternateBouncerToGoneTransitionViewModel.getScrimAlpha()) + .thenReturn(emptyFlow()); mScrimController = new ScrimController( mLightBarController, @@ -285,6 +290,7 @@ public class ScrimControllerTest extends SysuiTestCase { mKeyguardUnlockAnimationController, mStatusBarKeyguardViewManager, mPrimaryBouncerToGoneTransitionViewModel, + mAlternateBouncerToGoneTransitionViewModel, mKeyguardTransitionInteractor, mWallpaperRepository, mMainDispatcher, @@ -992,6 +998,7 @@ public class ScrimControllerTest extends SysuiTestCase { mKeyguardUnlockAnimationController, mStatusBarKeyguardViewManager, mPrimaryBouncerToGoneTransitionViewModel, + mAlternateBouncerToGoneTransitionViewModel, mKeyguardTransitionInteractor, mWallpaperRepository, mMainDispatcher, @@ -1775,7 +1782,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void ignoreTransitionRequestWhileKeyguardTransitionRunning() { mScrimController.transitionTo(ScrimState.UNLOCKED); - mScrimController.mPrimaryBouncerToGoneTransition.accept( + mScrimController.mBouncerToGoneTransition.accept( new TransitionStep(KeyguardState.PRIMARY_BOUNCER, KeyguardState.GONE, 0f, TransitionState.RUNNING, "ScrimControllerTest")); @@ -1787,7 +1794,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void primaryBouncerToGoneOnFinishCallsKeyguardFadedAway() { when(mKeyguardStateController.isKeyguardFadingAway()).thenReturn(true); - mScrimController.mPrimaryBouncerToGoneTransition.accept( + mScrimController.mBouncerToGoneTransition.accept( new TransitionStep(KeyguardState.PRIMARY_BOUNCER, KeyguardState.GONE, 0f, TransitionState.FINISHED, "ScrimControllerTest")); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt new file mode 100644 index 000000000000..21d22bcf3d2a --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2023 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.statusbar.phone + +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper.RunWithLooper +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.statusbar.policy.ConfigurationController +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.mock +import kotlin.test.Test +import org.junit.Before +import org.junit.runner.RunWith +import org.mockito.Mockito.verify + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@RunWithLooper(setAsMainLooper = true) +class SystemUIBottomSheetDialogTest : SysuiTestCase() { + + private val configurationController = mock<ConfigurationController>() + + private lateinit var dialog: SystemUIBottomSheetDialog + + @Before + fun setup() { + dialog = SystemUIBottomSheetDialog(mContext, configurationController) + } + + @Test + fun onStart_registersConfigCallback() { + dialog.show() + + verify(configurationController).addCallback(any()) + } + + @Test + fun onStop_unregisterConfigCallback() { + dialog.show() + dialog.dismiss() + + verify(configurationController).removeCallback(any()) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceStateRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceStateRepositoryTest.kt new file mode 100644 index 000000000000..4eb159103b49 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceStateRepositoryTest.kt @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2023 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.unfold.updates + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.unfold.system.DeviceStateRepositoryImpl +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.argumentCaptor +import com.android.systemui.util.mockito.capture +import com.android.systemui.util.mockito.mock +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.verify + +@RunWith(AndroidTestingRunner::class) +@SmallTest +class DeviceStateRepositoryTest : SysuiTestCase() { + + private val foldProvider = mock<FoldProvider>() + private val testScope = TestScope(UnconfinedTestDispatcher()) + + private val foldStateRepository = DeviceStateRepositoryImpl(foldProvider) { r -> r.run() } + + @Test + fun onHingeAngleUpdate_received() = + testScope.runTest { + val flowValue = collectLastValue(foldStateRepository.isFolded) + val foldCallback = argumentCaptor<FoldProvider.FoldCallback>() + + verify(foldProvider).registerCallback(capture(foldCallback), any()) + + foldCallback.value.onFoldUpdated(true) + assertThat(flowValue()).isEqualTo(true) + + foldCallback.value.onFoldUpdated(false) + assertThat(flowValue()).isEqualTo(false) + } + + @Test + fun onHingeAngleUpdate_unregisters() { + testScope.runTest { + val flowValue = collectLastValue(foldStateRepository.isFolded) + + verify(foldProvider).registerCallback(any(), any()) + } + verify(foldProvider).unregisterCallback(any()) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/FoldStateRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/FoldStateRepositoryTest.kt new file mode 100644 index 000000000000..065132300564 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/FoldStateRepositoryTest.kt @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2023 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.unfold.updates + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.unfold.updates.FoldStateRepository.FoldUpdate +import com.android.systemui.util.mockito.argumentCaptor +import com.android.systemui.util.mockito.capture +import com.android.systemui.util.mockito.mock +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.verify + +@RunWith(AndroidTestingRunner::class) +@SmallTest +class FoldStateRepositoryTest : SysuiTestCase() { + + private val foldStateProvider = mock<FoldStateProvider>() + private val foldUpdatesListener = argumentCaptor<FoldStateProvider.FoldUpdatesListener>() + private val testScope = TestScope(UnconfinedTestDispatcher()) + + private val foldStateRepository = FoldStateRepositoryImpl(foldStateProvider) + @Test + fun onHingeAngleUpdate_received() = + testScope.runTest { + val flowValue = collectLastValue(foldStateRepository.hingeAngle) + + verify(foldStateProvider).addCallback(capture(foldUpdatesListener)) + foldUpdatesListener.value.onHingeAngleUpdate(42f) + + assertThat(flowValue()).isEqualTo(42f) + } + + @Test + fun onFoldUpdate_received() = + testScope.runTest { + val flowValue = collectLastValue(foldStateRepository.foldUpdate) + + verify(foldStateProvider).addCallback(capture(foldUpdatesListener)) + foldUpdatesListener.value.onFoldUpdate(FOLD_UPDATE_START_OPENING) + + assertThat(flowValue()).isEqualTo(FoldUpdate.START_OPENING) + } + + @Test + fun foldUpdates_mappedCorrectly() { + mapOf( + FOLD_UPDATE_START_OPENING to FoldUpdate.START_OPENING, + FOLD_UPDATE_START_CLOSING to FoldUpdate.START_CLOSING, + FOLD_UPDATE_FINISH_HALF_OPEN to FoldUpdate.FINISH_HALF_OPEN, + FOLD_UPDATE_FINISH_FULL_OPEN to FoldUpdate.FINISH_FULL_OPEN, + FOLD_UPDATE_FINISH_CLOSED to FoldUpdate.FINISH_CLOSED + ) + .forEach { (id, expected) -> + assertThat(FoldUpdate.fromFoldUpdateId(id)).isEqualTo(expected) + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java index 468c5a73645b..fc2030f694ad 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java @@ -16,15 +16,20 @@ package com.android.systemui.wallpapers; +import static android.app.WallpaperManager.FLAG_LOCK; +import static android.app.WallpaperManager.FLAG_SYSTEM; + import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.hamcrest.Matchers.equalTo; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -111,7 +116,8 @@ public class ImageWallpaperTest extends SysuiTestCase { when(mWallpaperBitmap.getConfig()).thenReturn(Bitmap.Config.ARGB_8888); // set up wallpaper manager - when(mWallpaperManager.getBitmapAsUser(eq(ActivityManager.getCurrentUser()), anyBoolean())) + when(mWallpaperManager.getBitmapAsUser( + eq(ActivityManager.getCurrentUser()), anyBoolean(), anyInt(), anyBoolean())) .thenReturn(mWallpaperBitmap); when(mMockContext.getSystemService(WallpaperManager.class)).thenReturn(mWallpaperManager); @@ -208,6 +214,7 @@ public class ImageWallpaperTest extends SysuiTestCase { ImageWallpaper.CanvasEngine spyEngine = spy(engine); doNothing().when(spyEngine).drawFrameOnCanvas(any(Bitmap.class)); doNothing().when(spyEngine).reportEngineShown(anyBoolean()); + doReturn(FLAG_SYSTEM | FLAG_LOCK).when(spyEngine).getWallpaperFlags(); doAnswer(invocation -> { ((ImageWallpaper.CanvasEngine) invocation.getMock()).onMiniBitmapUpdated(); return null; @@ -216,7 +223,7 @@ public class ImageWallpaperTest extends SysuiTestCase { } private void setBitmapDimensions(int bitmapWidth, int bitmapHeight) { - when(mWallpaperManager.peekBitmapDimensions()) + when(mWallpaperManager.peekBitmapDimensions(anyInt(), anyBoolean())) .thenReturn(new Rect(0, 0, bitmapWidth, bitmapHeight)); when(mWallpaperBitmap.getWidth()).thenReturn(bitmapWidth); when(mWallpaperBitmap.getHeight()).thenReturn(bitmapHeight); @@ -234,9 +241,7 @@ public class ImageWallpaperTest extends SysuiTestCase { clearInvocations(mSurfaceHolder); setBitmapDimensions(bitmapWidth, bitmapHeight); - ImageWallpaper imageWallpaper = createImageWallpaper(); - ImageWallpaper.CanvasEngine engine = - (ImageWallpaper.CanvasEngine) imageWallpaper.onCreateEngine(); + ImageWallpaper.CanvasEngine engine = getSpyEngine(); engine.onCreate(mSurfaceHolder); verify(mSurfaceHolder, times(1)).setFixedSize( diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt index 5ffc094b88b3..7473ca6a6486 100644 --- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt +++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt @@ -22,6 +22,8 @@ import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgress import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder import com.android.systemui.unfold.updates.DeviceFoldStateProvider import com.android.systemui.unfold.updates.FoldStateProvider +import com.android.systemui.unfold.updates.FoldStateRepository +import com.android.systemui.unfold.updates.FoldStateRepositoryImpl import com.android.systemui.unfold.updates.hinge.EmptyHingeAngleProvider import com.android.systemui.unfold.updates.hinge.HingeAngleProvider import com.android.systemui.unfold.updates.hinge.HingeSensorAngleProvider @@ -55,6 +57,12 @@ class UnfoldSharedModule { fun unfoldKeyguardVisibilityManager( impl: UnfoldKeyguardVisibilityManagerImpl ): UnfoldKeyguardVisibilityManager = impl + + @Provides + @Singleton + fun foldStateRepository( + impl: FoldStateRepositoryImpl + ): FoldStateRepository = impl } /** diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt index 6743515c2ec7..003013e18583 100644 --- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt +++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt @@ -17,7 +17,6 @@ package com.android.systemui.unfold.updates import android.content.Context import android.os.Handler -import android.os.Trace import android.util.Log import androidx.annotation.FloatRange import androidx.annotation.VisibleForTesting @@ -130,7 +129,6 @@ constructor( "lastHingeAngleBeforeTransition: $lastHingeAngleBeforeTransition" ) } - Trace.setCounter("DeviceFoldStateProvider#onHingeAngle", angle.toLong()) val currentDirection = if (angle < lastHingeAngle) FOLD_UPDATE_START_CLOSING else FOLD_UPDATE_START_OPENING diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldProvider.kt index 6e87beeb295f..ea6786e6c4bc 100644 --- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldProvider.kt +++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldProvider.kt @@ -20,7 +20,7 @@ interface FoldProvider { fun registerCallback(callback: FoldCallback, executor: Executor) fun unregisterCallback(callback: FoldCallback) - interface FoldCallback { + fun interface FoldCallback { fun onFoldUpdated(isFolded: Boolean) } } diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateRepository.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateRepository.kt new file mode 100644 index 000000000000..61b0b40a55bf --- /dev/null +++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateRepository.kt @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2023 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.unfold.updates + +import com.android.systemui.unfold.updates.FoldStateRepository.FoldUpdate +import javax.inject.Inject +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.buffer +import kotlinx.coroutines.flow.callbackFlow + +/** + * Allows to subscribe to main events related to fold/unfold process such as hinge angle update, + * start folding/unfolding, screen availability + */ +interface FoldStateRepository { + /** Latest fold update, as described by [FoldStateProvider.FoldUpdate]. */ + val foldUpdate: Flow<FoldUpdate> + + /** Provides the hinge angle while the fold/unfold is in progress. */ + val hingeAngle: Flow<Float> + + enum class FoldUpdate { + START_OPENING, + START_CLOSING, + FINISH_HALF_OPEN, + FINISH_FULL_OPEN, + FINISH_CLOSED; + + companion object { + /** Maps the old [FoldStateProvider.FoldUpdate] to [FoldStateRepository.FoldUpdate]. */ + fun fromFoldUpdateId(@FoldStateProvider.FoldUpdate oldId: Int): FoldUpdate { + return when (oldId) { + FOLD_UPDATE_START_OPENING -> START_OPENING + FOLD_UPDATE_START_CLOSING -> START_CLOSING + FOLD_UPDATE_FINISH_HALF_OPEN -> FINISH_HALF_OPEN + FOLD_UPDATE_FINISH_FULL_OPEN -> FINISH_FULL_OPEN + FOLD_UPDATE_FINISH_CLOSED -> FINISH_CLOSED + else -> error("FoldUpdateNotFound") + } + } + } + } +} + +class FoldStateRepositoryImpl +@Inject +constructor( + private val foldStateProvider: FoldStateProvider, +) : FoldStateRepository { + + override val hingeAngle: Flow<Float> + get() = + callbackFlow { + val callback = + object : FoldStateProvider.FoldUpdatesListener { + override fun onHingeAngleUpdate(angle: Float) { + trySend(angle) + } + } + foldStateProvider.addCallback(callback) + awaitClose { foldStateProvider.removeCallback(callback) } + } + .buffer(capacity = Channel.CONFLATED) + + override val foldUpdate: Flow<FoldUpdate> + get() = + callbackFlow { + val callback = + object : FoldStateProvider.FoldUpdatesListener { + override fun onFoldUpdate(update: Int) { + trySend(FoldUpdate.fromFoldUpdateId(update)) + } + } + foldStateProvider.addCallback(callback) + awaitClose { foldStateProvider.removeCallback(callback) } + } + .buffer(capacity = Channel.CONFLATED) +} diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java index 3406102b28ac..98421a9e1d3e 100644 --- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java +++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java @@ -367,11 +367,7 @@ public class WallpaperBackupAgent extends BackupAgent { ComponentName wpService = parseWallpaperComponent(infoStage, "wp"); mSystemHasLiveComponent = wpService != null; - ComponentName kwpService = null; - boolean lockscreenLiveWallpaper = mWallpaperManager.isLockscreenLiveWallpaperEnabled(); - if (lockscreenLiveWallpaper) { - kwpService = parseWallpaperComponent(infoStage, "kwp"); - } + ComponentName kwpService = parseWallpaperComponent(infoStage, "kwp"); mLockHasLiveComponent = kwpService != null; boolean separateLockWallpaper = mLockHasLiveComponent || lockImageStage.exists(); @@ -381,17 +377,16 @@ public class WallpaperBackupAgent extends BackupAgent { // It is valid for the imagery to be absent; it means that we were not permitted // to back up the original image on the source device, or there was no user-supplied // wallpaper image present. - if (!lockscreenLiveWallpaper) restoreFromStage(imageStage, infoStage, "wp", sysWhich); if (lockImageStageExists) { restoreFromStage(lockImageStage, infoStage, "kwp", FLAG_LOCK); } - if (lockscreenLiveWallpaper) restoreFromStage(imageStage, infoStage, "wp", sysWhich); + restoreFromStage(imageStage, infoStage, "wp", sysWhich); // And reset to the wallpaper service we should be using - if (lockscreenLiveWallpaper && mLockHasLiveComponent) { - updateWallpaperComponent(kwpService, false, FLAG_LOCK); + if (mLockHasLiveComponent) { + updateWallpaperComponent(kwpService, FLAG_LOCK); } - updateWallpaperComponent(wpService, !lockImageStageExists, sysWhich); + updateWallpaperComponent(wpService, sysWhich); } catch (Exception e) { Slog.e(TAG, "Unable to restore wallpaper: " + e.getMessage()); mEventLogger.onRestoreException(e); @@ -410,36 +405,24 @@ public class WallpaperBackupAgent extends BackupAgent { } @VisibleForTesting - void updateWallpaperComponent(ComponentName wpService, boolean applyToLock, int which) + void updateWallpaperComponent(ComponentName wpService, int which) throws IOException { - boolean lockscreenLiveWallpaper = mWallpaperManager.isLockscreenLiveWallpaperEnabled(); if (servicePackageExists(wpService)) { Slog.i(TAG, "Using wallpaper service " + wpService); - if (lockscreenLiveWallpaper) { - mWallpaperManager.setWallpaperComponentWithFlags(wpService, which); - if ((which & FLAG_LOCK) != 0) { - mEventLogger.onLockLiveWallpaperRestored(wpService); - } - if ((which & FLAG_SYSTEM) != 0) { - mEventLogger.onSystemLiveWallpaperRestored(wpService); - } - return; - } - mWallpaperManager.setWallpaperComponent(wpService); - if (applyToLock) { - // We have a live wallpaper and no static lock image, - // allow live wallpaper to show "through" on lock screen. - mWallpaperManager.clear(FLAG_LOCK); + mWallpaperManager.setWallpaperComponentWithFlags(wpService, which); + if ((which & FLAG_LOCK) != 0) { mEventLogger.onLockLiveWallpaperRestored(wpService); } - mEventLogger.onSystemLiveWallpaperRestored(wpService); + if ((which & FLAG_SYSTEM) != 0) { + mEventLogger.onSystemLiveWallpaperRestored(wpService); + } } else { // If we've restored a live wallpaper, but the component doesn't exist, // we should log it as an error so we can easily identify the problem // in reports from users if (wpService != null) { // TODO(b/268471749): Handle delayed case - applyComponentAtInstall(wpService, applyToLock, which); + applyComponentAtInstall(wpService, which); Slog.w(TAG, "Wallpaper service " + wpService + " isn't available. " + " Will try to apply later"); } @@ -579,21 +562,17 @@ public class WallpaperBackupAgent extends BackupAgent { // Intentionally blank } - private void applyComponentAtInstall(ComponentName componentName, boolean applyToLock, - int which) { + private void applyComponentAtInstall(ComponentName componentName, int which) { PackageMonitor packageMonitor = getWallpaperPackageMonitor( - componentName, applyToLock, which); + componentName, which); packageMonitor.register(getBaseContext(), null, UserHandle.ALL, true); } @VisibleForTesting - PackageMonitor getWallpaperPackageMonitor(ComponentName componentName, boolean applyToLock, - int which) { + PackageMonitor getWallpaperPackageMonitor(ComponentName componentName, int which) { return new PackageMonitor() { @Override public void onPackageAdded(String packageName, int uid) { - boolean lockscreenLiveWallpaper = - mWallpaperManager.isLockscreenLiveWallpaperEnabled(); if (!isDeviceInRestore()) { // We don't want to reapply the wallpaper outside a restore. unregister(); @@ -601,9 +580,11 @@ public class WallpaperBackupAgent extends BackupAgent { // We have finished restore and not succeeded, so let's log that as an error. WallpaperEventLogger logger = new WallpaperEventLogger( mBackupManager.getDelayedRestoreLogger()); - logger.onSystemLiveWallpaperRestoreFailed( - WallpaperEventLogger.ERROR_LIVE_PACKAGE_NOT_INSTALLED); - if (applyToLock) { + if ((which & FLAG_SYSTEM) != 0) { + logger.onSystemLiveWallpaperRestoreFailed( + WallpaperEventLogger.ERROR_LIVE_PACKAGE_NOT_INSTALLED); + } + if ((which & FLAG_LOCK) != 0) { logger.onLockLiveWallpaperRestoreFailed( WallpaperEventLogger.ERROR_LIVE_PACKAGE_NOT_INSTALLED); } @@ -614,37 +595,27 @@ public class WallpaperBackupAgent extends BackupAgent { if (componentName.getPackageName().equals(packageName)) { Slog.d(TAG, "Applying component " + componentName); - boolean success = lockscreenLiveWallpaper - ? mWallpaperManager.setWallpaperComponentWithFlags(componentName, which) - : mWallpaperManager.setWallpaperComponent(componentName); + boolean success = mWallpaperManager.setWallpaperComponentWithFlags( + componentName, which); WallpaperEventLogger logger = new WallpaperEventLogger( mBackupManager.getDelayedRestoreLogger()); if (success) { - if (!lockscreenLiveWallpaper || (which & FLAG_SYSTEM) != 0) { + if ((which & FLAG_SYSTEM) != 0) { logger.onSystemLiveWallpaperRestored(componentName); } - if (lockscreenLiveWallpaper && (which & FLAG_LOCK) != 0) { + if ((which & FLAG_LOCK) != 0) { logger.onLockLiveWallpaperRestored(componentName); } } else { - if (!lockscreenLiveWallpaper || (which & FLAG_SYSTEM) != 0) { + if ((which & FLAG_SYSTEM) != 0) { logger.onSystemLiveWallpaperRestoreFailed( WallpaperEventLogger.ERROR_SET_COMPONENT_EXCEPTION); } - if (lockscreenLiveWallpaper && (which & FLAG_LOCK) != 0) { + if ((which & FLAG_LOCK) != 0) { logger.onLockLiveWallpaperRestoreFailed( WallpaperEventLogger.ERROR_SET_COMPONENT_EXCEPTION); } } - if (applyToLock && !lockscreenLiveWallpaper) { - try { - mWallpaperManager.clear(FLAG_LOCK); - logger.onLockLiveWallpaperRestored(componentName); - } catch (IOException e) { - Slog.w(TAG, "Failed to apply live wallpaper to lock screen: " + e); - logger.onLockLiveWallpaperRestoreFailed(e.getClass().getName()); - } - } // We're only expecting to restore the wallpaper component once. unregister(); mBackupManager.reportDelayedRestoreResult(logger.getBackupRestoreLogger()); diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java index dc1126edde41..4c224fb33b26 100644 --- a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java +++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java @@ -116,8 +116,6 @@ public class WallpaperBackupAgentTest { @Before public void setUp() { MockitoAnnotations.initMocks(this); - - when(mWallpaperManager.isLockscreenLiveWallpaperEnabled()).thenReturn(true); when(mWallpaperManager.isWallpaperBackupEligible(eq(FLAG_SYSTEM))).thenReturn(true); when(mWallpaperManager.isWallpaperBackupEligible(eq(FLAG_LOCK))).thenReturn(true); @@ -363,25 +361,19 @@ public class WallpaperBackupAgentTest { @Test public void testUpdateWallpaperComponent_doesApplyLater() throws IOException { mWallpaperBackupAgent.mIsDeviceInRestore = true; - mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent, - /* applyToLock */ true, FLAG_LOCK | FLAG_SYSTEM); + /* which */ FLAG_LOCK | FLAG_SYSTEM); // Imitate wallpaper component installation. mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, /* uid */0); - if (mWallpaperManager.isLockscreenLiveWallpaperEnabled()) { - verify(mWallpaperManager, times(1)) - .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM); - verify(mWallpaperManager, never()) - .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM); - verify(mWallpaperManager, never()) - .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK); - verify(mWallpaperManager, never()).clear(anyInt()); - } else { - verify(mWallpaperManager, times(1)).setWallpaperComponent(mWallpaperComponent); - verify(mWallpaperManager, times(1)).clear(eq(FLAG_LOCK)); - } + verify(mWallpaperManager, times(1)) + .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM); + verify(mWallpaperManager, never()) + .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM); + verify(mWallpaperManager, never()) + .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK); + verify(mWallpaperManager, never()).clear(anyInt()); } @Test @@ -390,24 +382,19 @@ public class WallpaperBackupAgentTest { mWallpaperBackupAgent.mIsDeviceInRestore = true; mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent, - /* applyToLock */ false, FLAG_SYSTEM); + /* which */ FLAG_SYSTEM); // Imitate wallpaper component installation. mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, /* uid */0); - if (mWallpaperManager.isLockscreenLiveWallpaperEnabled()) { - verify(mWallpaperManager, times(1)) - .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM); - verify(mWallpaperManager, never()) - .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK); - verify(mWallpaperManager, never()) - .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM); - verify(mWallpaperManager, never()).clear(anyInt()); - } else { - verify(mWallpaperManager, times(1)).setWallpaperComponent(mWallpaperComponent); - verify(mWallpaperManager, never()).clear(eq(FLAG_LOCK)); - } + verify(mWallpaperManager, times(1)) + .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM); + verify(mWallpaperManager, never()) + .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK); + verify(mWallpaperManager, never()) + .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM); + verify(mWallpaperManager, never()).clear(anyInt()); } @Test @@ -416,7 +403,7 @@ public class WallpaperBackupAgentTest { mWallpaperBackupAgent.mIsDeviceInRestore = false; mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent, - /* applyToLock */ true, FLAG_LOCK | FLAG_SYSTEM); + /* which */ FLAG_LOCK | FLAG_SYSTEM); // Imitate wallpaper component installation. mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, @@ -432,7 +419,7 @@ public class WallpaperBackupAgentTest { mWallpaperBackupAgent.mIsDeviceInRestore = false; mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent, - /* applyToLock */ true, FLAG_LOCK | FLAG_SYSTEM); + /* which */ FLAG_LOCK | FLAG_SYSTEM); // Imitate "wrong" wallpaper component installation. mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(/* packageName */"", @@ -622,7 +609,7 @@ public class WallpaperBackupAgentTest { } @Test - public void testOnRestore_systemWallpaperImgSuccess_logsSuccess() throws Exception { + public void testOnRestore_wallpaperImgSuccess_logsSuccess() throws Exception { mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, @@ -630,17 +617,16 @@ public class WallpaperBackupAgentTest { mWallpaperBackupAgent.onRestoreFinished(); + // wallpaper will be applied to home & lock screen, a success for both screens in expected DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(result).isNotNull(); assertThat(result.getSuccessCount()).isEqualTo(1); - if (mWallpaperManager.isLockscreenLiveWallpaperEnabled()) { - result = getLoggingResult(WALLPAPER_IMG_LOCK, - mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); - assertThat(result).isNotNull(); - assertThat(result.getSuccessCount()).isEqualTo(1); - } + result = getLoggingResult(WALLPAPER_IMG_LOCK, + mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); + assertThat(result).isNotNull(); + assertThat(result.getSuccessCount()).isEqualTo(1); } @Test @@ -758,7 +744,7 @@ public class WallpaperBackupAgentTest { mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager); mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent, - /* applyToLock */ true, FLAG_LOCK | FLAG_SYSTEM); + /* which */ FLAG_LOCK | FLAG_SYSTEM); // Imitate wallpaper component installation. mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, /* uid */0); @@ -782,7 +768,7 @@ public class WallpaperBackupAgentTest { mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager); mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent, - /* applyToLock */ true, FLAG_LOCK | FLAG_SYSTEM); + /* which */ FLAG_LOCK | FLAG_SYSTEM); // Imitate wallpaper component installation. mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, /* uid */0); @@ -804,7 +790,7 @@ public class WallpaperBackupAgentTest { mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager); mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent, - /* applyToLock */ true, FLAG_LOCK | FLAG_SYSTEM); + /* which */ FLAG_LOCK | FLAG_SYSTEM); // Imitate wallpaper component installation. mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, @@ -938,10 +924,8 @@ public class WallpaperBackupAgentTest { } @Override - PackageMonitor getWallpaperPackageMonitor(ComponentName componentName, - boolean applyToLock, int which) { - mWallpaperPackageMonitor = super.getWallpaperPackageMonitor( - componentName, applyToLock, which); + PackageMonitor getWallpaperPackageMonitor(ComponentName componentName, int which) { + mWallpaperPackageMonitor = super.getWallpaperPackageMonitor(componentName, which); return mWallpaperPackageMonitor; } diff --git a/services/core/java/com/android/server/media/AudioAttributesUtils.java b/services/core/java/com/android/server/media/AudioAttributesUtils.java index 5d5d59bcb6ef..8cb334dc2260 100644 --- a/services/core/java/com/android/server/media/AudioAttributesUtils.java +++ b/services/core/java/com/android/server/media/AudioAttributesUtils.java @@ -23,6 +23,8 @@ import android.media.AudioDeviceAttributes; import android.media.AudioDeviceInfo; import android.media.MediaRoute2Info; +import com.android.media.flags.Flags; + /* package */ final class AudioAttributesUtils { /* package */ static final AudioAttributes ATTRIBUTES_MEDIA = new AudioAttributes.Builder() @@ -36,6 +38,14 @@ import android.media.MediaRoute2Info; @MediaRoute2Info.Type /* package */ static int mapToMediaRouteType( @NonNull AudioDeviceAttributes audioDeviceAttributes) { + if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) { + switch (audioDeviceAttributes.getType()) { + case AudioDeviceInfo.TYPE_HDMI_ARC: + return MediaRoute2Info.TYPE_HDMI_ARC; + case AudioDeviceInfo.TYPE_HDMI_EARC: + return MediaRoute2Info.TYPE_HDMI_EARC; + } + } switch (audioDeviceAttributes.getType()) { case AudioDeviceInfo.TYPE_BUILTIN_EARPIECE: case AudioDeviceInfo.TYPE_BUILTIN_SPEAKER: @@ -64,7 +74,6 @@ import android.media.MediaRoute2Info; } } - /* package */ static boolean isDeviceOutputAttributes( @Nullable AudioDeviceAttributes audioDeviceAttributes) { if (audioDeviceAttributes == null) { diff --git a/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java b/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java index 33190ade4f42..360a6a721988 100644 --- a/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java +++ b/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java @@ -22,6 +22,8 @@ import static android.media.MediaRoute2Info.FEATURE_LOCAL_PLAYBACK; import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER; import static android.media.MediaRoute2Info.TYPE_DOCK; import static android.media.MediaRoute2Info.TYPE_HDMI; +import static android.media.MediaRoute2Info.TYPE_HDMI_ARC; +import static android.media.MediaRoute2Info.TYPE_HDMI_EARC; import static android.media.MediaRoute2Info.TYPE_USB_DEVICE; import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES; import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET; @@ -160,7 +162,6 @@ import java.util.Objects; @NonNull private MediaRoute2Info createRouteFromAudioInfo(@MediaRoute2Info.Type int type) { int name = R.string.default_audio_route_name; - switch (type) { case TYPE_WIRED_HEADPHONES: case TYPE_WIRED_HEADSET: @@ -170,6 +171,8 @@ import java.util.Objects; name = R.string.default_audio_route_name_dock_speakers; break; case TYPE_HDMI: + case TYPE_HDMI_ARC: + case TYPE_HDMI_EARC: name = R.string.default_audio_route_name_external_device; break; case TYPE_USB_DEVICE: @@ -211,6 +214,8 @@ import java.util.Objects; case TYPE_WIRED_HEADSET: case TYPE_DOCK: case TYPE_HDMI: + case TYPE_HDMI_ARC: + case TYPE_HDMI_EARC: case TYPE_USB_DEVICE: return true; default: diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index b4d36db96c01..452be2f435f5 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -71,6 +71,7 @@ import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE; +import static android.os.Flags.allowPrivateProfile; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; import static android.os.PowerWhitelistManager.REASON_NOTIFICATION_SERVICE; @@ -1931,7 +1932,8 @@ public class NotificationManagerService extends SystemService { cancelAllNotificationsInt(MY_UID, MY_PID, null, null, 0, 0, userHandle, REASON_USER_STOPPED); } - } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)) { + } else if ( + isProfileUnavailable(action)) { int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); if (userHandle >= 0 && !mDpm.isKeepProfilesRunningEnabled()) { cancelAllNotificationsInt(MY_UID, MY_PID, null, null, 0, 0, userHandle, @@ -1982,6 +1984,12 @@ public class NotificationManagerService extends SystemService { } } } + + private boolean isProfileUnavailable(String action) { + return allowPrivateProfile() ? + action.equals(Intent.ACTION_PROFILE_UNAVAILABLE) : + action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); + } }; private final class SettingsObserver extends ContentObserver { @@ -2552,6 +2560,9 @@ public class NotificationManagerService extends SystemService { filter.addAction(Intent.ACTION_USER_REMOVED); filter.addAction(Intent.ACTION_USER_UNLOCKED); filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); + if (allowPrivateProfile()){ + filter.addAction(Intent.ACTION_PROFILE_UNAVAILABLE); + } getContext().registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter, null, null); IntentFilter pkgFilter = new IntentFilter(); diff --git a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java index c54e3bdf0d51..5f8bbe5f18ad 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java @@ -29,7 +29,6 @@ import static com.android.server.wallpaper.WallpaperUtils.makeWallpaperIdLocked; import android.annotation.Nullable; import android.app.WallpaperColors; -import android.app.WallpaperManager; import android.app.WallpaperManager.SetWallpaperFlags; import android.app.backup.WallpaperBackupHelper; import android.content.ComponentName; @@ -38,7 +37,6 @@ import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Color; import android.os.FileUtils; -import android.os.SystemProperties; import android.util.Slog; import android.util.SparseArray; import android.util.Xml; @@ -77,8 +75,6 @@ class WallpaperDataParser { private final WallpaperCropper mWallpaperCropper; private final Context mContext; - private final boolean mIsLockscreenLiveWallpaperEnabled; - WallpaperDataParser(Context context, WallpaperDisplayHelper wallpaperDisplayHelper, WallpaperCropper wallpaperCropper) { mContext = context; @@ -86,8 +82,6 @@ class WallpaperDataParser { mWallpaperCropper = wallpaperCropper; mImageWallpaper = ComponentName.unflattenFromString( context.getResources().getString(R.string.image_wallpaper_component)); - mIsLockscreenLiveWallpaperEnabled = - SystemProperties.getBoolean("persist.wm.debug.lockscreen_live_wallpaper", true); } private JournaledFile makeJournaledFile(int userId) { @@ -127,42 +121,26 @@ class WallpaperDataParser { } /** - * TODO(b/197814683) adapt comment once flag is removed - * * Load the system wallpaper (and the lock wallpaper, if it exists) from disk * @param userId the id of the user for which the wallpaper should be loaded * @param keepDimensionHints if false, parse and set the * {@link DisplayData} width and height for the specified userId - * @param wallpaper the wallpaper object to reuse to do the modifications. - * If null, a new object will be created. - * @param lockWallpaper the lock wallpaper object to reuse to do the modifications. - * If null, a new object will be created. - * @param which The wallpaper(s) to load. Only has effect if - * {@link WallpaperManager#isLockscreenLiveWallpaperEnabled} is true, - * otherwise both wallpaper will always be loaded. + * @param migrateFromOld whether the current wallpaper is pre-N and needs migration + * @param which The wallpaper(s) to load. * @return a {@link WallpaperLoadingResult} object containing the wallpaper data. - * This object will contain the {@code wallpaper} and - * {@code lockWallpaper} provided as parameters, if they are not null. */ public WallpaperLoadingResult loadSettingsLocked(int userId, boolean keepDimensionHints, - WallpaperData wallpaper, WallpaperData lockWallpaper, @SetWallpaperFlags int which) { + boolean migrateFromOld, @SetWallpaperFlags int which) { JournaledFile journal = makeJournaledFile(userId); FileInputStream stream = null; File file = journal.chooseForRead(); - boolean migrateFromOld = wallpaper == null; - - boolean separateLockscreenEngine = mIsLockscreenLiveWallpaperEnabled; - boolean loadSystem = !separateLockscreenEngine || (which & FLAG_SYSTEM) != 0; - boolean loadLock = !separateLockscreenEngine || (which & FLAG_LOCK) != 0; - - // don't reuse the wallpaper objects in the new version - if (separateLockscreenEngine) { - wallpaper = null; - lockWallpaper = null; - } + boolean loadSystem = (which & FLAG_SYSTEM) != 0; + boolean loadLock = (which & FLAG_LOCK) != 0; + WallpaperData wallpaper = null; + WallpaperData lockWallpaper = null; - if (wallpaper == null && loadSystem) { + if (loadSystem) { // Do this once per boot if (migrateFromOld) migrateFromOld(); wallpaper = new WallpaperData(userId, FLAG_SYSTEM); @@ -188,11 +166,8 @@ class WallpaperDataParser { type = parser.next(); if (type == XmlPullParser.START_TAG) { String tag = parser.getName(); - if (("wp".equals(tag) && loadSystem) - || ("kwp".equals(tag) && mIsLockscreenLiveWallpaperEnabled - && loadLock)) { - - if ("kwp".equals(tag) && lockWallpaper == null) { + if (("wp".equals(tag) && loadSystem) || ("kwp".equals(tag) && loadLock)) { + if ("kwp".equals(tag)) { lockWallpaper = new WallpaperData(userId, FLAG_LOCK); } WallpaperData wallpaperToParse = @@ -219,12 +194,6 @@ class WallpaperDataParser { Slog.v(TAG, "mNextWallpaperComponent:" + wallpaper.nextWallpaperComponent); } - } else if ("kwp".equals(tag) && !mIsLockscreenLiveWallpaperEnabled) { - // keyguard-specific wallpaper for this user (legacy code) - if (lockWallpaper == null) { - lockWallpaper = new WallpaperData(userId, FLAG_LOCK); - } - parseWallpaperAttributes(parser, lockWallpaper, false); } } } while (type != XmlPullParser.END_DOCUMENT); diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index c7a3c4349f4c..bdcde66a8102 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -188,8 +188,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } private final Object mLock = new Object(); - /** True to enable a second engine for lock screen wallpaper when different from system wp. */ - private final boolean mIsLockscreenLiveWallpaperEnabled; /** True to support different crops for different display dimensions */ private final boolean mIsMultiCropEnabled; /** Tracks wallpaper being migrated from system+lock to lock when setting static wp. */ @@ -230,7 +228,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub mWallpaperLockFile = new File(mWallpaperDir, WALLPAPER_LOCK_ORIG); } - WallpaperData dataForEvent(boolean sysChanged, boolean lockChanged) { + WallpaperData dataForEvent(boolean lockChanged) { WallpaperData wallpaper = null; synchronized (mLock) { if (lockChanged) { @@ -252,7 +250,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub final File changedFile = new File(mWallpaperDir, path); final boolean sysWallpaperChanged = (mWallpaperFile.equals(changedFile)); final boolean lockWallpaperChanged = (mWallpaperLockFile.equals(changedFile)); - final WallpaperData wallpaper = dataForEvent(sysWallpaperChanged, lockWallpaperChanged); + final WallpaperData wallpaper = dataForEvent(lockWallpaperChanged); final boolean moved = (event == MOVED_TO); final boolean written = (event == CLOSE_WRITE || moved); @@ -378,7 +376,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } saveSettingsLocked(wallpaper.userId); - if ((sysWallpaperChanged || lockWallpaperChanged) && localSync != null) { + if (localSync != null) { localSync.complete(); } } @@ -389,129 +387,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } } - // Handles static wallpaper changes generated by WallpaperObserver events when - // enableSeparateLockScreenEngine() is false. - // TODO(b/266818039) Remove this method - private void updateWallpapersLegacy(int event, String path) { - final boolean moved = (event == MOVED_TO); - final boolean written = (event == CLOSE_WRITE || moved); - final File changedFile = new File(mWallpaperDir, path); - - // System and system+lock changes happen on the system wallpaper input file; - // lock-only changes happen on the dedicated lock wallpaper input file - final boolean sysWallpaperChanged = (mWallpaperFile.equals(changedFile)); - final boolean lockWallpaperChanged = (mWallpaperLockFile.equals(changedFile)); - int notifyColorsWhich = 0; - WallpaperData wallpaper = dataForEvent(sysWallpaperChanged, lockWallpaperChanged); - - if (DEBUG) { - Slog.v(TAG, "Wallpaper file change: evt=" + event - + " path=" + path - + " sys=" + sysWallpaperChanged - + " lock=" + lockWallpaperChanged - + " imagePending=" + wallpaper.imageWallpaperPending - + " mWhich=0x" + Integer.toHexString(wallpaper.mWhich) - + " written=" + written); - } - - if (moved && lockWallpaperChanged) { - // We just migrated sys -> lock to preserve imagery for an impending - // new system-only wallpaper. Tell keyguard about it and make sure it - // has the right SELinux label. - if (DEBUG) { - Slog.i(TAG, "Sys -> lock MOVED_TO"); - } - SELinux.restorecon(changedFile); - notifyLockWallpaperChanged(); - notifyWallpaperColorsChanged(wallpaper, FLAG_LOCK); - return; - } - - synchronized (mLock) { - if (sysWallpaperChanged || lockWallpaperChanged) { - notifyCallbacksLocked(wallpaper); - if (wallpaper.wallpaperComponent == null - || event != CLOSE_WRITE // includes the MOVED_TO case - || wallpaper.imageWallpaperPending) { - if (written) { - // The image source has finished writing the source image, - // so we now produce the crop rect (in the background), and - // only publish the new displayable (sub)image as a result - // of that work. - if (DEBUG) { - Slog.v(TAG, "Wallpaper written; generating crop"); - } - SELinux.restorecon(changedFile); - if (moved) { - // This is a restore, so generate the crop using any just-restored new - // crop guidelines, making sure to preserve our local dimension hints. - // We also make sure to reapply the correct SELinux label. - if (DEBUG) { - Slog.v(TAG, "moved-to, therefore restore; reloading metadata"); - } - loadSettingsLocked(wallpaper.userId, true, FLAG_SYSTEM | FLAG_LOCK); - } - mWallpaperCropper.generateCrop(wallpaper); - if (DEBUG) { - Slog.v(TAG, "Crop done; invoking completion callback"); - } - wallpaper.imageWallpaperPending = false; - if (sysWallpaperChanged) { - IRemoteCallback.Stub callback = new IRemoteCallback.Stub() { - @Override - public void sendResult(Bundle data) throws RemoteException { - Slog.d(TAG, "publish system wallpaper changed!"); - notifyWallpaperChanged(wallpaper); - } - }; - // If this was the system wallpaper, rebind... - bindWallpaperComponentLocked(mImageWallpaper, true, - false, wallpaper, callback); - notifyColorsWhich |= FLAG_SYSTEM; - } - if (lockWallpaperChanged - || (wallpaper.mWhich & FLAG_LOCK) != 0) { - if (DEBUG) { - Slog.i(TAG, "Lock-relevant wallpaper changed"); - } - // either a lock-only wallpaper commit or a system+lock event. - // if it's system-plus-lock we need to wipe the lock bookkeeping; - // we're falling back to displaying the system wallpaper there. - if (!lockWallpaperChanged) { - mLockWallpaperMap.remove(wallpaper.userId); - } - // and in any case, tell keyguard about it - notifyLockWallpaperChanged(); - notifyColorsWhich |= FLAG_LOCK; - } - - saveSettingsLocked(wallpaper.userId); - // Notify the client immediately if only lockscreen wallpaper changed. - if (lockWallpaperChanged && !sysWallpaperChanged) { - notifyWallpaperChanged(wallpaper); - } - } - } - } - } - - // Outside of the lock since it will synchronize itself - if (notifyColorsWhich != 0) { - notifyWallpaperColorsChanged(wallpaper, notifyColorsWhich); - } - } - @Override public void onEvent(int event, String path) { - if (path == null) { - return; - } - - if (mIsLockscreenLiveWallpaperEnabled) { - updateWallpapers(event, path); - } else { - updateWallpapersLegacy(event, path); - } + if (path != null) updateWallpapers(event, path); } } @@ -528,17 +406,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } } - private void notifyLockWallpaperChanged() { - final IWallpaperManagerCallback cb = mKeyguardListener; - if (cb != null) { - try { - cb.onWallpaperChanged(); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to notify keyguard callback about wallpaper changes", e); - } - } - } - void notifyWallpaperColorsChanged(@NonNull WallpaperData wallpaper, int which) { if (DEBUG) { Slog.i(TAG, "Notifying wallpaper colors changed"); @@ -597,14 +464,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub private void notifyColorListeners(@NonNull WallpaperColors wallpaperColors, int which, int userId, int displayId) { - final IWallpaperManagerCallback keyguardListener; final ArrayList<IWallpaperManagerCallback> colorListeners = new ArrayList<>(); synchronized (mLock) { final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners = getWallpaperCallbacks(userId, displayId); final RemoteCallbackList<IWallpaperManagerCallback> userAllColorListeners = getWallpaperCallbacks(UserHandle.USER_ALL, displayId); - keyguardListener = mKeyguardListener; if (currentUserColorListeners != null) { final int count = currentUserColorListeners.beginBroadcast(); @@ -633,15 +498,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub Slog.w(TAG, "onWallpaperColorsChanged() threw an exception", e); } } - - // Only shows Keyguard on default display - if (keyguardListener != null && displayId == DEFAULT_DISPLAY) { - try { - keyguardListener.onWallpaperColorsChanged(wallpaperColors, which, userId); - } catch (RemoteException e) { - Slog.w(TAG, "keyguardListener.onWallpaperColorsChanged threw an exception", e); - } - } } /** @@ -762,8 +618,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub private final MyPackageMonitor mMonitor; private final AppOpsManager mAppOpsManager; - // TODO("b/264637309") probably move this in WallpaperDisplayUtils, - // after logic is changed for the lockscreen lwp project private final DisplayManager.DisplayListener mDisplayListener = new DisplayManager.DisplayListener() { @@ -814,8 +668,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub protected WallpaperData mLastWallpaper; // The currently bound lock screen only wallpaper, or null if none protected WallpaperData mLastLockWallpaper; - private IWallpaperManagerCallback mKeyguardListener; - private boolean mWaitingForUnlock; /** * Flag set to true after reboot if the home wallpaper is waiting for the device to be unlocked. @@ -1017,8 +869,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (!mWallpaper.wallpaperUpdating && mWallpaper.userId == mCurrentUserId) { Slog.w(TAG, "Wallpaper reconnect timed out for " + mWallpaper.wallpaperComponent + ", reverting to built-in wallpaper!"); - int which = mIsLockscreenLiveWallpaperEnabled ? mWallpaper.mWhich : FLAG_SYSTEM; - clearWallpaperLocked(which, mWallpaper.userId, null); + int which = mWallpaper.mWhich; + clearWallpaperLocked(which, mWallpaper.userId, false, null); } } }; @@ -1198,7 +1050,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } else { // Timeout Slog.w(TAG, "Reverting to built-in wallpaper!"); - clearWallpaperLocked(mWallpaper.mWhich, mWallpaper.userId, null); + clearWallpaperLocked(mWallpaper.mWhich, mWallpaper.userId, false, null); final String flattened = wpService.flattenToString(); EventLog.writeEvent(EventLogTags.WP_WALLPAPER_CRASHED, flattened.substring(0, Math.min(flattened.length(), @@ -1238,7 +1090,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (mLmkLimitRebindRetries <= 0) { Slog.w(TAG, "Reverting to built-in wallpaper due to lmk!"); clearWallpaperLocked( - mWallpaper.mWhich, mWallpaper.userId, null); + mWallpaper.mWhich, mWallpaper.userId, false, null); mLmkLimitRebindRetries = LMK_RECONNECT_REBIND_RETRIES; return; } @@ -1257,7 +1109,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub && mWallpaper.lastDiedTime + MIN_WALLPAPER_CRASH_TIME > SystemClock.uptimeMillis()) { Slog.w(TAG, "Reverting to built-in wallpaper!"); - clearWallpaperLocked(FLAG_SYSTEM, mWallpaper.userId, null); + clearWallpaperLocked(FLAG_SYSTEM, mWallpaper.userId, false, null); } else { mWallpaper.lastDiedTime = SystemClock.uptimeMillis(); tryToRebind(); @@ -1294,19 +1146,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (mImageWallpaper.equals(mWallpaper.wallpaperComponent)) { return; } - - // Live wallpapers always are system wallpapers unless lock screen live wp is - // enabled. - which = mIsLockscreenLiveWallpaperEnabled ? mWallpaper.mWhich : FLAG_SYSTEM; + which = mWallpaper.mWhich; mWallpaper.primaryColors = primaryColors; - - // It's also the lock screen wallpaper when we don't have a bitmap in there. - if (displayId == DEFAULT_DISPLAY) { - final WallpaperData lockedWallpaper = mLockWallpaperMap.get(mWallpaper.userId); - if (lockedWallpaper == null) { - which |= FLAG_LOCK; - } - } } if (which != 0) { notifyWallpaperColorsChangedOnDisplay(mWallpaper, which, displayId); @@ -1492,9 +1333,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub wallpaper, null)) { Slog.w(TAG, "Wallpaper " + wpService + " no longer available; reverting to default"); - int which = mIsLockscreenLiveWallpaperEnabled - ? wallpaper.mWhich : FLAG_SYSTEM; - clearWallpaperLocked(which, wallpaper.userId, null); + clearWallpaperLocked(wallpaper.mWhich, wallpaper.userId, false, null); } } } @@ -1568,7 +1407,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub boolean doPackagesChangedLocked(boolean doit, WallpaperData wallpaper) { boolean changed = false; - int which = mIsLockscreenLiveWallpaperEnabled ? wallpaper.mWhich : FLAG_SYSTEM; if (wallpaper.wallpaperComponent != null) { int change = isPackageDisappearing(wallpaper.wallpaperComponent .getPackageName()); @@ -1578,7 +1416,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (doit) { Slog.w(TAG, "Wallpaper uninstalled, removing: " + wallpaper.wallpaperComponent); - clearWallpaperLocked(which, wallpaper.userId, null); + clearWallpaperLocked(wallpaper.mWhich, wallpaper.userId, false, null); } } } @@ -1599,7 +1437,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } catch (NameNotFoundException e) { Slog.w(TAG, "Wallpaper component gone, removing: " + wallpaper.wallpaperComponent); - clearWallpaperLocked(which, wallpaper.userId, null); + clearWallpaperLocked(wallpaper.mWhich, wallpaper.userId, false, null); } } if (wallpaper.nextWallpaperComponent != null @@ -1686,9 +1524,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub mColorsChangedListeners = new SparseArray<>(); mWallpaperDataParser = new WallpaperDataParser(mContext, mWallpaperDisplayHelper, mWallpaperCropper); - - mIsLockscreenLiveWallpaperEnabled = - SystemProperties.getBoolean("persist.wm.debug.lockscreen_live_wallpaper", true); mIsMultiCropEnabled = SystemProperties.getBoolean("persist.wm.debug.wallpaper_multi_crop", false); LocalServices.addService(WallpaperManagerInternal.class, new LocalService()); @@ -1755,8 +1590,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (DEBUG) { Slog.i(TAG, "Unable to regenerate crop; resetting"); } - int which = isLockscreenLiveWallpaperEnabled() ? wallpaper.mWhich : FLAG_SYSTEM; - clearWallpaperLocked(which, UserHandle.USER_SYSTEM, null); + clearWallpaperLocked(wallpaper.mWhich, UserHandle.USER_SYSTEM, false, null); } } else { if (DEBUG) { @@ -1883,29 +1717,19 @@ public class WallpaperManagerService extends IWallpaperManager.Stub public void onUnlockUser(final int userId) { synchronized (mLock) { if (mCurrentUserId == userId) { - if (mIsLockscreenLiveWallpaperEnabled) { - if (mHomeWallpaperWaitingForUnlock) { - final WallpaperData systemWallpaper = - getWallpaperSafeLocked(userId, FLAG_SYSTEM); - switchWallpaper(systemWallpaper, null); - // TODO(b/278261563): call notifyCallbacksLocked inside switchWallpaper - notifyCallbacksLocked(systemWallpaper); - } - if (mLockWallpaperWaitingForUnlock) { - final WallpaperData lockWallpaper = - getWallpaperSafeLocked(userId, FLAG_LOCK); - switchWallpaper(lockWallpaper, null); - notifyCallbacksLocked(lockWallpaper); - } - } - - if (mWaitingForUnlock && !mIsLockscreenLiveWallpaperEnabled) { - // the desired wallpaper is not direct-boot aware, load it now + if (mHomeWallpaperWaitingForUnlock) { final WallpaperData systemWallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM); switchWallpaper(systemWallpaper, null); + // TODO(b/278261563): call notifyCallbacksLocked inside switchWallpaper notifyCallbacksLocked(systemWallpaper); } + if (mLockWallpaperWaitingForUnlock) { + final WallpaperData lockWallpaper = + getWallpaperSafeLocked(userId, FLAG_LOCK); + switchWallpaper(lockWallpaper, null); + notifyCallbacksLocked(lockWallpaper); + } // Make sure that the SELinux labeling of all the relevant files is correct. // This corrects for mislabeling bugs that might have arisen from move-to @@ -1954,21 +1778,15 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } mCurrentUserId = userId; systemWallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM); - - if (mIsLockscreenLiveWallpaperEnabled) { - lockWallpaper = systemWallpaper.mWhich == (FLAG_LOCK | FLAG_SYSTEM) - ? systemWallpaper : getWallpaperSafeLocked(userId, FLAG_LOCK); - } else { - final WallpaperData tmpLockWallpaper = mLockWallpaperMap.get(userId); - lockWallpaper = tmpLockWallpaper == null ? systemWallpaper : tmpLockWallpaper; - } + lockWallpaper = systemWallpaper.mWhich == (FLAG_LOCK | FLAG_SYSTEM) + ? systemWallpaper : getWallpaperSafeLocked(userId, FLAG_LOCK); // Not started watching yet, in case wallpaper data was loaded for other reasons. if (systemWallpaper.wallpaperObserver == null) { systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper); systemWallpaper.wallpaperObserver.startWatching(); } - if (mIsLockscreenLiveWallpaperEnabled && lockWallpaper != systemWallpaper) { + if (lockWallpaper != systemWallpaper) { switchWallpaper(lockWallpaper, null); } switchWallpaper(systemWallpaper, reply); @@ -1988,11 +1806,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) { synchronized (mLock) { - mWaitingForUnlock = false; - if (mIsLockscreenLiveWallpaperEnabled) { - if ((wallpaper.mWhich & FLAG_SYSTEM) != 0) mHomeWallpaperWaitingForUnlock = false; - if ((wallpaper.mWhich & FLAG_LOCK) != 0) mLockWallpaperWaitingForUnlock = false; - } + if ((wallpaper.mWhich & FLAG_SYSTEM) != 0) mHomeWallpaperWaitingForUnlock = false; + if ((wallpaper.mWhich & FLAG_LOCK) != 0) mLockWallpaperWaitingForUnlock = false; final ComponentName cname = wallpaper.wallpaperComponent != null ? wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent; @@ -2006,37 +1821,19 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } catch (RemoteException e) { Slog.w(TAG, "Failure starting previous wallpaper; clearing", e); } - - if (mIsLockscreenLiveWallpaperEnabled) { - onSwitchWallpaperFailLocked(wallpaper, reply, si); - return; - } - - if (si == null) { - clearWallpaperLocked(FLAG_SYSTEM, wallpaper.userId, reply); - } else { - Slog.w(TAG, "Wallpaper isn't direct boot aware; using fallback until unlocked"); - // We might end up persisting the current wallpaper data - // while locked, so pretend like the component was actually - // bound into place - wallpaper.wallpaperComponent = wallpaper.nextWallpaperComponent; - final WallpaperData fallback = new WallpaperData(wallpaper.userId, FLAG_LOCK); - bindWallpaperComponentLocked(mImageWallpaper, true, false, fallback, reply); - mWaitingForUnlock = true; - } + onSwitchWallpaperFailLocked(wallpaper, reply, si); } } } /** * Fallback method if a wallpaper fails to load on boot or after a user switch. - * Only called if mIsLockscreenLiveWallpaperEnabled is true. */ private void onSwitchWallpaperFailLocked( WallpaperData wallpaper, IRemoteCallback reply, ServiceInfo serviceInfo) { if (serviceInfo == null) { - clearWallpaperLocked(wallpaper.mWhich, wallpaper.userId, reply); + clearWallpaperLocked(wallpaper.mWhich, wallpaper.userId, false, reply); return; } Slog.w(TAG, "Wallpaper isn't direct boot aware; using fallback until unlocked"); @@ -2067,12 +1864,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub WallpaperData data = null; synchronized (mLock) { - if (mIsLockscreenLiveWallpaperEnabled) { - boolean fromForeground = isFromForegroundApp(callingPackage); - clearWallpaperLocked(which, userId, fromForeground, null); - } else { - clearWallpaperLocked(which, userId, null); - } + boolean fromForeground = isFromForegroundApp(callingPackage); + clearWallpaperLocked(which, userId, fromForeground, null); if (which == FLAG_LOCK) { data = mLockWallpaperMap.get(userId); @@ -2153,91 +1946,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } } - // TODO(b/266818039) remove - private void clearWallpaperLocked(int which, int userId, IRemoteCallback reply) { - - if (mIsLockscreenLiveWallpaperEnabled) { - clearWallpaperLocked(which, userId, false, reply); - return; - } - - if (which != FLAG_SYSTEM && which != FLAG_LOCK) { - throw new IllegalArgumentException("Must specify exactly one kind of wallpaper to clear"); - } - - WallpaperData wallpaper = null; - if (which == FLAG_LOCK) { - wallpaper = mLockWallpaperMap.get(userId); - if (wallpaper == null) { - // It's already gone; we're done. - if (DEBUG) { - Slog.i(TAG, "Lock wallpaper already cleared"); - } - return; - } - } else { - wallpaper = mWallpaperMap.get(userId); - if (wallpaper == null) { - // Might need to bring it in the first time to establish our rewrite - loadSettingsLocked(userId, false, FLAG_SYSTEM); - wallpaper = mWallpaperMap.get(userId); - } - } - if (wallpaper == null) { - return; - } - - final long ident = Binder.clearCallingIdentity(); - try { - if (clearWallpaperBitmaps(wallpaper)) { - if (which == FLAG_LOCK) { - mLockWallpaperMap.remove(userId); - final IWallpaperManagerCallback cb = mKeyguardListener; - if (cb != null) { - if (DEBUG) { - Slog.i(TAG, "Notifying keyguard of lock wallpaper clear"); - } - try { - cb.onWallpaperChanged(); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to notify keyguard after wallpaper clear", e); - } - } - saveSettingsLocked(userId); - return; - } - } - - RuntimeException e = null; - try { - wallpaper.primaryColors = null; - wallpaper.imageWallpaperPending = false; - if (userId != mCurrentUserId) return; - if (bindWallpaperComponentLocked(null, true, false, wallpaper, reply)) { - return; - } - } catch (IllegalArgumentException e1) { - e = e1; - } - - // This can happen if the default wallpaper component doesn't - // exist. This should be a system configuration problem, but - // let's not let it crash the system and just live with no - // wallpaper. - Slog.e(TAG, "Default wallpaper component not found!", e); - clearWallpaperComponentLocked(wallpaper); - if (reply != null) { - try { - reply.sendResult(null); - } catch (RemoteException e1) { - Slog.w(TAG, "Failed to notify callback after wallpaper clear", e1); - } - } - } finally { - Binder.restoreCallingIdentity(ident); - } - } - private boolean hasCrossUserPermission() { final int interactPermission = mContext.checkCallingPermission(INTERACT_ACROSS_USERS_FULL); @@ -2615,45 +2323,20 @@ public class WallpaperManagerService extends IWallpaperManager.Stub * @param animationDuration Duration of the animation, or 0 when immediate. */ public void setInAmbientMode(boolean inAmbientMode, long animationDuration) { - if (mIsLockscreenLiveWallpaperEnabled) { - List<IWallpaperEngine> engines = new ArrayList<>(); - synchronized (mLock) { - mInAmbientMode = inAmbientMode; - for (WallpaperData data : getActiveWallpapers()) { - if (data.connection.mInfo == null - || data.connection.mInfo.supportsAmbientMode()) { - // TODO(multi-display) Extends this method with specific display. - IWallpaperEngine engine = data.connection - .getDisplayConnectorOrCreate(DEFAULT_DISPLAY).mEngine; - if (engine != null) engines.add(engine); - } - } - } - for (IWallpaperEngine engine : engines) { - try { - engine.setInAmbientMode(inAmbientMode, animationDuration); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to set ambient mode", e); - } - } - return; - } - - final IWallpaperEngine engine; + List<IWallpaperEngine> engines = new ArrayList<>(); synchronized (mLock) { mInAmbientMode = inAmbientMode; - final WallpaperData data = mWallpaperMap.get(mCurrentUserId); - // The wallpaper info is null for image wallpaper, also use the engine in this case. - if (data != null && data.connection != null && (data.connection.mInfo == null - || data.connection.mInfo.supportsAmbientMode())) { - // TODO(multi-display) Extends this method with specific display. - engine = data.connection.getDisplayConnectorOrCreate(DEFAULT_DISPLAY).mEngine; - } else { - engine = null; + for (WallpaperData data : getActiveWallpapers()) { + if (data.connection.mInfo == null + || data.connection.mInfo.supportsAmbientMode()) { + // TODO(multi-display) Extends this method with specific display. + IWallpaperEngine engine = data.connection + .getDisplayConnectorOrCreate(DEFAULT_DISPLAY).mEngine; + if (engine != null) engines.add(engine); + } } } - - if (engine != null) { + for (IWallpaperEngine engine : engines) { try { engine.setInAmbientMode(inAmbientMode, animationDuration); } catch (RemoteException e) { @@ -2664,11 +2347,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub private void pauseOrResumeRenderingImmediately(boolean pause) { synchronized (mLock) { - final WallpaperData[] wallpapers = mIsLockscreenLiveWallpaperEnabled - ? getActiveWallpapers() : new WallpaperData[] { - mWallpaperMap.get(mCurrentUserId) }; - for (WallpaperData data : wallpapers) { - if (data.connection == null || data.connection.mInfo == null) { + for (WallpaperData data : getActiveWallpapers()) { + if (data.connection.mInfo == null) { continue; } if (pause || LocalServices.getService(ActivityTaskManagerInternal.class) @@ -2697,34 +2377,17 @@ public class WallpaperManagerService extends IWallpaperManager.Stub public void notifyWakingUp(int x, int y, @NonNull Bundle extras) { checkCallerIsSystemOrSystemUi(); synchronized (mLock) { - if (mIsLockscreenLiveWallpaperEnabled) { - for (WallpaperData data : getActiveWallpapers()) { - data.connection.forEachDisplayConnector(displayConnector -> { - if (displayConnector.mEngine != null) { - try { - displayConnector.mEngine.dispatchWallpaperCommand( - WallpaperManager.COMMAND_WAKING_UP, x, y, -1, extras); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to dispatch COMMAND_WAKING_UP", e); - } + for (WallpaperData data : getActiveWallpapers()) { + data.connection.forEachDisplayConnector(displayConnector -> { + if (displayConnector.mEngine != null) { + try { + displayConnector.mEngine.dispatchWallpaperCommand( + WallpaperManager.COMMAND_WAKING_UP, x, y, -1, extras); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to dispatch COMMAND_WAKING_UP", e); } - }); - } - return; - } - final WallpaperData data = mWallpaperMap.get(mCurrentUserId); - if (data != null && data.connection != null) { - data.connection.forEachDisplayConnector( - displayConnector -> { - if (displayConnector.mEngine != null) { - try { - displayConnector.mEngine.dispatchWallpaperCommand( - WallpaperManager.COMMAND_WAKING_UP, x, y, -1, extras); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to dispatch COMMAND_WAKING_UP", e); - } - } - }); + } + }); } } } @@ -2735,36 +2398,18 @@ public class WallpaperManagerService extends IWallpaperManager.Stub public void notifyGoingToSleep(int x, int y, @NonNull Bundle extras) { checkCallerIsSystemOrSystemUi(); synchronized (mLock) { - if (mIsLockscreenLiveWallpaperEnabled) { - for (WallpaperData data : getActiveWallpapers()) { - data.connection.forEachDisplayConnector(displayConnector -> { - if (displayConnector.mEngine != null) { - try { - displayConnector.mEngine.dispatchWallpaperCommand( - WallpaperManager.COMMAND_GOING_TO_SLEEP, x, y, -1, - extras); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to dispatch COMMAND_GOING_TO_SLEEP", e); - } + for (WallpaperData data : getActiveWallpapers()) { + data.connection.forEachDisplayConnector(displayConnector -> { + if (displayConnector.mEngine != null) { + try { + displayConnector.mEngine.dispatchWallpaperCommand( + WallpaperManager.COMMAND_GOING_TO_SLEEP, x, y, -1, + extras); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to dispatch COMMAND_GOING_TO_SLEEP", e); } - }); - } - return; - } - final WallpaperData data = mWallpaperMap.get(mCurrentUserId); - if (data != null && data.connection != null) { - data.connection.forEachDisplayConnector( - displayConnector -> { - if (displayConnector.mEngine != null) { - try { - displayConnector.mEngine.dispatchWallpaperCommand( - WallpaperManager.COMMAND_GOING_TO_SLEEP, x, y, -1, - extras); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to dispatch COMMAND_GOING_TO_SLEEP", e); - } - } - }); + } + }); } } } @@ -2774,35 +2419,18 @@ public class WallpaperManagerService extends IWallpaperManager.Stub */ private void notifyScreenTurnedOn(int displayId) { synchronized (mLock) { - if (mIsLockscreenLiveWallpaperEnabled) { - for (WallpaperData data : getActiveWallpapers()) { - if (data.connection.containsDisplay(displayId)) { - final IWallpaperEngine engine = data.connection - .getDisplayConnectorOrCreate(displayId).mEngine; - if (engine != null) { - try { - engine.onScreenTurnedOn(); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to notify that the screen turned on", e); - } + for (WallpaperData data : getActiveWallpapers()) { + if (data.connection.containsDisplay(displayId)) { + final IWallpaperEngine engine = data.connection + .getDisplayConnectorOrCreate(displayId).mEngine; + if (engine != null) { + try { + engine.onScreenTurnedOn(); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to notify that the screen turned on", e); } } } - return; - } - final WallpaperData data = mWallpaperMap.get(mCurrentUserId); - if (data != null - && data.connection != null - && data.connection.containsDisplay(displayId)) { - final IWallpaperEngine engine = data.connection - .getDisplayConnectorOrCreate(displayId).mEngine; - if (engine != null) { - try { - engine.onScreenTurnedOn(); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to notify that the screen turned on", e); - } - } } } } @@ -2812,35 +2440,18 @@ public class WallpaperManagerService extends IWallpaperManager.Stub */ private void notifyScreenTurningOn(int displayId) { synchronized (mLock) { - if (mIsLockscreenLiveWallpaperEnabled) { - for (WallpaperData data : getActiveWallpapers()) { - if (data.connection.containsDisplay(displayId)) { - final IWallpaperEngine engine = data.connection - .getDisplayConnectorOrCreate(displayId).mEngine; - if (engine != null) { - try { - engine.onScreenTurningOn(); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to notify that the screen is turning on", e); - } + for (WallpaperData data : getActiveWallpapers()) { + if (data.connection.containsDisplay(displayId)) { + final IWallpaperEngine engine = data.connection + .getDisplayConnectorOrCreate(displayId).mEngine; + if (engine != null) { + try { + engine.onScreenTurningOn(); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to notify that the screen is turning on", e); } } } - return; - } - final WallpaperData data = mWallpaperMap.get(mCurrentUserId); - if (data != null - && data.connection != null - && data.connection.containsDisplay(displayId)) { - final IWallpaperEngine engine = data.connection - .getDisplayConnectorOrCreate(displayId).mEngine; - if (engine != null) { - try { - engine.onScreenTurningOn(); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to notify that the screen is turning on", e); - } - } } } } @@ -2850,25 +2461,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub */ private void notifyKeyguardGoingAway() { synchronized (mLock) { - if (mIsLockscreenLiveWallpaperEnabled) { - for (WallpaperData data : getActiveWallpapers()) { - data.connection.forEachDisplayConnector(displayConnector -> { - if (displayConnector.mEngine != null) { - try { - displayConnector.mEngine.dispatchWallpaperCommand( - WallpaperManager.COMMAND_KEYGUARD_GOING_AWAY, - -1, -1, -1, new Bundle()); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to notify that the keyguard is going away", e); - } - } - }); - } - return; - } - - final WallpaperData data = mWallpaperMap.get(mCurrentUserId); - if (data != null && data.connection != null) { + for (WallpaperData data : getActiveWallpapers()) { data.connection.forEachDisplayConnector(displayConnector -> { if (displayConnector.mEngine != null) { try { @@ -2884,15 +2477,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } } - @Override - public boolean setLockWallpaperCallback(IWallpaperManagerCallback cb) { - checkPermission(android.Manifest.permission.INTERNAL_SYSTEM_WINDOW); - synchronized (mLock) { - mKeyguardListener = cb; - } - return true; - } - private WallpaperData[] getActiveWallpapers() { WallpaperData systemWallpaper = mWallpaperMap.get(mCurrentUserId); WallpaperData lockWallpaper = mLockWallpaperMap.get(mCurrentUserId); @@ -2904,12 +2488,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub : new WallpaperData[0]; } - // TODO(b/266818039) remove private WallpaperData[] getWallpapers() { WallpaperData systemWallpaper = mWallpaperMap.get(mCurrentUserId); WallpaperData lockWallpaper = mLockWallpaperMap.get(mCurrentUserId); boolean systemValid = systemWallpaper != null; - boolean lockValid = lockWallpaper != null && isLockscreenLiveWallpaperEnabled(); + boolean lockValid = lockWallpaper != null; return systemValid && lockValid ? new WallpaperData[]{systemWallpaper, lockWallpaper} : systemValid ? new WallpaperData[]{systemWallpaper} : lockValid ? new WallpaperData[]{lockWallpaper} @@ -3043,54 +2626,29 @@ public class WallpaperManagerService extends IWallpaperManager.Stub lockWallpaper.mWallpaperDimAmount = maxDimAmount; } - if (mIsLockscreenLiveWallpaperEnabled) { - boolean changed = false; - for (WallpaperData wp : getActiveWallpapers()) { - if (wp != null && wp.connection != null) { - wp.connection.forEachDisplayConnector(connector -> { - if (connector.mEngine != null) { - try { - connector.mEngine.applyDimming(maxDimAmount); - } catch (RemoteException e) { - Slog.w(TAG, "Can't apply dimming on wallpaper display " - + "connector", e); - } - } - }); - // Need to extract colors again to re-calculate dark hints after - // applying dimming. - wp.mIsColorExtractedFromDim = true; - pendingColorExtraction.add(wp); - changed = true; - } - } - if (changed) { - saveSettingsLocked(wallpaper.userId); - } - } else { - if (wallpaper.connection != null) { - wallpaper.connection.forEachDisplayConnector(connector -> { + boolean changed = false; + for (WallpaperData wp : getActiveWallpapers()) { + if (wp != null && wp.connection != null) { + wp.connection.forEachDisplayConnector(connector -> { if (connector.mEngine != null) { try { connector.mEngine.applyDimming(maxDimAmount); } catch (RemoteException e) { - Slog.w(TAG, - "Can't apply dimming on wallpaper display connector", - e); + Slog.w(TAG, "Can't apply dimming on wallpaper display " + + "connector", e); } } }); // Need to extract colors again to re-calculate dark hints after // applying dimming. - wallpaper.mIsColorExtractedFromDim = true; - notifyWallpaperColorsChanged(wallpaper, FLAG_SYSTEM); - if (lockWallpaper != null) { - lockWallpaper.mIsColorExtractedFromDim = true; - notifyWallpaperColorsChanged(lockWallpaper, FLAG_LOCK); - } - saveSettingsLocked(wallpaper.userId); + wp.mIsColorExtractedFromDim = true; + pendingColorExtraction.add(wp); + changed = true; } } + if (changed) { + saveSettingsLocked(wallpaper.userId); + } } for (WallpaperData wp: pendingColorExtraction) { notifyWallpaperColorsChanged(wp, wp.mWhich); @@ -3246,10 +2804,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (which == FLAG_SYSTEM && systemIsStatic && systemIsBoth) { Slog.i(TAG, "Migrating current wallpaper to be lock-only before" + " updating system wallpaper"); - if (!migrateStaticSystemToLockWallpaperLocked(userId) - && !isLockscreenLiveWallpaperEnabled()) { - which |= FLAG_LOCK; - } + migrateStaticSystemToLockWallpaperLocked(userId); } wallpaper = getWallpaperSafeLocked(userId, which); @@ -3277,13 +2832,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } } - private boolean migrateStaticSystemToLockWallpaperLocked(int userId) { + private void migrateStaticSystemToLockWallpaperLocked(int userId) { WallpaperData sysWP = mWallpaperMap.get(userId); if (sysWP == null) { if (DEBUG) { Slog.i(TAG, "No system wallpaper? Not tracking for lock-only"); } - return true; + return; } // We know a-priori that there is no lock-only wallpaper currently @@ -3297,25 +2852,21 @@ public class WallpaperManagerService extends IWallpaperManager.Stub // Migrate the bitmap files outright; no need to copy try { - if (!mIsLockscreenLiveWallpaperEnabled || sysWP.getWallpaperFile().exists()) { + if (sysWP.getWallpaperFile().exists()) { Os.rename(sysWP.getWallpaperFile().getAbsolutePath(), lockWP.getWallpaperFile().getAbsolutePath()); } - if (!mIsLockscreenLiveWallpaperEnabled || sysWP.getCropFile().exists()) { + if (sysWP.getCropFile().exists()) { Os.rename(sysWP.getCropFile().getAbsolutePath(), lockWP.getCropFile().getAbsolutePath()); } mLockWallpaperMap.put(userId, lockWP); - if (mIsLockscreenLiveWallpaperEnabled) { - SELinux.restorecon(lockWP.getWallpaperFile()); - mLastLockWallpaper = lockWP; - } - return true; + SELinux.restorecon(lockWP.getWallpaperFile()); + mLastLockWallpaper = lockWP; } catch (ErrnoException e) { // can happen when migrating default wallpaper (which is not stored in wallpaperFile) Slog.w(TAG, "Couldn't migrate system wallpaper: " + e.getMessage()); clearWallpaperBitmaps(lockWP); - return false; } } @@ -3372,13 +2923,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub @VisibleForTesting boolean setWallpaperComponent(ComponentName name, String callingPackage, @SetWallpaperFlags int which, int userId) { - if (mIsLockscreenLiveWallpaperEnabled) { - boolean fromForeground = isFromForegroundApp(callingPackage); - return setWallpaperComponentInternal(name, which, userId, false, fromForeground, null); - } else { - setWallpaperComponentInternalLegacy(name, callingPackage, which, userId); - return true; - } + boolean fromForeground = isFromForegroundApp(callingPackage); + return setWallpaperComponentInternal(name, which, userId, false, fromForeground, null); } private boolean setWallpaperComponentInternal(ComponentName name, @SetWallpaperFlags int which, @@ -3491,87 +3037,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub return bindSuccess; } - // TODO(b/266818039) Remove this method - private void setWallpaperComponentInternalLegacy(ComponentName name, String callingPackage, - @SetWallpaperFlags int which, int userId) { - userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId, - false /* all */, true /* full */, "changing live wallpaper", null /* pkg */); - checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT); - - int legacyWhich = FLAG_SYSTEM; - boolean shouldNotifyColors = false; - WallpaperData wallpaper; - - synchronized (mLock) { - Slog.v(TAG, "setWallpaperComponentLegacy name=" + name + ", which=" + which); - wallpaper = mWallpaperMap.get(userId); - if (wallpaper == null) { - throw new IllegalStateException("Wallpaper not yet initialized for user " + userId); - } - final long ident = Binder.clearCallingIdentity(); - - // Live wallpapers can't be specified for keyguard. If we're using a static - // system+lock image currently, migrate the system wallpaper to be a lock-only - // image as part of making a different live component active as the system - // wallpaper. - if (mImageWallpaper.equals(wallpaper.wallpaperComponent)) { - if (mLockWallpaperMap.get(userId) == null) { - // We're using the static imagery and there is no lock-specific image in place, - // therefore it's a shared system+lock image that we need to migrate. - Slog.i(TAG, "Migrating current wallpaper to be lock-only before" - + "updating system wallpaper"); - if (!migrateStaticSystemToLockWallpaperLocked(userId)) { - which |= FLAG_LOCK; - } - } - } - - // New live wallpaper is also a lock wallpaper if nothing is set - if (mLockWallpaperMap.get(userId) == null) { - legacyWhich |= FLAG_LOCK; - } - - try { - wallpaper.imageWallpaperPending = false; - wallpaper.mWhich = which; - wallpaper.fromForegroundApp = isFromForegroundApp(callingPackage); - boolean same = changingToSame(name, wallpaper); - - // force rebind when reapplying a system-only wallpaper to system+lock - boolean forceRebind = same && mLockWallpaperMap.get(userId) != null - && which == (FLAG_SYSTEM | FLAG_LOCK); - if (bindWallpaperComponentLocked(name, forceRebind, true, wallpaper, null)) { - if (!same) { - wallpaper.primaryColors = null; - } else { - if (wallpaper.connection != null) { - wallpaper.connection.forEachDisplayConnector(displayConnector -> { - try { - if (displayConnector.mEngine != null) { - displayConnector.mEngine.dispatchWallpaperCommand( - COMMAND_REAPPLY, 0, 0, 0, null); - } - } catch (RemoteException e) { - Slog.w(TAG, "Error sending apply message to wallpaper", e); - } - }); - } - } - wallpaper.wallpaperId = makeWallpaperIdLocked(); - notifyCallbacksLocked(wallpaper); - shouldNotifyColors = true; - } - } finally { - Binder.restoreCallingIdentity(ident); - } - } - - if (shouldNotifyColors) { - notifyWallpaperColorsChanged(wallpaper, legacyWhich); - notifyWallpaperColorsChanged(mFallbackWallpaper, FLAG_SYSTEM); - } - } - /** * Determines if the given component name is the default component. Note: a null name can be * used to represent the default component. @@ -3743,21 +3208,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub Slog.w(TAG, msg); return false; } - if (mIsLockscreenLiveWallpaperEnabled) { - maybeDetachLastWallpapers(wallpaper); - } else if (wallpaper.userId == mCurrentUserId && mLastWallpaper != null - && !wallpaper.equals(mFallbackWallpaper)) { - detachWallpaperLocked(mLastWallpaper); - } + maybeDetachLastWallpapers(wallpaper); wallpaper.wallpaperComponent = componentName; wallpaper.connection = newConn; newConn.mReply = reply; - if (mIsLockscreenLiveWallpaperEnabled) { - updateCurrentWallpapers(wallpaper); - } else if (wallpaper.userId == mCurrentUserId && !wallpaper.equals( - mFallbackWallpaper)) { - mLastWallpaper = wallpaper; - } + updateCurrentWallpapers(wallpaper); updateFallbackConnection(); } catch (RemoteException e) { String msg = "Remote exception for " + componentName + "\n" + e; @@ -3773,7 +3228,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } // Updates tracking of the currently bound wallpapers. - // Assumes isLockscreenLiveWallpaperEnabled is true. private void updateCurrentWallpapers(WallpaperData newWallpaper) { if (newWallpaper.userId != mCurrentUserId || newWallpaper.equals(mFallbackWallpaper)) { return; @@ -3787,8 +3241,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } } - // Detaches previously bound wallpapers if no longer in use. Assumes - // isLockscreenLiveWallpaperEnabled is true. + // Detaches previously bound wallpapers if no longer in use. private void maybeDetachLastWallpapers(WallpaperData newWallpaper) { if (newWallpaper.userId != mCurrentUserId || newWallpaper.equals(mFallbackWallpaper)) { return; @@ -3981,11 +3434,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } @Override - public boolean isLockscreenLiveWallpaperEnabled() { - return mIsLockscreenLiveWallpaperEnabled; - } - - @Override public boolean isMultiCropEnabled() { return mIsMultiCropEnabled; } @@ -4074,13 +3522,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub private void loadSettingsLocked(int userId, boolean keepDimensionHints, int which) { initializeFallbackWallpaper(); - WallpaperData wallpaperData = mWallpaperMap.get(userId); - WallpaperData lockWallpaperData = mLockWallpaperMap.get(userId); + boolean restoreFromOld = !mWallpaperMap.contains(userId); WallpaperDataParser.WallpaperLoadingResult result = mWallpaperDataParser.loadSettingsLocked( - userId, keepDimensionHints, wallpaperData, lockWallpaperData, which); + userId, keepDimensionHints, restoreFromOld, which); - boolean updateSystem = !mIsLockscreenLiveWallpaperEnabled || (which & FLAG_SYSTEM) != 0; - boolean updateLock = !mIsLockscreenLiveWallpaperEnabled || (which & FLAG_LOCK) != 0; + boolean updateSystem = (which & FLAG_SYSTEM) != 0; + boolean updateLock = (which & FLAG_LOCK) != 0; if (updateSystem) mWallpaperMap.put(userId, result.getSystemWallpaperData()); if (updateLock) { @@ -4243,8 +3690,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (mFallbackWallpaper != null) { dumpWallpaper(mFallbackWallpaper, pw); } - pw.print("mIsLockscreenLiveWallpaperEnabled="); - pw.println(mIsLockscreenLiveWallpaperEnabled); } } } diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index 94e66ffd8373..33ef3c5629e3 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -45,7 +45,6 @@ import android.os.Debug; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; -import android.os.SystemProperties; import android.util.ArraySet; import android.util.MathUtils; import android.util.Slog; @@ -117,8 +116,6 @@ class WallpaperController { private boolean mShouldOffsetWallpaperCenter; - final boolean mIsLockscreenLiveWallpaperEnabled; - private final Consumer<WindowState> mFindWallpapers = w -> { if (w.mAttrs.type == TYPE_WALLPAPER) { WallpaperWindowToken token = w.mToken.asWallpaperToken(); @@ -236,9 +233,6 @@ class WallpaperController { WallpaperController(WindowManagerService service, DisplayContent displayContent) { mService = service; mDisplayContent = displayContent; - mIsLockscreenLiveWallpaperEnabled = - SystemProperties.getBoolean("persist.wm.debug.lockscreen_live_wallpaper", true); - Resources resources = service.mContext.getResources(); mMinWallpaperScale = resources.getFloat(com.android.internal.R.dimen.config_wallpaperMinScale); diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java index 1ed14310a500..15bd6078dc2d 100644 --- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java +++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java @@ -82,18 +82,16 @@ class WallpaperWindowToken extends WindowToken { return; } mShowWhenLocked = showWhenLocked; - if (mDisplayContent.mWallpaperController.mIsLockscreenLiveWallpaperEnabled) { - // Move the window token to the front (private) or back (showWhenLocked). This is - // possible - // because the DisplayArea underneath TaskDisplayArea only contains TYPE_WALLPAPER - // windows. - final int position = showWhenLocked ? POSITION_BOTTOM : POSITION_TOP; - - // Note: Moving all the way to the front or back breaks ordering based on addition - // times. - // We should never have more than one non-animating token of each type. - getParent().positionChildAt(position, this /* child */, false /*includingParents */); - } + // Move the window token to the front (private) or back (showWhenLocked). This is + // possible + // because the DisplayArea underneath TaskDisplayArea only contains TYPE_WALLPAPER + // windows. + final int position = showWhenLocked ? POSITION_BOTTOM : POSITION_TOP; + + // Note: Moving all the way to the front or back breaks ordering based on addition + // times. + // We should never have more than one non-animating token of each type. + getParent().positionChildAt(position, this /* child */, false /*includingParents */); } boolean canShowWhenLocked() { diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java index eefe5af314a6..3dbab1360af4 100644 --- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java @@ -462,7 +462,7 @@ public class WallpaperManagerServiceTests { wallpaper.wallpaperObserver.stopWatching(); spyOn(wallpaper.wallpaperObserver); - doReturn(wallpaper).when(wallpaper.wallpaperObserver).dataForEvent(true, false); + doReturn(wallpaper).when(wallpaper.wallpaperObserver).dataForEvent(false); wallpaper.wallpaperObserver.onEvent(CLOSE_WRITE, WALLPAPER); // ACTION_WALLPAPER_CHANGED should be invoked before onWallpaperColorsChanged. diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 75d012a8e1f2..16f97f09dd0c 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -71,6 +71,7 @@ import static android.os.UserHandle.USER_SYSTEM; import static android.os.UserManager.USER_TYPE_FULL_SECONDARY; import static android.os.UserManager.USER_TYPE_PROFILE_CLONE; import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED; +import static android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE; import static android.service.notification.Adjustment.KEY_IMPORTANCE; import static android.service.notification.Adjustment.KEY_USER_SENTIMENT; import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING; @@ -207,6 +208,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.WorkSource; import android.permission.PermissionManager; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.DeviceConfig; import android.provider.MediaStore; import android.provider.Settings; @@ -318,6 +320,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { private static final int UID_HEADLESS = 1_000_000; private static final int TOAST_DURATION = 2_000; private static final int SECONDARY_DISPLAY_ID = 42; + private static final int TEST_PROFILE_USERHANDLE = 12; private final int mUid = Binder.getCallingUid(); private final @UserIdInt int mUserId = UserHandle.getUserId(mUid); @@ -445,7 +448,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { TestableNotificationManagerService.StrongAuthTrackerFake mStrongAuthTracker; TestableFlagResolver mTestFlagResolver = new TestableFlagResolver(); - + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake( 1 << 30); @Mock @@ -826,6 +829,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mPackageIntentReceiver.onReceive(getContext(), intent); } + private void simulateProfileAvailabilityActions(String intentAction) { + final Intent intent = new Intent(intentAction); + intent.putExtra(Intent.EXTRA_USER_HANDLE, TEST_PROFILE_USERHANDLE); + mUserSwitchIntentReceiver.onReceive(mContext, intent); + } + private ArrayMap<Boolean, ArrayList<ComponentName>> generateResetComponentValues() { ArrayMap<Boolean, ArrayList<ComponentName>> changed = new ArrayMap<>(); changed.put(true, new ArrayList<>()); @@ -12751,6 +12760,23 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verify(service, times(1)).setDNDMigrationDone(user.id); } + @Test + public void testProfileUnavailableIntent() throws RemoteException { + mSetFlagsRule.enableFlags(FLAG_ALLOW_PRIVATE_PROFILE); + simulateProfileAvailabilityActions(Intent.ACTION_PROFILE_UNAVAILABLE); + verify(mWorkerHandler).post(any(Runnable.class)); + verify(mSnoozeHelper).clearData(anyInt()); + } + + + @Test + public void testManagedProfileUnavailableIntent() throws RemoteException { + mSetFlagsRule.disableFlags(FLAG_ALLOW_PRIVATE_PROFILE); + simulateProfileAvailabilityActions(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); + verify(mWorkerHandler).post(any(Runnable.class)); + verify(mSnoozeHelper).clearData(anyInt()); + } + private NotificationRecord createAndPostNotification(Notification.Builder nb, String testName) throws RemoteException { StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, testName, mUid, 0, |