diff --git a/AconfigFlags.bp b/AconfigFlags.bp index 6d74a840525bad68ca81c4a21cac346685cef21f..1c9785f34b79f70a506eb7c162029f1b514433f0 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -51,6 +51,7 @@ aconfig_srcjars = [ ":aconfig_midi_flags_java_lib{.generated_srcjars}", ":android.service.autofill.flags-aconfig-java{.generated_srcjars}", ":com.android.net.flags-aconfig-java{.generated_srcjars}", + ":device_policy_aconfig_flags_lib{.generated_srcjars}", ] filegroup { @@ -523,3 +524,23 @@ java_aconfig_library { aconfig_declarations: "com.android.net.flags-aconfig", defaults: ["framework-minus-apex-aconfig-java-defaults"], } + +// DevicePolicy +aconfig_declarations { + name: "device_policy_aconfig_flags", + package: "android.app.admin.flags", + srcs: [ + "core/java/android/app/admin/flags/flags.aconfig", + ], +} + +java_aconfig_library { + name: "device_policy_aconfig_flags_lib", + aconfig_declarations: "device_policy_aconfig_flags", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + +cc_aconfig_library { + name: "device_policy_aconfig_flags_c_lib", + aconfig_declarations: "device_policy_aconfig_flags", +} diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index b5d3ed7c8a7e66d4f22892b073572827069b1755..2af3c34bf2c45bf5ed28a65d5c6e35f2f7caab31 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -6,7 +6,7 @@ package android { field public static final String CONTROL_AUTOMOTIVE_GNSS = "android.permission.CONTROL_AUTOMOTIVE_GNSS"; field public static final String GET_INTENT_SENDER_INTENT = "android.permission.GET_INTENT_SENDER_INTENT"; field public static final String MAKE_UID_VISIBLE = "android.permission.MAKE_UID_VISIBLE"; - field public static final String USE_COMPANION_TRANSPORTS = "android.permission.USE_COMPANION_TRANSPORTS"; + field @FlaggedApi("android.companion.flags.companion_transport_apis") public static final String USE_COMPANION_TRANSPORTS = "android.permission.USE_COMPANION_TRANSPORTS"; } } @@ -85,21 +85,21 @@ package android.app.admin { package android.companion { public final class CompanionDeviceManager { - method @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void addOnMessageReceivedListener(@NonNull java.util.concurrent.Executor, int, @NonNull android.companion.CompanionDeviceManager.OnMessageReceivedListener); - method @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void addOnTransportsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.CompanionDeviceManager.OnTransportsChangedListener); - method @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnMessageReceivedListener(int, @NonNull android.companion.CompanionDeviceManager.OnMessageReceivedListener); - method @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnTransportsChangedListener(@NonNull android.companion.CompanionDeviceManager.OnTransportsChangedListener); - method @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void sendMessage(int, @NonNull byte[], @NonNull int[]); - field public static final int MESSAGE_REQUEST_CONTEXT_SYNC = 1667729539; // 0x63678883 - field public static final int MESSAGE_REQUEST_PERMISSION_RESTORE = 1669491075; // 0x63826983 - field public static final int MESSAGE_REQUEST_REMOTE_AUTHENTICATION = 1669494629; // 0x63827765 + method @FlaggedApi("android.companion.companion_transport_apis") @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void addOnMessageReceivedListener(@NonNull java.util.concurrent.Executor, int, @NonNull android.companion.CompanionDeviceManager.OnMessageReceivedListener); + method @FlaggedApi("android.companion.companion_transport_apis") @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void addOnTransportsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.CompanionDeviceManager.OnTransportsChangedListener); + method @FlaggedApi("android.companion.companion_transport_apis") @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnMessageReceivedListener(int, @NonNull android.companion.CompanionDeviceManager.OnMessageReceivedListener); + method @FlaggedApi("android.companion.companion_transport_apis") @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnTransportsChangedListener(@NonNull android.companion.CompanionDeviceManager.OnTransportsChangedListener); + method @FlaggedApi("android.companion.companion_transport_apis") @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void sendMessage(int, @NonNull byte[], @NonNull int[]); + field @FlaggedApi("android.companion.companion_transport_apis") public static final int MESSAGE_REQUEST_CONTEXT_SYNC = 1667729539; // 0x63678883 + field @FlaggedApi("android.companion.companion_transport_apis") public static final int MESSAGE_REQUEST_PERMISSION_RESTORE = 1669491075; // 0x63826983 + field @FlaggedApi("android.companion.companion_transport_apis") public static final int MESSAGE_REQUEST_REMOTE_AUTHENTICATION = 1669494629; // 0x63827765 } - public static interface CompanionDeviceManager.OnMessageReceivedListener { + @FlaggedApi("android.companion.companion_transport_apis") public static interface CompanionDeviceManager.OnMessageReceivedListener { method public void onMessageReceived(int, @NonNull byte[]); } - public static interface CompanionDeviceManager.OnTransportsChangedListener { + @FlaggedApi("android.companion.companion_transport_apis") public static interface CompanionDeviceManager.OnTransportsChangedListener { method public void onTransportsChanged(@NonNull java.util.List<android.companion.AssociationInfo>); } diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 384b9573528eb2db0b27bdcb763dcaed101c6145..306bdeb84e4d17e0306d6584b9398dca1943352d 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -541,7 +541,7 @@ package android.app.admin { field public static final String PERMITTED_INPUT_METHODS_POLICY = "permittedInputMethods"; field public static final String PERSONAL_APPS_SUSPENDED_POLICY = "personalAppsSuspended"; field public static final String SCREEN_CAPTURE_DISABLED_POLICY = "screenCaptureDisabled"; - field public static final String USB_DATA_SIGNALING_POLICY = "usbDataSignaling"; + field @FlaggedApi("android.app.admin.flags.policy_engine_migration_v2_enabled") public static final String USB_DATA_SIGNALING_POLICY = "usbDataSignaling"; } public class DevicePolicyManager { @@ -857,7 +857,7 @@ package android.companion { public final class CompanionDeviceManager { method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public void enableSecureTransport(boolean); - field public static final int MESSAGE_REQUEST_PING = 1669362552; // 0x63807378 + field @FlaggedApi("android.companion.companion_transport_apis") public static final int MESSAGE_REQUEST_PING = 1669362552; // 0x63807378 } public abstract class CompanionDeviceService extends android.app.Service { diff --git a/core/java/android/app/admin/DevicePolicyIdentifiers.java b/core/java/android/app/admin/DevicePolicyIdentifiers.java index ad0af72c72b4445d4f10a5535869b9f6aa289ac6..84b1ca5c6a61f7f5e878becc1fd86525b39b41fd 100644 --- a/core/java/android/app/admin/DevicePolicyIdentifiers.java +++ b/core/java/android/app/admin/DevicePolicyIdentifiers.java @@ -16,10 +16,13 @@ package android.app.admin; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.TestApi; +import android.app.admin.flags.Flags; import android.os.UserManager; + import java.util.Objects; /** @@ -164,6 +167,7 @@ public final class DevicePolicyIdentifiers { * * @hide */ + @FlaggedApi(Flags.FLAG_POLICY_ENGINE_MIGRATION_V2_ENABLED) @TestApi public static final String USB_DATA_SIGNALING_POLICY = "usbDataSignaling"; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/flags/FlagUtils.java b/core/java/android/app/admin/flags/FlagUtils.java similarity index 68% rename from services/devicepolicy/java/com/android/server/devicepolicy/flags/FlagUtils.java rename to core/java/android/app/admin/flags/FlagUtils.java index 7e17ef111cf0fcfe55ecc8bc228c3172a48d1291..7c3c3d5260b44b1e01b98a6351b37d639362eb26 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/flags/FlagUtils.java +++ b/core/java/android/app/admin/flags/FlagUtils.java @@ -14,15 +14,20 @@ * limitations under the License. */ -package com.android.server.devicepolicy.flags; +package android.app.admin.flags; -import static com.android.server.devicepolicy.flags.Flags.devicePolicySizeTrackingEnabled; -import static com.android.server.devicepolicy.flags.Flags.policyEngineMigrationV2Enabled; +import static android.app.admin.flags.Flags.devicePolicySizeTrackingEnabled; +import static android.app.admin.flags.Flags.policyEngineMigrationV2Enabled; +import static android.app.admin.flags.Flags.onboardingBugreportV2Enabled; import android.os.Binder; +/** + * + * @hide + */ public final class FlagUtils { - private FlagUtils(){} + private FlagUtils() {} public static boolean isPolicyEngineMigrationV2Enabled() { return Binder.withCleanCallingIdentity(() -> { @@ -35,4 +40,10 @@ public final class FlagUtils { return devicePolicySizeTrackingEnabled(); }); } + + public static boolean isOnboardingBugreportV2Enabled() { + return Binder.withCleanCallingIdentity(() -> { + return onboardingBugreportV2Enabled(); + }); + } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig similarity index 58% rename from services/devicepolicy/java/com/android/server/devicepolicy/flags/flags.aconfig rename to core/java/android/app/admin/flags/flags.aconfig index 0dde496e728582b0fbd6609ad6cbde473764176b..c145c0255b0aa89bdb7bdcc1e1816d6e2752bde0 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/flags/flags.aconfig +++ b/core/java/android/app/admin/flags/flags.aconfig @@ -1,4 +1,4 @@ -package: "com.android.server.devicepolicy.flags" +package: "android.app.admin.flags" flag { name: "policy_engine_migration_v2_enabled" @@ -6,9 +6,17 @@ flag { description: "V2 of the policy engine migrations for Android V" bug: "289520697" } + flag { name: "device_policy_size_tracking_enabled" namespace: "enterprise" description: "Add feature to track the total policy size and have a max threshold." bug: "281543351" +} + +flag { + name: "onboarding_bugreport_v2_enabled" + namespace: "enterprise" + description: "Add feature to track required changes for enabled V2 of auto-capturing of onboarding bug reports." + bug: "302517677" } \ No newline at end of file diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java index a84845a15a79217b2404d5a174f043d28d10bba6..dbc67fc5a3a3683777e6b1bee5b11ad781025010 100644 --- a/core/java/android/companion/CompanionDeviceManager.java +++ b/core/java/android/companion/CompanionDeviceManager.java @@ -23,6 +23,7 @@ import static android.Manifest.permission.REQUEST_COMPANION_PROFILE_WATCH; import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; import android.annotation.CallbackExecutor; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -216,12 +217,14 @@ public final class CompanionDeviceManager { * * @hide */ + @FlaggedApi(Flags.FLAG_COMPANION_TRANSPORT_APIS) @TestApi public static final int MESSAGE_REQUEST_PING = 0x63807378; // ?PIN /** * Message header assigned to the remote authentication handshakes. * * @hide */ + @FlaggedApi(Flags.FLAG_COMPANION_TRANSPORT_APIS) @SystemApi(client = MODULE_LIBRARIES) public static final int MESSAGE_REQUEST_REMOTE_AUTHENTICATION = 0x63827765; // ?RMA /** @@ -229,6 +232,7 @@ public final class CompanionDeviceManager { * * @hide */ + @FlaggedApi(Flags.FLAG_COMPANION_TRANSPORT_APIS) @SystemApi(client = MODULE_LIBRARIES) public static final int MESSAGE_REQUEST_CONTEXT_SYNC = 0x63678883; // ?CXS /** @@ -236,6 +240,7 @@ public final class CompanionDeviceManager { * * @hide */ + @FlaggedApi(Flags.FLAG_COMPANION_TRANSPORT_APIS) @SystemApi(client = MODULE_LIBRARIES) public static final int MESSAGE_REQUEST_PERMISSION_RESTORE = 0x63826983; // ?RES @@ -873,6 +878,7 @@ public final class CompanionDeviceManager { * * @hide */ + @FlaggedApi(Flags.FLAG_COMPANION_TRANSPORT_APIS) @SystemApi(client = MODULE_LIBRARIES) public interface OnTransportsChangedListener { /** @@ -892,6 +898,7 @@ public final class CompanionDeviceManager { * * @hide */ + @FlaggedApi(Flags.FLAG_COMPANION_TRANSPORT_APIS) @SystemApi(client = MODULE_LIBRARIES) @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void addOnTransportsChangedListener( @@ -913,6 +920,7 @@ public final class CompanionDeviceManager { * * @hide */ + @FlaggedApi(Flags.FLAG_COMPANION_TRANSPORT_APIS) @SystemApi(client = MODULE_LIBRARIES) @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnTransportsChangedListener( @@ -934,6 +942,7 @@ public final class CompanionDeviceManager { * * @hide */ + @FlaggedApi(Flags.FLAG_COMPANION_TRANSPORT_APIS) @SystemApi(client = MODULE_LIBRARIES) @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void sendMessage(int messageType, @NonNull byte[] data, @NonNull int[] associationIds) { @@ -951,6 +960,7 @@ public final class CompanionDeviceManager { * * @hide */ + @FlaggedApi(Flags.FLAG_COMPANION_TRANSPORT_APIS) @SystemApi(client = MODULE_LIBRARIES) public interface OnMessageReceivedListener { /** @@ -964,6 +974,7 @@ public final class CompanionDeviceManager { * * @hide */ + @FlaggedApi(Flags.FLAG_COMPANION_TRANSPORT_APIS) @SystemApi(client = MODULE_LIBRARIES) @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void addOnMessageReceivedListener( @@ -983,6 +994,7 @@ public final class CompanionDeviceManager { * * @hide */ + @FlaggedApi(Flags.FLAG_COMPANION_TRANSPORT_APIS) @SystemApi(client = MODULE_LIBRARIES) @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnMessageReceivedListener(int messageType, diff --git a/core/java/android/companion/flags.aconfig b/core/java/android/companion/flags.aconfig index b9e5609171c3eddd4ac6b50cea69f16e58d3cdbd..1b4234b5205ccb5484394f1563e558a844a55b96 100644 --- a/core/java/android/companion/flags.aconfig +++ b/core/java/android/companion/flags.aconfig @@ -5,4 +5,11 @@ flag { namespace: "companion" description: "Controls if the new Builder is exposed to test apis." bug: "296251481" +} + +flag { + name: "companion_transport_apis" + namespace: "companion" + description: "Grants access to the companion transport apis." + bug: "288297505" } \ No newline at end of file diff --git a/core/java/android/companion/virtual/sensor/VirtualSensor.java b/core/java/android/companion/virtual/sensor/VirtualSensor.java index eaa17925b14bd5a0a145da1e97a745c06b3109ef..14c799763a96f792af62360699f8761eb0c68c25 100644 --- a/core/java/android/companion/virtual/sensor/VirtualSensor.java +++ b/core/java/android/companion/virtual/sensor/VirtualSensor.java @@ -115,6 +115,11 @@ public final class VirtualSensor implements Parcelable { parcel.writeStrongBinder(mToken); } + @Override + public String toString() { + return "VirtualSensor{ mType=" + mType + ", mName='" + mName + "' }"; + } + /** * Send a sensor event to the system. */ diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index b765562ab587b7e1006a90b0489f058b438e69da..bb9cc0bef6717b74a2388c415ee54533b76e0f4c 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -64,6 +64,7 @@ import android.os.Process; import android.os.ResultReceiver; import android.os.ShellCommand; import android.os.StrictMode; +import android.os.SystemClock; import android.os.UserHandle; import android.os.storage.StorageManager; import android.provider.ContactsContract.QuickContact; @@ -2796,6 +2797,8 @@ public class Intent implements Parcelable, Cloneable { * started and is no longer considered stopped. * <ul> * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package. + * <li> {@link #EXTRA_TIME} containing the {@link SystemClock#elapsedRealtime() + * elapsed realtime} of when the package was unstopped. * </ul> * * <p class="note">This is a protected intent that can only be sent by the system. @@ -2869,9 +2872,15 @@ public class Intent implements Parcelable, Cloneable { * * <p class="note">This is a protected intent that can only be sent * by the system. + * <p> + * Starting in {@link Build.VERSION_CODES#VANILLA_ICE_CREAM Android V}, an extra timestamp + * {@link #EXTRA_TIME} is included with this broadcast to indicate the exact time the package + * was restarted, in {@link SystemClock#elapsedRealtime() elapsed realtime}. + * </p> */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED"; + /** * Broadcast Action: The user has cleared the data of a package. This should * be preceded by {@link #ACTION_PACKAGE_RESTARTED}, after which all of @@ -6578,8 +6587,8 @@ public class Intent implements Parcelable, Cloneable { = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY"; /** - * Optional extra specifying a time in milliseconds since the Epoch. The value must be - * non-negative. + * Optional extra specifying a time in milliseconds. The timebase depends on the Intent + * including this extra. The value must be non-negative. * <p> * Type: long * </p> diff --git a/core/java/android/service/rotationresolver/OWNERS b/core/java/android/service/rotationresolver/OWNERS index 5b57fc7fa52853dcd275dc3e67804c888917e87c..dce874dcd982c2a2a56e085928cd8db5926a887e 100644 --- a/core/java/android/service/rotationresolver/OWNERS +++ b/core/java/android/service/rotationresolver/OWNERS @@ -1,9 +1,7 @@ # Bug component: 814982 asalo@google.com -augale@google.com eejiang@google.com payamp@google.com siddikap@google.com -svetoslavganov@google.com tgadh@google.com diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 506945501609ab54a2324183724954569a47c1fd..17c7fcc3a7bb8cf28d4686f9d6e348c47004c771 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -2656,6 +2656,7 @@ public final class Display { if (displayId == getDisplayId()) { float newRatio = getHdrSdrRatio(); if (newRatio != mLastReportedRatio) { + mLastReportedRatio = newRatio; mListener.accept(Display.this); } } diff --git a/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig b/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig index 5c86feb3c22c463573822b61a69f6129a3f73f32..f6ee061fdd89891e852a7f9277a07ea7b8ced77e 100644 --- a/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig +++ b/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig @@ -13,3 +13,10 @@ flag { description: "If true, content protection groups config will be parsed." bug: "302187922" } + +flag { + name: "setting_ui_enabled" + namespace: "content_protection" + description: "If true, content protection setting ui is displayed in Settings > Privacy & Security > More security & privacy." + bug: "305792348" +} diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig index 73778900399ca16ba9a0071b2da3985fe1079764..7cfd35b075473ff17995b5829d4e42e65647e1e6 100644 --- a/core/java/android/window/flags/windowing_frontend.aconfig +++ b/core/java/android/window/flags/windowing_frontend.aconfig @@ -18,7 +18,7 @@ flag { name: "dimmer_refactor" namespace: "windowing_frontend" description: "Refactor dim to fix flickers" - bug: "281632483,295291019" + bug: "295291019" is_fixed_read_only: true } diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java index 4e7bfe50cd30905e83197f4bef729014d7b539ff..71bbccb3d989aede572d4b87b83c503592e6e57f 100644 --- a/core/java/com/android/internal/app/PlatLogoActivity.java +++ b/core/java/com/android/internal/app/PlatLogoActivity.java @@ -259,7 +259,7 @@ public class PlatLogoActivity extends Activity { } return true; } - return false; + return super.onKeyDown(keyCode,event); } @Override @@ -268,7 +268,7 @@ public class PlatLogoActivity extends Activity { stopWarp(); return true; } - return false; + return super.onKeyUp(keyCode,event); } private void startWarp() { diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java index 6e836e077e4446e1f3c84a8276cb66dd1692e870..7e9cef720a136ee74b85b92c4fc50acc9c7754dc 100644 --- a/core/java/com/android/internal/jank/InteractionJankMonitor.java +++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java @@ -40,6 +40,7 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OPEN_ALL_APPS; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OPEN_SEARCH_RESULT; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_QUICK_SWITCH; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_UNFOLD_ANIM; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_UNLOCK_ENTRANCE_ANIMATION; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_CLOCK_MOVE_ANIMATION; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_LAUNCH_CAMERA; @@ -273,7 +274,9 @@ public class InteractionJankMonitor { public static final int CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER = 82; - private static final int LAST_CUJ = CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER; + public static final int CUJ_LAUNCHER_UNFOLD_ANIM = 83; + + private static final int LAST_CUJ = CUJ_LAUNCHER_UNFOLD_ANIM; private static final int NO_STATSD_LOGGING = -1; // Used to convert CujType to InteractionType enum value for statsd logging. @@ -366,6 +369,7 @@ public class InteractionJankMonitor { CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_IME_INSETS_SHOW_ANIMATION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_SHOW_ANIMATION; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_IME_INSETS_HIDE_ANIMATION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_HIDE_ANIMATION; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_DOUBLE_TAP_DIVIDER; + CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_UNFOLD_ANIM] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_UNFOLD_ANIM; } private static class InstanceHolder { @@ -468,6 +472,7 @@ public class InteractionJankMonitor { CUJ_IME_INSETS_SHOW_ANIMATION, CUJ_IME_INSETS_HIDE_ANIMATION, CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER, + CUJ_LAUNCHER_UNFOLD_ANIM, }) @Retention(RetentionPolicy.SOURCE) public @interface CujType { @@ -1101,6 +1106,8 @@ public class InteractionJankMonitor { return "IME_INSETS_HIDE_ANIMATION"; case CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER: return "SPLIT_SCREEN_DOUBLE_TAP_DIVIDER"; + case CUJ_LAUNCHER_UNFOLD_ANIM: + return "LAUNCHER_UNFOLD_ANIM"; } return "UNKNOWN"; } diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index 406505517bcc5f9782d5f0aa13ab8b9bf185ddfd..82367834f93d5813ab7a3b63a6c6aecdb969ef9b 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -108,4 +108,5 @@ interface ILockSettings { boolean removeWeakEscrowToken(long handle, int userId); boolean isWeakEscrowTokenActive(long handle, int userId); boolean isWeakEscrowTokenValid(long handle, in byte[] token, int userId); + void unlockUserKeyIfUnsecured(int userId); } diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index d5b8f62aaf2b85ecc42bcffd740b4b4bde6cf2eb..a3e27062fa7b9de88f39d551539b89d1e785e37f 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -1933,8 +1933,23 @@ public class LockPatternUtils { } } + /** + * Unlocks the credential-encrypted storage for the given user if the user is not secured, i.e. + * doesn't have an LSKF. + * <p> + * Whether the storage has been unlocked can be determined by + * {@link StorageManager#isUserKeyUnlocked()}. + * + * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission. + * + * @param userId the ID of the user whose storage to unlock + */ public void unlockUserKeyIfUnsecured(@UserIdInt int userId) { - getLockSettingsInternal().unlockUserKeyIfUnsecured(userId); + try { + getLockSettings().unlockUserKeyIfUnsecured(userId); + } catch (RemoteException re) { + re.rethrowFromSystemServer(); + } } public void createNewUser(@UserIdInt int userId, int userSerialNumber) { diff --git a/core/java/com/android/internal/widget/LockSettingsInternal.java b/core/java/com/android/internal/widget/LockSettingsInternal.java index 6063c90d6ab9e080098e91fdb470157e689dd65a..8114e1fd3bb0401e58a44aab2b22b2d12ff6affd 100644 --- a/core/java/com/android/internal/widget/LockSettingsInternal.java +++ b/core/java/com/android/internal/widget/LockSettingsInternal.java @@ -59,17 +59,6 @@ public abstract class LockSettingsInternal { */ public abstract void onThirdPartyAppsStarted(); - /** - * Unlocks the credential-encrypted storage for the given user if the user is not secured, i.e. - * doesn't have an LSKF. - * <p> - * This doesn't throw an exception on failure; whether the storage has been unlocked can be - * determined by {@link StorageManager#isUserKeyUnlocked()}. - * - * @param userId the ID of the user whose storage to unlock - */ - public abstract void unlockUserKeyIfUnsecured(@UserIdInt int userId); - /** * Creates the locksettings state for a new user. * <p> diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index b73a7651c567774ab2d3da542ce90d02760048e8..6daa5b934284a42c7de15ecec98f0fb036305a40 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -5668,7 +5668,8 @@ android:description="@string/permdesc_deliverCompanionMessages" android:protectionLevel="normal" /> - <!-- @hide @SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES) + <!-- @hide @FlaggedApi("android.companion.flags.companion_transport_apis") + @SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES) Allows an application to send and receive messages via CDM transports. --> <permission android:name="android.permission.USE_COMPANION_TRANSPORTS" diff --git a/core/tests/coretests/src/android/view/OWNERS b/core/tests/coretests/src/android/view/OWNERS index 2ca99943a8a0b8913cf01b5a36fca1402252a8db..23668a4b2afb83e872271fa23de82a1480317b34 100644 --- a/core/tests/coretests/src/android/view/OWNERS +++ b/core/tests/coretests/src/android/view/OWNERS @@ -20,4 +20,7 @@ per-file *ContentRecord* = file:/services/core/java/com/android/server/wm/OWNER per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS # Stylus -per-file stylus/* = file:/core/java/android/text/OWNERS \ No newline at end of file +per-file stylus/* = file:/core/java/android/text/OWNERS + +# View +file:/core/java/android/view/OWNERS \ No newline at end of file diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp index c72a42cce2bd88f4a2cbb16fb9df30dcd0c717a5..187964947b946e5e11f12650f07a546532d803ce 100644 --- a/libs/WindowManager/Shell/Android.bp +++ b/libs/WindowManager/Shell/Android.bp @@ -151,6 +151,7 @@ android_library { static_libs: [ "androidx.appcompat_appcompat", "androidx.core_core-animation", + "androidx.core_core-ktx", "androidx.arch.core_core-runtime", "androidx-constraintlayout_constraintlayout", "androidx.dynamicanimation_dynamicanimation", diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/EntryHighlight.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/EntryHighlight.kt index 90c44b549df9fe4cb7ea1c6c558b2216f00ff102..330755c0b4195e0ed3a6c71929b1b330b1a27bba 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/EntryHighlight.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/EntryHighlight.kt @@ -30,11 +30,11 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import com.android.settingslib.spa.framework.common.LocalEntryDataProvider -import com.android.settingslib.spa.framework.theme.SettingsTheme @Composable -internal fun EntryHighlight(UiLayoutFn: @Composable () -> Unit) { +internal fun EntryHighlight(content: @Composable () -> Unit) { val entryData = LocalEntryDataProvider.current val entryIsHighlighted = rememberSaveable { entryData.isHighlighted } var localHighlighted by rememberSaveable { mutableStateOf(false) } @@ -45,15 +45,16 @@ internal fun EntryHighlight(UiLayoutFn: @Composable () -> Unit) { val backgroundColor by animateColorAsState( targetValue = when { localHighlighted -> MaterialTheme.colorScheme.surfaceVariant - else -> SettingsTheme.colorScheme.background + else -> Color.Transparent }, animationSpec = repeatable( iterations = 3, animation = tween(durationMillis = 500), repeatMode = RepeatMode.Restart - ) + ), + label = "BackgroundColorAnimation", ) Box(modifier = Modifier.background(color = backgroundColor)) { - UiLayoutFn() + content() } } diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 9ac1e9f58dbca396aa65d4b21b723b8c6dfd560c..572f6ff2745e3fc96fa8be5de7a364ec7b28b4b2 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -531,19 +531,25 @@ </string> <!-- A path similar to frameworks/base/core/res/res/values/config.xml - config_mainBuiltInDisplayCutout that describes a path larger than the exact path of a display - cutout. If present as well as config_enableDisplayCutoutProtection is set to true, then - SystemUI will draw this "protection path" instead of the display cutout path that is normally - used for anti-aliasing. + config_mainBuiltInDisplayCutout that describes a path larger than the exact path of a outer + display cutout. If present as well as config_enableDisplayCutoutProtection is set to true, + then SystemUI will draw this "protection path" instead of the display cutout path that is + normally used for anti-aliasing. This path will only be drawn when the front-facing camera turns on, otherwise the main DisplayCutout path will be rendered --> <string translatable="false" name="config_frontBuiltInDisplayCutoutProtection"></string> - <!-- ID for the camera that needs extra protection --> + <!-- ID for the camera of outer display that needs extra protection --> <string translatable="false" name="config_protectedCameraId"></string> + <!-- Similar to config_frontBuiltInDisplayCutoutProtection but for inner display. --> + <string translatable="false" name="config_innerBuiltInDisplayCutoutProtection"></string> + + <!-- ID for the camera of inner display that needs extra protection --> + <string translatable="false" name="config_protectedInnerCameraId"></string> + <!-- Comma-separated list of packages to exclude from camera protection e.g. "com.android.systemui,com.android.xyz" --> <string translatable="false" name="config_cameraProtectionExcludedPackages"></string> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java index 1e896142f7188c5ed85fb3ff59d8b76ba9093178..400f6529eed6f47b12bbbe14d48550da231a7bd9 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java @@ -702,13 +702,18 @@ public class RotationButtonController { @Override public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation) { - // Only hide the icon if the top task changes its requestedOrientation - // Launcher can alter its requestedOrientation while it's not on top, don't hide on this - Optional.ofNullable(ActivityManagerWrapper.getInstance()) - .map(ActivityManagerWrapper::getRunningTask) - .ifPresent(a -> { - if (a.id == taskId) setRotateSuggestionButtonState(false /* visible */); - }); + mBgExecutor.execute(() -> { + // Only hide the icon if the top task changes its requestedOrientation Launcher can + // alter its requestedOrientation while it's not on top, don't hide on this + Optional.ofNullable(ActivityManagerWrapper.getInstance()) + .map(ActivityManagerWrapper::getRunningTask) + .ifPresent(a -> { + if (a.id == taskId) { + mMainThreadHandler.post(() -> + setRotateSuggestionButtonState(false /* visible */)); + } + }); + }); } } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java index eb20669360880355539e80cd59e9e262404a9eb2..c505bd5029858ce709bb42d22552e24279ffcc67 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java @@ -61,6 +61,8 @@ public final class InteractionJankMonitorWrapper { InteractionJankMonitor.CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS; public static final int CUJ_OPEN_SEARCH_RESULT = InteractionJankMonitor.CUJ_LAUNCHER_OPEN_SEARCH_RESULT; + public static final int CUJ_LAUNCHER_UNFOLD_ANIM = + InteractionJankMonitor.CUJ_LAUNCHER_UNFOLD_ANIM; @IntDef({ CUJ_APP_LAUNCH_FROM_RECENTS, @@ -77,6 +79,7 @@ public final class InteractionJankMonitorWrapper { CUJ_CLOSE_ALL_APPS_SWIPE, CUJ_CLOSE_ALL_APPS_TO_HOME, CUJ_OPEN_SEARCH_RESULT, + CUJ_LAUNCHER_UNFOLD_ANIM, }) @Retention(RetentionPolicy.SOURCE) public @interface CujType { diff --git a/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt index 2d2ebe99d651100b9865165d029bad2338385652..d33d279023daa35ad3594678dff2e8a9f11cbde9 100644 --- a/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt +++ b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt @@ -17,6 +17,7 @@ package com.android.systemui import android.content.Context +import android.content.res.Resources import android.graphics.Path import android.graphics.Rect import android.graphics.RectF @@ -33,37 +34,32 @@ import kotlin.math.roundToInt */ class CameraAvailabilityListener( private val cameraManager: CameraManager, - private val cutoutProtectionPath: Path, - private val targetCameraId: String, + private val cameraProtectionInfoList: List<CameraProtectionInfo>, excludedPackages: String, private val executor: Executor ) { - private var cutoutBounds = Rect() private val excludedPackageIds: Set<String> private val listeners = mutableListOf<CameraTransitionCallback>() private val availabilityCallback: CameraManager.AvailabilityCallback = object : CameraManager.AvailabilityCallback() { override fun onCameraClosed(cameraId: String) { - if (targetCameraId == cameraId) { - notifyCameraInactive() + cameraProtectionInfoList.forEach { + if (cameraId == it.cameraId) { + notifyCameraInactive() + } } } override fun onCameraOpened(cameraId: String, packageId: String) { - if (targetCameraId == cameraId && !isExcluded(packageId)) { - notifyCameraActive() + cameraProtectionInfoList.forEach { + if (cameraId == it.cameraId && !isExcluded(packageId)) { + notifyCameraActive(it) + } } } } init { - val computed = RectF() - cutoutProtectionPath.computeBounds(computed, false /* unused */) - cutoutBounds.set( - computed.left.roundToInt(), - computed.top.roundToInt(), - computed.right.roundToInt(), - computed.bottom.roundToInt()) excludedPackageIds = excludedPackages.split(",").toSet() } @@ -100,8 +96,10 @@ class CameraAvailabilityListener( cameraManager.unregisterAvailabilityCallback(availabilityCallback) } - private fun notifyCameraActive() { - listeners.forEach { it.onApplyCameraProtection(cutoutProtectionPath, cutoutBounds) } + private fun notifyCameraActive(info: CameraProtectionInfo) { + listeners.forEach { + it.onApplyCameraProtection(info.cutoutProtectionPath, info.cutoutBounds) + } } private fun notifyCameraInactive() { @@ -121,12 +119,11 @@ class CameraAvailabilityListener( val manager = context .getSystemService(Context.CAMERA_SERVICE) as CameraManager val res = context.resources - val pathString = res.getString(R.string.config_frontBuiltInDisplayCutoutProtection) - val cameraId = res.getString(R.string.config_protectedCameraId) + val cameraProtectionInfoList = loadCameraProtectionInfoList(res) val excluded = res.getString(R.string.config_cameraProtectionExcludedPackages) return CameraAvailabilityListener( - manager, pathFromString(pathString), cameraId, excluded, executor) + manager, cameraProtectionInfoList, excluded, executor) } private fun pathFromString(pathString: String): Path { @@ -140,5 +137,53 @@ class CameraAvailabilityListener( return p } + + private fun loadCameraProtectionInfoList(res: Resources): List<CameraProtectionInfo> { + val list = mutableListOf<CameraProtectionInfo>() + val front = loadCameraProtectionInfo( + res, + R.string.config_protectedCameraId, + R.string.config_frontBuiltInDisplayCutoutProtection + ) + if (front != null) { + list.add(front) + } + val inner = loadCameraProtectionInfo( + res, + R.string.config_protectedInnerCameraId, + R.string.config_innerBuiltInDisplayCutoutProtection + ) + if (inner != null) { + list.add(inner) + } + return list + } + + private fun loadCameraProtectionInfo( + res: Resources, + cameraIdRes: Int, + pathRes: Int + ): CameraProtectionInfo? { + val cameraId = res.getString(cameraIdRes) + if (cameraId == null || cameraId.isEmpty()) { + return null + } + val protectionPath = pathFromString(res.getString(pathRes)) + val computed = RectF() + protectionPath.computeBounds(computed) + val protectionBounds = Rect( + computed.left.roundToInt(), + computed.top.roundToInt(), + computed.right.roundToInt(), + computed.bottom.roundToInt() + ) + return CameraProtectionInfo(cameraId, protectionPath, protectionBounds) + } } + + data class CameraProtectionInfo ( + val cameraId: String, + val cutoutProtectionPath: Path, + val cutoutBounds: Rect + ) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt index 84cd3ef622ba8a180559560ab43ba1ebf00c9e0f..3eef6aa37122ab343d1cee1a7e261c236805d4a1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt @@ -25,6 +25,7 @@ import android.util.Log import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionInfo +import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import java.util.UUID @@ -48,8 +49,8 @@ import kotlinx.coroutines.flow.filter * [TransitionInteractor]. These interactors will call [startTransition] and [updateTransition] on * this repository. * - * To print all transitions to logcat to help with debugging, run this command: - * adb shell settings put global systemui/buffer/KeyguardLog VERBOSE + * To print all transitions to logcat to help with debugging, run this command: adb shell settings + * put global systemui/buffer/KeyguardLog VERBOSE * * This will print all keyguard transitions to logcat with the KeyguardTransitionAuditLogger tag. */ @@ -73,11 +74,8 @@ interface KeyguardTransitionRepository { /** * Begin a transition from one state to another. Transitions are interruptible, and will issue a * [TransitionStep] with state = [TransitionState.CANCELED] before beginning the next one. - * - * When canceled, there are two options: to continue from the current position of the prior - * transition, or to reset the position. When [resetIfCanceled] == true, it will do the latter. */ - fun startTransition(info: TransitionInfo, resetIfCanceled: Boolean = false): UUID? + fun startTransition(info: TransitionInfo): UUID? /** * Allows manual control of a transition. When calling [startTransition], the consumer must pass @@ -138,10 +136,7 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio ) } - override fun startTransition( - info: TransitionInfo, - resetIfCanceled: Boolean, - ): UUID? { + override fun startTransition(info: TransitionInfo): UUID? { if (lastStep.from == info.from && lastStep.to == info.to) { Log.i(TAG, "Duplicate call to start the transition, rejecting: $info") return null @@ -149,10 +144,10 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio val startingValue = if (lastStep.transitionState != TransitionState.FINISHED) { Log.i(TAG, "Transition still active: $lastStep, canceling") - if (resetIfCanceled) { - 0f - } else { - lastStep.value + when (info.modeOnCanceled) { + TransitionModeOnCanceled.LAST_VALUE -> lastStep.value + TransitionModeOnCanceled.RESET -> 0f + TransitionModeOnCanceled.REVERSE -> 1f - lastStep.value } } else { 0f diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt index 6e0aa4c7682d6c91ef1b40cb6b1c33400bfae8b6..a331a668e1351d8018e8167c73b362bfc41bb1bb 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt @@ -24,6 +24,7 @@ import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositor import com.android.systemui.keyguard.shared.model.BiometricUnlockModel.Companion.isWakeAndUnlock import com.android.systemui.keyguard.shared.model.DozeStateModel import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.util.kotlin.Utils.Companion.toTriple import com.android.systemui.util.kotlin.sample import javax.inject.Inject @@ -65,8 +66,21 @@ constructor( ) .collect { (_, lastStartedStep, occluded) -> if (lastStartedStep.to == KeyguardState.AOD) { - startTransitionTo( + val toState = if (occluded) KeyguardState.OCCLUDED else KeyguardState.LOCKSCREEN + val modeOnCanceled = + if ( + toState == KeyguardState.LOCKSCREEN && + lastStartedStep.from == KeyguardState.LOCKSCREEN + ) { + TransitionModeOnCanceled.REVERSE + } else { + TransitionModeOnCanceled.LAST_VALUE + } + + startTransitionTo( + toState = toState, + modeOnCanceled = modeOnCanceled, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt index c67153a5963da2d60e54d9cbf9bf0f97f0215c61..eace0c70cb5ba8189c868d4c5d196f9291617430 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt @@ -22,6 +22,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.util.kotlin.Utils.Companion.toTriple import com.android.systemui.util.kotlin.sample @@ -114,8 +115,9 @@ constructor( .collect { (isAsleep, lastStartedStep, isAodAvailable) -> if (lastStartedStep.to == KeyguardState.GONE && isAsleep) { startTransitionTo( - if (isAodAvailable) KeyguardState.AOD else KeyguardState.DOZING, - resetIfCancelled = true, + toState = + if (isAodAvailable) KeyguardState.AOD else KeyguardState.DOZING, + modeOnCanceled = TransitionModeOnCanceled.RESET, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt index c39a4c9c41729ed3b4d87fc099c152759844f1e5..d44a9d86a731762f665b03bc49bdf25a190b6874 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt @@ -27,6 +27,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardSurfaceBehindModel import com.android.systemui.keyguard.shared.model.StatusBarState.KEYGUARD import com.android.systemui.keyguard.shared.model.TransitionInfo +import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.shade.data.repository.ShadeRepository @@ -340,8 +341,20 @@ constructor( ) .collect { (isAsleep, lastStartedStep, isAodAvailable) -> if (lastStartedStep.to == KeyguardState.LOCKSCREEN && isAsleep) { - startTransitionTo( + val toState = if (isAodAvailable) KeyguardState.AOD else KeyguardState.DOZING + val modeOnCanceled = + if ( + toState == KeyguardState.AOD && + lastStartedStep.from == KeyguardState.AOD + ) { + TransitionModeOnCanceled.REVERSE + } else { + TransitionModeOnCanceled.LAST_VALUE + } + startTransitionTo( + toState = toState, + modeOnCanceled = modeOnCanceled, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt index f1649fb2851e8476d345f59f7e8108317a32b580..24b666185ce2172ad418c70f71932038de11b4e4 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt @@ -25,6 +25,7 @@ import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardSurfaceBehindModel +import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.kotlin.Utils.Companion.toQuad @@ -236,7 +237,7 @@ constructor( getDefaultAnimatorForTransitionsToState(KeyguardState.GONE).apply { this.duration = duration.inWholeMilliseconds }, - resetIfCancelled = true + modeOnCanceled = TransitionModeOnCanceled.RESET, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt index 54c6d5f6d09f4eeb16b5770a033d2611b3848c11..76018080848f764e2ee05a7613f3c3919ed948ae 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt @@ -21,6 +21,7 @@ import android.util.Log import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionInfo +import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.util.kotlin.sample import java.util.UUID import kotlinx.coroutines.CoroutineScope @@ -49,7 +50,7 @@ sealed class TransitionInteractor( fun startTransitionTo( toState: KeyguardState, animator: ValueAnimator? = getDefaultAnimatorForTransitionsToState(toState), - resetIfCancelled: Boolean = false, + modeOnCanceled: TransitionModeOnCanceled = TransitionModeOnCanceled.LAST_VALUE ): UUID? { if ( fromState != transitionInteractor.startedKeyguardState.value && @@ -73,8 +74,8 @@ sealed class TransitionInteractor( fromState, toState, animator, - ), - resetIfCancelled + modeOnCanceled, + ) ) } @@ -91,8 +92,8 @@ sealed class TransitionInteractor( // so use the last finishedKeyguardState to determine the overriding FROM state if (finishedKeyguardState == fromState) { startTransitionTo( - KeyguardState.OCCLUDED, - resetIfCancelled = true, + toState = KeyguardState.OCCLUDED, + modeOnCanceled = TransitionModeOnCanceled.RESET, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionInfo.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionInfo.kt index bfccf3fe076cbc48b5a619e1cd0fdb515267bc8b..7a37365a9cbea2d6e79d7bb84cc603397aece095 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionInfo.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionInfo.kt @@ -22,7 +22,13 @@ data class TransitionInfo( val ownerName: String, val from: KeyguardState, val to: KeyguardState, - val animator: ValueAnimator?, // 'null' animator signal manual control + /** [null] animator signals manual control, otherwise transition run by the animator */ + val animator: ValueAnimator?, + /** + * If the transition resets in the cancellation of another transition, use this mode to + * determine how to continue. + */ + val modeOnCanceled: TransitionModeOnCanceled = TransitionModeOnCanceled.LAST_VALUE, ) { override fun toString(): String = "TransitionInfo(ownerName=$ownerName, from=$from, to=$to, " + diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/QSTilesDefaultLog.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionModeOnCanceled.kt similarity index 54% rename from packages/SystemUI/src/com/android/systemui/log/dagger/QSTilesDefaultLog.kt rename to packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionModeOnCanceled.kt index 6575cdd69c93888d10858e73fe3c0eb45b9eced3..56f90bdb4f718c7d7c688c7af3dc4cd56a8431dc 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/QSTilesDefaultLog.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionModeOnCanceled.kt @@ -11,18 +11,16 @@ * 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. + * limitations under the License */ -package com.android.systemui.log.dagger +package com.android.systemui.keyguard.shared.model -import javax.inject.Qualifier - -/** - * A default [com.android.systemui.log.LogBuffer] for QS tiles messages. It's used exclusively in - * [com.android.systemui.qs.tiles.base.logging.QSTileLogger]. If you need to increase it for you - * tile, add one to the map provided by the [QSTilesLogBuffers] - */ -@Qualifier -@MustBeDocumented -@Retention(AnnotationRetention.RUNTIME) -annotation class QSTilesDefaultLog +/** When canceled, provide different ways to start the next transition. */ +enum class TransitionModeOnCanceled { + /** Proceed from the last value. If canceled at .7, start from .7 and end at 1 */ + LAST_VALUE, + /** Start over from 0. If canceled at .7, start from 0 and end at 1 */ + RESET, + /** Reverse the transition. If canceled at .7, start from 1-.7 (0.3) and end at 1 */ + REVERSE +} diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java index 67531ad9926a4f3b887885be6c665732f920cdc2..fd6b3f1e0f45ba06b7f0bd5fdd879c7a03e82191 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java @@ -190,17 +190,6 @@ public class LogModule { } } - /** - * Provides a logging buffer for all logs related to Quick Settings tiles. This LogBuffer is - * unique for each tile. - * go/qs-tile-refactor - */ - @Provides - @QSTilesDefaultLog - public static LogBuffer provideQuickSettingsTilesLogBuffer(LogBufferFactory factory) { - return factory.create("QSTileLog", 25 /* maxSize */, false /* systrace */); - } - @Provides @QSTilesLogBuffers public static Map<TileSpec, LogBuffer> provideQuickSettingsTilesLogBufferCache() { diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt index a48e56a9f158eec982749c58e8fa3bb20ea142dd..7cb5b3bc092494f212098d74913baa39b414996d 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt @@ -731,6 +731,7 @@ constructor( removePlayer(existingSmartspaceMediaKey, dismissMediaData = false) removedPlayer?.run { debugLogger.logPotentialMemoryLeak(existingSmartspaceMediaKey) + onDestroy() } } @@ -1302,6 +1303,7 @@ internal object MediaPlayerData { val removedPlayer = removeMediaPlayer(key) if (removedPlayer != null && removedPlayer != player) { debugLogger?.logPotentialMemoryLeak(key) + removedPlayer.onDestroy() } val sortKey = MediaSortKey( @@ -1329,6 +1331,7 @@ internal object MediaPlayerData { val removedPlayer = removeMediaPlayer(key) if (!update && removedPlayer != null && removedPlayer != player) { debugLogger?.logPotentialMemoryLeak(key) + removedPlayer.onDestroy() } val sortKey = MediaSortKey( @@ -1357,7 +1360,10 @@ internal object MediaPlayerData { // MediaPlayer should not be visible // no need to set isDismissed flag. val removedPlayer = removeMediaPlayer(newKey) - removedPlayer?.run { debugLogger?.logPotentialMemoryLeak(newKey) } + removedPlayer?.run { + debugLogger?.logPotentialMemoryLeak(newKey) + onDestroy() + } mediaData.put(newKey, it) } } diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionMetricsLogger.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionMetricsLogger.kt index a53f0f11c38047741c10af8767c608c59a257376..ce8b79cd9e38882adc0a494a5e1e66cd66313cf1 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionMetricsLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionMetricsLogger.kt @@ -24,6 +24,7 @@ import com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGE import com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_SYSTEM_UI_SCREEN_RECORDER as METRICS_CREATION_SOURCE_SYSTEM_UI_SCREEN_RECORDER import com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN as METRICS_CREATION_SOURCE_UNKNOWN import com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED +import com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_PERMISSION_REQUEST_DISPLAYED as METRICS_STATE_PERMISSION_REQUEST_DISPLAYED import com.android.systemui.dagger.SysUISingleton import javax.inject.Inject @@ -47,6 +48,10 @@ constructor(private val service: IMediaProjectionManager) { ) } + fun notifyPermissionRequestDisplayed() { + notifyToServer(METRICS_STATE_PERMISSION_REQUEST_DISPLAYED, SessionCreationSource.UNKNOWN) + } + /** * Request to log that the permission request moved to the given state. * diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java index fa418fc8b98b47db4c37d3351d2d5a16f8b60678..2d830d3115625152d1cf832c2f17172e7ba3bd92 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java @@ -249,6 +249,10 @@ public class MediaProjectionPermissionActivity extends Activity setUpDialog(mDialog); mDialog.show(); + + if (savedInstanceState == null) { + mMediaProjectionMetricsLogger.notifyPermissionRequestDisplayed(); + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java index 959afd86ee8d9966bf4fd65f40c7aff1695b6ec2..e27a59c6fb21e8300f6815a2a1ad866e5361eaa9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java @@ -30,12 +30,12 @@ import androidx.annotation.Nullable; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.res.R; import com.android.systemui.animation.DialogCuj; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.qs.QSTile; @@ -45,6 +45,7 @@ import com.android.systemui.qs.QsEventLogger; import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor; import com.android.systemui.qs.tileimpl.QSTileImpl; +import com.android.systemui.res.R; import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.statusbar.phone.KeyguardDismissUtil; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -69,6 +70,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> private final DialogLaunchAnimator mDialogLaunchAnimator; private final FeatureFlags mFlags; private final PanelInteractor mPanelInteractor; + private final MediaProjectionMetricsLogger mMediaProjectionMetricsLogger; private long mMillisUntilFinished = 0; @@ -88,7 +90,8 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> KeyguardDismissUtil keyguardDismissUtil, KeyguardStateController keyguardStateController, DialogLaunchAnimator dialogLaunchAnimator, - PanelInteractor panelInteractor + PanelInteractor panelInteractor, + MediaProjectionMetricsLogger mediaProjectionMetricsLogger ) { super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger, statusBarStateController, activityStarter, qsLogger); @@ -99,6 +102,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> mKeyguardStateController = keyguardStateController; mDialogLaunchAnimator = dialogLaunchAnimator; mPanelInteractor = panelInteractor; + mMediaProjectionMetricsLogger = mediaProjectionMetricsLogger; } @Override @@ -190,6 +194,9 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> } else { dialog.show(); } + + mMediaProjectionMetricsLogger.notifyPermissionRequestDisplayed(); + return false; }; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt index 70a683b81f75ab8bfa20311f3ea495e885ff508b..f8de36563dd245a59e3f352f97ae194fa5e0edc0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt @@ -19,8 +19,8 @@ package com.android.systemui.qs.tiles.base.logging import androidx.annotation.GuardedBy import com.android.systemui.dagger.SysUISingleton import com.android.systemui.log.LogBuffer +import com.android.systemui.log.LogBufferFactory import com.android.systemui.log.core.LogLevel -import com.android.systemui.log.dagger.QSTilesDefaultLog import com.android.systemui.log.dagger.QSTilesLogBuffers import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.pipeline.shared.TileSpec @@ -29,14 +29,13 @@ import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.statusbar.StatusBarState import javax.inject.Inject -import javax.inject.Provider @SysUISingleton class QSTileLogger @Inject constructor( @QSTilesLogBuffers logBuffers: Map<TileSpec, LogBuffer>, - @QSTilesDefaultLog private val defaultLogBufferProvider: Provider<LogBuffer>, + private val factory: LogBufferFactory, private val mStatusBarStateController: StatusBarStateController, ) { @GuardedBy("logBufferCache") private val logBufferCache = logBuffers.toMutableMap() @@ -154,7 +153,13 @@ constructor( private fun TileSpec.getLogBuffer(): LogBuffer = synchronized(logBufferCache) { - logBufferCache.getOrPut(this) { defaultLogBufferProvider.get() } + logBufferCache.getOrPut(this) { + factory.create( + "QSTileLog_${this.getLogTag()}", + BUFFER_MAX_SIZE /* maxSize */, + false /* systrace */ + ) + } } private fun StateUpdateTrigger.toLogString(): String = @@ -185,5 +190,6 @@ constructor( private companion object { const val TAG_FORMAT_PREFIX = "QSLog" const val DATA_MAX_LENGTH = 50 + const val BUFFER_MAX_SIZE = 25 } } diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt index cf1fbe3685e3785c8f117b11e5c5dc8fd9ae6d1c..d6f1ed9c33343fdf331a6f1ebb029ab8a2a92caf 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt +++ b/packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt @@ -68,6 +68,10 @@ interface UserTracker : UserContentResolverProvider, UserContextProvider { */ @WeaklyReferencedCallback interface Callback { + /** + * Notifies that the current user will be changed. + */ + fun onBeforeUserSwitching(newUser: Int) {} /** * Same as {@link onUserChanging(Int, Context, Runnable)} but the callback will be diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt index 99127ea928bfcd4f20f19fafa3e78e85e573cff9..9f416bbf2c59d28b685934e980bd6f758739c4cb 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt @@ -227,6 +227,13 @@ open class UserTrackerImpl internal constructor( protected open fun handleBeforeUserSwitching(newUserId: Int) { Assert.isNotMainThread() setUserIdInternal(newUserId) + + val list = synchronized(callbacks) { + callbacks.toList() + } + list.forEach { + it.callback.get()?.onBeforeUserSwitching(newUserId) + } } @WorkerThread diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java index 9dca013f8aa4cbac05c86eed60195be44f8aefdd..aea3030967d281ef23fa9c5fd680a46e548836e0 100644 --- a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java @@ -109,6 +109,7 @@ public class ImageWallpaper extends WallpaperService { private WallpaperManager mWallpaperManager; private final WallpaperLocalColorExtractor mWallpaperLocalColorExtractor; private SurfaceHolder mSurfaceHolder; + private boolean mDrawn = false; @VisibleForTesting static final int MIN_SURFACE_WIDTH = 128; @VisibleForTesting @@ -239,6 +240,7 @@ public class ImageWallpaper extends WallpaperService { private void drawFrameSynchronized() { synchronized (mLock) { + if (mDrawn) return; drawFrameInternal(); } } @@ -276,6 +278,7 @@ public class ImageWallpaper extends WallpaperService { Rect dest = mSurfaceHolder.getSurfaceFrame(); try { canvas.drawBitmap(bitmap, null, dest, null); + mDrawn = true; } finally { surface.unlockCanvasAndPost(canvas); } diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index 897c4da0fae2069c3003ee889c62c83a1242d681..1e801aeb5a29f80bf0b8c19d73519b60e4771b40 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -33,6 +33,7 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.inputmethodservice.InputMethodService; import android.os.IBinder; +import android.util.Log; import android.view.Display; import android.view.KeyEvent; @@ -66,6 +67,7 @@ import com.android.wm.shell.splitscreen.SplitScreen; import com.android.wm.shell.sysui.ShellInterface; import java.io.PrintWriter; +import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.concurrent.Executor; @@ -371,6 +373,13 @@ public final class WMShell implements @Override public void dump(PrintWriter pw, String[] args) { + Log.d(TAG, "Dumping with args: " + String.join(", ", args)); + + // Strip out the SysUI "dependency" arg before sending to WMShell + if (args[0].equals("dependency")) { + args = Arrays.copyOfRange(args, 1, args.length); + } + // Handle commands if provided if (mShell.handleCommand(args, pw)) { return; diff --git a/packages/SystemUI/tests/src/com/android/systemui/CameraAvailabilityListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/CameraAvailabilityListenerTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..b1421b21b3771f72676f7ea46963128fc1daf2b8 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/CameraAvailabilityListenerTest.kt @@ -0,0 +1,162 @@ +package com.android.systemui + +import android.graphics.Path +import android.graphics.Rect +import android.graphics.RectF +import android.hardware.camera2.CameraManager +import android.testing.AndroidTestingRunner +import android.util.PathParser +import androidx.test.filters.SmallTest +import com.android.systemui.res.R +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.withArgCaptor +import java.util.concurrent.Executor +import kotlin.math.roundToInt +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@RunWith(AndroidTestingRunner::class) +@SmallTest +class CameraAvailabilityListenerTest : SysuiTestCase() { + companion object { + const val EXCLUDED_PKG = "test.excluded.package" + const val CAMERA_ID_FRONT = "0" + const val CAMERA_ID_INNER = "1" + const val PROTECTION_PATH_STRING_FRONT = "M 50,50 a 20,20 0 1 0 40,0 a 20,20 0 1 0 -40,0 Z" + const val PROTECTION_PATH_STRING_INNER = "M 40,40 a 10,10 0 1 0 20,0 a 10,10 0 1 0 -20,0 Z" + val PATH_RECT_FRONT = rectFromPath(pathFromString(PROTECTION_PATH_STRING_FRONT)) + val PATH_RECT_INNER = rectFromPath(pathFromString(PROTECTION_PATH_STRING_INNER)) + + private fun pathFromString(pathString: String): Path { + val spec = pathString.trim() + val p: Path + try { + p = PathParser.createPathFromPathData(spec) + } catch (e: Throwable) { + throw IllegalArgumentException("Invalid protection path", e) + } + + return p + } + + private fun rectFromPath(path: Path): Rect { + val computed = RectF() + path.computeBounds(computed) + return Rect( + computed.left.roundToInt(), + computed.top.roundToInt(), + computed.right.roundToInt(), + computed.bottom.roundToInt() + ) + } + } + + @Mock private lateinit var cameraManager: CameraManager + @Mock + private lateinit var cameraTransitionCb: CameraAvailabilityListener.CameraTransitionCallback + private lateinit var cameraAvailabilityListener: CameraAvailabilityListener + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + context + .getOrCreateTestableResources() + .addOverride(R.string.config_cameraProtectionExcludedPackages, EXCLUDED_PKG) + context + .getOrCreateTestableResources() + .addOverride(R.string.config_protectedCameraId, CAMERA_ID_FRONT) + context + .getOrCreateTestableResources() + .addOverride( + R.string.config_frontBuiltInDisplayCutoutProtection, + PROTECTION_PATH_STRING_FRONT + ) + context + .getOrCreateTestableResources() + .addOverride(R.string.config_protectedInnerCameraId, CAMERA_ID_INNER) + context + .getOrCreateTestableResources() + .addOverride( + R.string.config_innerBuiltInDisplayCutoutProtection, + PROTECTION_PATH_STRING_INNER + ) + + context.addMockSystemService(CameraManager::class.java, cameraManager) + + cameraAvailabilityListener = + CameraAvailabilityListener.Factory.build(context, context.mainExecutor) + } + + @Test + fun testFrontCamera() { + var path: Path? = null + var rect: Rect? = null + val callback = + object : CameraAvailabilityListener.CameraTransitionCallback { + override fun onApplyCameraProtection(protectionPath: Path, bounds: Rect) { + path = protectionPath + rect = bounds + } + + override fun onHideCameraProtection() {} + } + + cameraAvailabilityListener.addTransitionCallback(callback) + cameraAvailabilityListener.startListening() + + val callbackCaptor = withArgCaptor { + verify(cameraManager).registerAvailabilityCallback(any(Executor::class.java), capture()) + } + + callbackCaptor.onCameraOpened(CAMERA_ID_FRONT, "") + assertNotNull(path) + assertEquals(PATH_RECT_FRONT, rect) + } + + @Test + fun testInnerCamera() { + var path: Path? = null + var rect: Rect? = null + val callback = + object : CameraAvailabilityListener.CameraTransitionCallback { + override fun onApplyCameraProtection(protectionPath: Path, bounds: Rect) { + path = protectionPath + rect = bounds + } + + override fun onHideCameraProtection() {} + } + + cameraAvailabilityListener.addTransitionCallback(callback) + cameraAvailabilityListener.startListening() + + val callbackCaptor = withArgCaptor { + verify(cameraManager).registerAvailabilityCallback(any(Executor::class.java), capture()) + } + + callbackCaptor.onCameraOpened(CAMERA_ID_INNER, "") + assertNotNull(path) + assertEquals(PATH_RECT_INNER, rect) + } + + @Test + fun testExcludedPackage() { + cameraAvailabilityListener.addTransitionCallback(cameraTransitionCb) + cameraAvailabilityListener.startListening() + + val callbackCaptor = withArgCaptor { + verify(cameraManager).registerAvailabilityCallback(any(Executor::class.java), capture()) + } + callbackCaptor.onCameraOpened(CAMERA_ID_FRONT, EXCLUDED_PKG) + + verify(cameraTransitionCb, never()) + .onApplyCameraProtection(any(Path::class.java), any(Rect::class.java)) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt index 5afc4059357c8b3dc6bde1eccf0e5ed5a4f0a800..ad80a06e3fcd6e0e4903be0fd7d48ae5384389a5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt @@ -29,6 +29,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState.AOD import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.TransitionInfo +import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.keyguard.util.KeyguardTransitionRunner @@ -86,7 +87,7 @@ class KeyguardTransitionRepositoryTest : SysuiTestCase() { } @Test - fun startingSecondTransitionWillCancelTheFirstTransition() = + fun startingSecondTransitionWillCancelTheFirstTransitionAndUseLastValue() = TestScope().runTest { val steps = mutableListOf<TransitionStep>() val job = underTest.transition(AOD, LOCKSCREEN).onEach { steps.add(it) }.launchIn(this) @@ -100,12 +101,19 @@ class KeyguardTransitionRepositoryTest : SysuiTestCase() { val job2 = underTest.transition(LOCKSCREEN, AOD).onEach { steps.add(it) }.launchIn(this) runner.startTransition( this, - TransitionInfo(OWNER_NAME, LOCKSCREEN, AOD, getAnimator()), + TransitionInfo( + OWNER_NAME, + LOCKSCREEN, + AOD, + getAnimator(), + TransitionModeOnCanceled.LAST_VALUE + ), ) val firstTransitionSteps = listWithStep(step = BigDecimal(.1), stop = BigDecimal(.1)) assertSteps(steps.subList(0, 4), firstTransitionSteps, AOD, LOCKSCREEN) + // Second transition starts from .1 (LAST_VALUE) val secondTransitionSteps = listWithStep(step = BigDecimal(.1), start = BigDecimal(.1)) assertSteps(steps.subList(4, steps.size), secondTransitionSteps, LOCKSCREEN, AOD) @@ -113,6 +121,76 @@ class KeyguardTransitionRepositoryTest : SysuiTestCase() { job2.cancel() } + @Test + fun startingSecondTransitionWillCancelTheFirstTransitionAndUseReset() = + TestScope().runTest { + val steps = mutableListOf<TransitionStep>() + val job = underTest.transition(AOD, LOCKSCREEN).onEach { steps.add(it) }.launchIn(this) + runner.startTransition( + this, + TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, getAnimator()), + maxFrames = 3, + ) + + // Now start 2nd transition, which will interrupt the first + val job2 = underTest.transition(LOCKSCREEN, AOD).onEach { steps.add(it) }.launchIn(this) + runner.startTransition( + this, + TransitionInfo( + OWNER_NAME, + LOCKSCREEN, + AOD, + getAnimator(), + TransitionModeOnCanceled.RESET + ), + ) + + val firstTransitionSteps = listWithStep(step = BigDecimal(.1), stop = BigDecimal(.1)) + assertSteps(steps.subList(0, 4), firstTransitionSteps, AOD, LOCKSCREEN) + + // Second transition starts from 0 (RESET) + val secondTransitionSteps = listWithStep(start = BigDecimal(0), step = BigDecimal(.1)) + assertSteps(steps.subList(4, steps.size), secondTransitionSteps, LOCKSCREEN, AOD) + + job.cancel() + job2.cancel() + } + + @Test + fun startingSecondTransitionWillCancelTheFirstTransitionAndUseReverse() = + TestScope().runTest { + val steps = mutableListOf<TransitionStep>() + val job = underTest.transition(AOD, LOCKSCREEN).onEach { steps.add(it) }.launchIn(this) + runner.startTransition( + this, + TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, getAnimator()), + maxFrames = 3, + ) + + // Now start 2nd transition, which will interrupt the first + val job2 = underTest.transition(LOCKSCREEN, AOD).onEach { steps.add(it) }.launchIn(this) + runner.startTransition( + this, + TransitionInfo( + OWNER_NAME, + LOCKSCREEN, + AOD, + getAnimator(), + TransitionModeOnCanceled.REVERSE + ), + ) + + val firstTransitionSteps = listWithStep(step = BigDecimal(.1), stop = BigDecimal(.1)) + assertSteps(steps.subList(0, 4), firstTransitionSteps, AOD, LOCKSCREEN) + + // Second transition starts from .9 (REVERSE) + val secondTransitionSteps = listWithStep(start = BigDecimal(0.9), step = BigDecimal(.1)) + assertSteps(steps.subList(4, steps.size), secondTransitionSteps, LOCKSCREEN, AOD) + + job.cancel() + job2.cancel() + } + @Test fun nullAnimatorEnablesManualControlWithUpdateTransition() = TestScope().runTest { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt index f3930a37c4867f72db9dde540af7690928f84642..275ac804b321f528cdcaf420528f274be2f55056 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt @@ -57,7 +57,6 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 -import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.Mockito.clearInvocations @@ -244,7 +243,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to PRIMARY_BOUNCER should occur assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor") @@ -271,7 +270,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DOZING should occur assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor") @@ -298,7 +297,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DOZING should occur assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor") @@ -328,7 +327,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DREAMING should occur assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor") @@ -359,7 +358,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DREAMING_LOCKSCREEN_HOSTED should occur assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor") @@ -386,7 +385,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DOZING should occur assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor") @@ -413,7 +412,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DOZING should occur assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor") @@ -446,7 +445,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to Lockscreen should occur assertThat(info.ownerName).isEqualTo("FromDreamingLockscreenHostedTransitionInteractor") @@ -474,7 +473,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to Gone should occur assertThat(info.ownerName).isEqualTo("FromDreamingLockscreenHostedTransitionInteractor") @@ -504,7 +503,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to PRIMARY_BOUNCER should occur assertThat(info.ownerName).isEqualTo("FromDreamingLockscreenHostedTransitionInteractor") @@ -537,7 +536,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DOZING should occur assertThat(info.ownerName).isEqualTo("FromDreamingLockscreenHostedTransitionInteractor") @@ -569,7 +568,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to OCCLUDED should occur assertThat(info.ownerName).isEqualTo("FromDreamingLockscreenHostedTransitionInteractor") @@ -593,7 +592,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DOZING should occur assertThat(info.ownerName).isEqualTo("FromDozingTransitionInteractor") @@ -625,7 +624,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { advanceUntilIdle() // THEN the transition is ignored - verify(transitionRepository, never()).startTransition(any(), anyBoolean()) + verify(transitionRepository, never()).startTransition(any()) coroutineContext.cancelChildren() } @@ -642,7 +641,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DOZING should occur assertThat(info.ownerName).isEqualTo("FromDozingTransitionInteractor") @@ -669,7 +668,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DOZING should occur assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor") @@ -696,7 +695,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to AOD should occur assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor") @@ -719,7 +718,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to AOD should occur assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor") @@ -749,7 +748,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DREAMING should occur assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor") @@ -780,7 +779,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DREAMING_LOCKSCREEN_HOSTED should occur assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor") @@ -806,7 +805,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to PRIMARY_BOUNCER should occur assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor") @@ -838,7 +837,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to AOD should occur assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor") @@ -871,7 +870,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DOZING should occur assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor") @@ -901,7 +900,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to LOCKSCREEN should occur assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor") @@ -929,7 +928,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to AOD should occur assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor") @@ -957,7 +956,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to DOZING should occur assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor") @@ -981,7 +980,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to LOCKSCREEN should occur assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor") @@ -1011,7 +1010,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition back to DREAMING_LOCKSCREEN_HOSTED should occur assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor") @@ -1042,7 +1041,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to GONE should occur assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor") @@ -1071,7 +1070,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to LOCKSCREEN should occur assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor") @@ -1096,7 +1095,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to AlternateBouncer should occur assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor") @@ -1121,7 +1120,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to AlternateBouncer should occur assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor") @@ -1147,7 +1146,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to OCCLUDED should occur assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor") @@ -1172,7 +1171,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to OCCLUDED should occur assertThat(info.ownerName).isEqualTo("FromDozingTransitionInteractor") @@ -1199,7 +1198,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to OCCLUDED should occur assertThat(info.ownerName).isEqualTo("FromDreamingTransitionInteractor") @@ -1223,7 +1222,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to OCCLUDED should occur assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor") @@ -1253,7 +1252,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } // THEN a transition to OCCLUDED should occur assertThat(info.ownerName).isEqualTo("FromAodTransitionInteractor") @@ -1287,7 +1286,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // THEN a transition from LOCKSCREEN => OCCLUDED should occur val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor") assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN) @@ -1318,7 +1317,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // THEN a transition from LOCKSCREEN => PRIMARY_BOUNCER should occur val info = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor") assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN) @@ -1339,7 +1338,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // THEN a transition from PRIMARY_BOUNCER => LOCKSCREEN should occur val info2 = withArgCaptor<TransitionInfo> { - verify(transitionRepository).startTransition(capture(), anyBoolean()) + verify(transitionRepository).startTransition(capture()) } assertThat(info2.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER) assertThat(info2.to).isEqualTo(KeyguardState.LOCKSCREEN) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/KeyguardTransitionRunner.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/KeyguardTransitionRunner.kt index 54fc4938e1b0034909b26efb64b1a65533967747..1abb441439fe0c0d6a697d65e37ea53ab51d9870 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/KeyguardTransitionRunner.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/KeyguardTransitionRunner.kt @@ -42,7 +42,7 @@ class KeyguardTransitionRunner( private var frameCount = 1L private var frames = MutableStateFlow(Pair<Long, FrameCallback?>(0L, null)) private var job: Job? = null - private var isTerminated = false + @Volatile private var isTerminated = false /** * For transitions being directed by an animator. Will control the number of frames being diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java index 5b3d45bb6625ec4ddf030161c1d7451c55464d1c..ac03073be17badea38dfe202929324b73ed80a20 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java @@ -22,11 +22,13 @@ import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertFalse; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.Dialog; import android.os.Handler; import android.service.quicksettings.Tile; import android.testing.AndroidTestingRunner; @@ -35,11 +37,11 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -48,6 +50,7 @@ import com.android.systemui.qs.QsEventLogger; import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor; import com.android.systemui.qs.tileimpl.QSTileImpl; +import com.android.systemui.res.R; import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.statusbar.phone.KeyguardDismissUtil; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -89,6 +92,10 @@ public class ScreenRecordTileTest extends SysuiTestCase { private PanelInteractor mPanelInteractor; @Mock private QsEventLogger mUiEventLogger; + @Mock + private MediaProjectionMetricsLogger mMediaProjectionMetricsLogger; + @Mock + private Dialog mPermissionDialogPrompt; private TestableLooper mTestableLooper; private ScreenRecordTile mTile; @@ -116,7 +123,8 @@ public class ScreenRecordTileTest extends SysuiTestCase { mKeyguardDismissUtil, mKeyguardStateController, mDialogLaunchAnimator, - mPanelInteractor + mPanelInteractor, + mMediaProjectionMetricsLogger ); mTile.initialize(); @@ -280,4 +288,27 @@ public class ScreenRecordTileTest extends SysuiTestCase { assertEquals(state.icon, QSTileImpl.ResourceIcon.get(R.drawable.qs_screen_record_icon_off)); } + @Test + public void showingDialogPrompt_logsMediaProjectionPermissionRequested() { + when(mController.isStarting()).thenReturn(false); + when(mController.isRecording()).thenReturn(false); + when(mController.createScreenRecordDialog(any(), any(), any(), any(), any())) + .thenReturn(mPermissionDialogPrompt); + + mTile.handleClick(null /* view */); + mTestableLooper.processAllMessages(); + + verify(mController).createScreenRecordDialog(any(), eq(mFeatureFlags), + eq(mDialogLaunchAnimator), eq(mActivityStarter), any()); + var onDismissAction = ArgumentCaptor.forClass(ActivityStarter.OnDismissAction.class); + verify(mKeyguardDismissUtil).executeWhenUnlocked( + onDismissAction.capture(), anyBoolean(), anyBoolean()); + assertNotNull(onDismissAction.getValue()); + + onDismissAction.getValue().onDismiss(); + + verify(mPermissionDialogPrompt).show(); + verify(mMediaProjectionMetricsLogger).notifyPermissionRequestDisplayed(); + } + } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt index f1fcee318141ffbf3dd609cac66dc2488919f2c7..9907278402b0b06da95c886e37c26db18c7f3d84 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt @@ -23,11 +23,14 @@ import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.dump.LogcatEchoTrackerAlways import com.android.systemui.log.LogBuffer +import com.android.systemui.log.LogBufferFactory import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.qs.tiles.base.interactor.StateUpdateTrigger import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import java.io.PrintWriter import java.io.StringWriter @@ -42,6 +45,7 @@ import org.mockito.MockitoAnnotations class QSTileLoggerTest : SysuiTestCase() { @Mock private lateinit var statusBarController: StatusBarStateController + @Mock private lateinit var logBufferFactory: LogBufferFactory private val chattyLogBuffer = LogBuffer("TestChatty", 5, LogcatEchoTrackerAlways()) private val logBuffer = LogBuffer("Test", 1, LogcatEchoTrackerAlways()) @@ -51,10 +55,11 @@ class QSTileLoggerTest : SysuiTestCase() { @Before fun setup() { MockitoAnnotations.initMocks(this) + whenever(logBufferFactory.create(any(), any(), any())).thenReturn(logBuffer) underTest = QSTileLogger( mapOf(TileSpec.create("chatty_tile") to chattyLogBuffer), - { logBuffer }, + logBufferFactory, statusBarController ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt index e160548fed78095bcb364a499665aea09e950319..71e2bc1339a66ae2a905c6742c5b57765a10d217 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt @@ -42,7 +42,7 @@ class FakeKeyguardTransitionRepository @Inject constructor() : KeyguardTransitio _transitions.emit(step) } - override fun startTransition(info: TransitionInfo, resetIfCanceled: Boolean): UUID? { + override fun startTransition(info: TransitionInfo): UUID? { return if (info.animator == null) UUID.randomUUID() else null } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeUserTracker.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeUserTracker.kt index 4307ff980be41b8a8cf8e7af9c83c0edee7f43c7..7494ccf32a2cd693e5ef5ec2a1c5b8b5d1acaa4b 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeUserTracker.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeUserTracker.kt @@ -69,10 +69,16 @@ class FakeUserTracker( _userId = _userInfo.id _userHandle = UserHandle.of(_userId) + onBeforeUserSwitching() onUserChanging() onUserChanged() } + fun onBeforeUserSwitching(userId: Int = _userId) { + val copy = callbacks.toList() + copy.forEach { it.onBeforeUserSwitching(userId) } + } + fun onUserChanging(userId: Int = _userId) { val copy = callbacks.toList() copy.forEach { it.onUserChanging(userId, userContext) {} } diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java index 2d231b3cf42eaba30ba6342f68375103bf4481b6..aa788ebb6ba7833995b39acadc1abb1b326b5587 100644 --- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java +++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java @@ -118,6 +118,7 @@ public class SettingsToPropertiesMapper { // The list is sorted. @VisibleForTesting static final String[] sDeviceConfigAconfigScopes = new String[] { + "accessibility", "android_core_networking", "angle", "arc_next", diff --git a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java index 39f0b13f716aa4a32f6e4455ddfae9211acf7e17..200d88a78dd787db89c7c0596d76b9f7536f24a8 100644 --- a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java +++ b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java @@ -24,7 +24,6 @@ import android.os.PowerManager; import android.view.SurfaceControlHdrLayerInfoListener; import com.android.internal.annotations.VisibleForTesting; -import com.android.server.display.BrightnessUtils; import com.android.server.display.config.HdrBrightnessData; import java.io.PrintWriter; @@ -176,21 +175,14 @@ public class HdrClamper { } else if (mDesiredMaxBrightness != expectedMaxBrightness) { mDesiredMaxBrightness = expectedMaxBrightness; long debounceTime; - long transitionDuration; if (mDesiredMaxBrightness > mMaxBrightness) { debounceTime = mHdrBrightnessData.mBrightnessIncreaseDebounceMillis; - transitionDuration = mHdrBrightnessData.mBrightnessIncreaseDurationMillis; + mDesiredTransitionRate = mHdrBrightnessData.mScreenBrightnessRampIncrease; } else { debounceTime = mHdrBrightnessData.mBrightnessDecreaseDebounceMillis; - transitionDuration = mHdrBrightnessData.mBrightnessDecreaseDurationMillis; + mDesiredTransitionRate = mHdrBrightnessData.mScreenBrightnessRampDecrease; } - float maxHlg = BrightnessUtils.convertLinearToGamma(mMaxBrightness); - float desiredMaxHlg = BrightnessUtils.convertLinearToGamma(mDesiredMaxBrightness); - - mDesiredTransitionRate = Math.abs( - (maxHlg - desiredMaxHlg) * 1000f / transitionDuration); - mHandler.removeCallbacks(mDebouncer); mHandler.postDelayed(mDebouncer, debounceTime); } diff --git a/services/core/java/com/android/server/display/config/HdrBrightnessData.java b/services/core/java/com/android/server/display/config/HdrBrightnessData.java index 48d671d356f7a559fb6cbfa659b8f70d048ad9ca..837fbf7ca17c0894d4773e7eb0e125ee1fc6da3b 100644 --- a/services/core/java/com/android/server/display/config/HdrBrightnessData.java +++ b/services/core/java/com/android/server/display/config/HdrBrightnessData.java @@ -40,9 +40,9 @@ public class HdrBrightnessData { public final long mBrightnessIncreaseDebounceMillis; /** - * Brightness increase animation duration + * Brightness increase animation speed */ - public final long mBrightnessIncreaseDurationMillis; + public final float mScreenBrightnessRampIncrease; /** * Debounce time for brightness decrease @@ -50,19 +50,19 @@ public class HdrBrightnessData { public final long mBrightnessDecreaseDebounceMillis; /** - * Brightness decrease animation duration + * Brightness decrease animation speed */ - public final long mBrightnessDecreaseDurationMillis; + public final float mScreenBrightnessRampDecrease; @VisibleForTesting public HdrBrightnessData(Map<Float, Float> maxBrightnessLimits, - long brightnessIncreaseDebounceMillis, long brightnessIncreaseDurationMillis, - long brightnessDecreaseDebounceMillis, long brightnessDecreaseDurationMillis) { + long brightnessIncreaseDebounceMillis, float screenBrightnessRampIncrease, + long brightnessDecreaseDebounceMillis, float screenBrightnessRampDecrease) { mMaxBrightnessLimits = maxBrightnessLimits; mBrightnessIncreaseDebounceMillis = brightnessIncreaseDebounceMillis; - mBrightnessIncreaseDurationMillis = brightnessIncreaseDurationMillis; + mScreenBrightnessRampIncrease = screenBrightnessRampIncrease; mBrightnessDecreaseDebounceMillis = brightnessDecreaseDebounceMillis; - mBrightnessDecreaseDurationMillis = brightnessDecreaseDurationMillis; + mScreenBrightnessRampDecrease = screenBrightnessRampDecrease; } @Override @@ -70,9 +70,9 @@ public class HdrBrightnessData { return "HdrBrightnessData {" + "mMaxBrightnessLimits: " + mMaxBrightnessLimits + ", mBrightnessIncreaseDebounceMillis: " + mBrightnessIncreaseDebounceMillis - + ", mBrightnessIncreaseDurationMillis: " + mBrightnessIncreaseDurationMillis + + ", mScreenBrightnessRampIncrease: " + mScreenBrightnessRampIncrease + ", mBrightnessDecreaseDebounceMillis: " + mBrightnessDecreaseDebounceMillis - + ", mBrightnessDecreaseDurationMillis: " + mBrightnessDecreaseDurationMillis + + ", mScreenBrightnessRampDecrease: " + mScreenBrightnessRampDecrease + "} "; } @@ -94,8 +94,8 @@ public class HdrBrightnessData { return new HdrBrightnessData(brightnessLimits, hdrConfig.getBrightnessIncreaseDebounceMillis().longValue(), - hdrConfig.getBrightnessIncreaseDurationMillis().longValue(), + hdrConfig.getScreenBrightnessRampIncrease().floatValue(), hdrConfig.getBrightnessDecreaseDebounceMillis().longValue(), - hdrConfig.getBrightnessDecreaseDurationMillis().longValue()); + hdrConfig.getScreenBrightnessRampDecrease().floatValue()); } } diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index f168f435b5d7d77c7bc82f0a35aae01abe89bb24..f35b045471a66dfb8736aa42a8622256d08bfd3c 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -240,6 +240,10 @@ public class LockSettingsService extends ILockSettings.Stub { private static final String LSKF_LAST_CHANGED_TIME_KEY = "sp-handle-ts"; private static final String USER_SERIAL_NUMBER_KEY = "serial-number"; + private static final String MIGRATED_FRP2 = "migrated_frp2"; + private static final String MIGRATED_KEYSTORE_NS = "migrated_keystore_namespace"; + private static final String MIGRATED_SP_CE_ONLY = "migrated_all_users_to_sp_and_bound_ce"; + // Duration that LockSettingsService will store the gatekeeper password for. This allows // multiple biometric enrollments without prompting the user to enter their password via // ConfirmLockPassword/ConfirmLockPattern multiple times. This needs to be at least the duration @@ -909,14 +913,14 @@ public class LockSettingsService extends ILockSettings.Stub { } private void migrateOldData() { - if (getString("migrated_keystore_namespace", null, 0) == null) { + if (getString(MIGRATED_KEYSTORE_NS, null, 0) == null) { boolean success = true; synchronized (mSpManager) { success &= mSpManager.migrateKeyNamespace(); } success &= migrateProfileLockKeys(); if (success) { - setString("migrated_keystore_namespace", "true", 0); + setString(MIGRATED_KEYSTORE_NS, "true", 0); Slog.i(TAG, "Migrated keys to LSS namespace"); } else { Slog.w(TAG, "Failed to migrate keys to LSS namespace"); @@ -936,9 +940,9 @@ public class LockSettingsService extends ILockSettings.Stub { // "migrated_frp" to "migrated_frp2" to cause migrateFrpCredential() to run again on devices // where it had run before. if (LockPatternUtils.frpCredentialEnabled(mContext) - && !getBoolean("migrated_frp2", false, 0)) { + && !getBoolean(MIGRATED_FRP2, false, 0)) { migrateFrpCredential(); - setBoolean("migrated_frp2", true, 0); + setBoolean(MIGRATED_FRP2, true, 0); } } @@ -1028,14 +1032,14 @@ public class LockSettingsService extends ILockSettings.Stub { // If this gets interrupted (e.g. by the device powering off), there shouldn't be a // problem since this will run again on the next boot, and setUserKeyProtection() is // okay with the key being already protected by the given secret. - if (getString("migrated_all_users_to_sp_and_bound_ce", null, 0) == null) { + if (getString(MIGRATED_SP_CE_ONLY, null, 0) == null) { for (UserInfo user : mUserManager.getAliveUsers()) { removeStateForReusedUserIdIfNecessary(user.id, user.serialNumber); synchronized (mSpManager) { migrateUserToSpWithBoundCeKeyLocked(user.id); } } - setString("migrated_all_users_to_sp_and_bound_ce", "true", 0); + setString(MIGRATED_SP_CE_ONLY, "true", 0); } mThirdPartyAppsStarted = true; @@ -1062,7 +1066,7 @@ public class LockSettingsService extends ILockSettings.Stub { Slogf.wtf(TAG, "Failed to unwrap synthetic password for unsecured user %d", userId); return; } - setUserKeyProtection(userId, result.syntheticPassword.deriveFileBasedEncryptionKey()); + setUserKeyProtection(userId, result.syntheticPassword); } } @@ -1347,8 +1351,8 @@ public class LockSettingsService extends ILockSettings.Stub { AndroidKeyStoreMaintenance.onUserPasswordChanged(userHandle, password); } - private void unlockKeystore(byte[] password, int userHandle) { - Authorization.onLockScreenEvent(false, userHandle, password, null); + private void unlockKeystore(int userId, SyntheticPassword sp) { + Authorization.onLockScreenEvent(false, userId, sp.deriveKeyStorePassword(), null); } @VisibleForTesting /** Note: this method is overridden in unit tests */ @@ -2001,7 +2005,8 @@ public class LockSettingsService extends ILockSettings.Stub { mStorage.writeChildProfileLock(profileUserId, ArrayUtils.concat(iv, ciphertext)); } - private void setUserKeyProtection(@UserIdInt int userId, byte[] secret) { + private void setUserKeyProtection(@UserIdInt int userId, SyntheticPassword sp) { + final byte[] secret = sp.deriveFileBasedEncryptionKey(); final long callingId = Binder.clearCallingIdentity(); try { mStorageManager.setUserKeyProtection(userId, secret); @@ -2045,7 +2050,9 @@ public class LockSettingsService extends ILockSettings.Stub { } } - private void unlockUserKeyIfUnsecured(@UserIdInt int userId) { + @Override + public void unlockUserKeyIfUnsecured(@UserIdInt int userId) { + checkPasswordReadPermission(); synchronized (mSpManager) { if (isUserKeyUnlocked(userId)) { Slogf.d(TAG, "CE storage for user %d is already unlocked", userId); @@ -2768,7 +2775,7 @@ public class LockSettingsService extends ILockSettings.Stub { final long protectorId = mSpManager.createLskfBasedProtector(getGateKeeperService(), LockscreenCredential.createNone(), sp, userId); setCurrentLskfBasedProtectorId(protectorId, userId); - setUserKeyProtection(userId, sp.deriveFileBasedEncryptionKey()); + setUserKeyProtection(userId, sp); onSyntheticPasswordCreated(userId, sp); Slogf.i(TAG, "Successfully initialized synthetic password for user %d", userId); return sp; @@ -2827,7 +2834,7 @@ public class LockSettingsService extends ILockSettings.Stub { } } - unlockKeystore(sp.deriveKeyStorePassword(), userId); + unlockKeystore(userId, sp); unlockUserKey(userId, sp); @@ -2894,7 +2901,7 @@ public class LockSettingsService extends ILockSettings.Stub { mSpManager.clearSidForUser(userId); gateKeeperClearSecureUserId(userId); unlockUserKey(userId, sp); - unlockKeystore(sp.deriveKeyStorePassword(), userId); + unlockKeystore(userId, sp); setKeystorePassword(null, userId); removeBiometricsForUser(userId); } @@ -3453,11 +3460,6 @@ public class LockSettingsService extends ILockSettings.Stub { LockSettingsService.this.onThirdPartyAppsStarted(); } - @Override - public void unlockUserKeyIfUnsecured(@UserIdInt int userId) { - LockSettingsService.this.unlockUserKeyIfUnsecured(userId); - } - @Override public void createNewUser(@UserIdInt int userId, int userSerialNumber) { LockSettingsService.this.createNewUser(userId, userSerialNumber); diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java index df95c69e7271cefce1b4f8ab0cfb822b2ba105f6..4bac872dbaa9674e85ad31da2518b0d2a8d06f2b 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java @@ -174,7 +174,7 @@ class LockSettingsShellCommand extends ShellCommand { pw.println(" Sets the lock screen as PIN, using the given PIN to unlock."); pw.println(""); pw.println(" set-password [--old <CREDENTIAL>] [--user USER_ID] <PASSWORD>"); - pw.println(" Sets the lock screen as password, using the given PASSOWRD to unlock."); + pw.println(" Sets the lock screen as password, using the given PASSWORD to unlock."); pw.println(""); pw.println(" clear [--old <CREDENTIAL>] [--user USER_ID]"); pw.println(" Clears the lock credentials."); diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 0e8f90795ef930a82cea2be5cee199a4f2b7b1d3..2c595116afed5a90b421b67d62e99a8d8140b557 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -268,7 +268,14 @@ public class MediaSessionService extends SystemService implements Monitor { } if (record.isSystemPriority()) { if (DEBUG_KEY_EVENT) { - Log.d(TAG, "Global priority session is updated, active=" + record.isActive()); + Log.d( + TAG, + "Global priority session updated - user id=" + + record.getUserId() + + " package=" + + record.getPackageName() + + " active=" + + record.isActive()); } user.pushAddressedPlayerChangedLocked(); } else { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 839b6998bd8b60708223125c41589befad7090e8..61b6b24ba97e04f40412db504ce8e10a2c945190 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4566,6 +4566,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService final Bundle extras = new Bundle(); extras.putInt(Intent.EXTRA_UID, pmi.getPackageUid(packageName, 0, userId)); extras.putInt(Intent.EXTRA_USER_HANDLE, userId); + extras.putLong(Intent.EXTRA_TIME, SystemClock.elapsedRealtime()); mHandler.post(() -> { mBroadcastHelper.sendPackageBroadcast(Intent.ACTION_PACKAGE_UNSTOPPED, packageName, extras, @@ -6969,6 +6970,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService final Bundle extras = new Bundle(); extras.putInt(Intent.EXTRA_UID, uid); extras.putInt(Intent.EXTRA_USER_HANDLE, userId); + extras.putLong(Intent.EXTRA_TIME, SystemClock.elapsedRealtime()); mHandler.post(() -> { mBroadcastHelper.sendPackageBroadcast(Intent.ACTION_PACKAGE_RESTARTED, packageName, extras, diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java index 3ca933a66656d90f6bac58d3e0cff7800037e871..42f4cfb8b4dfa084f4e65ce072a27e68250b27b2 100644 --- a/services/core/java/com/android/server/pm/PackageSetting.java +++ b/services/core/java/com/android/server/pm/PackageSetting.java @@ -238,34 +238,16 @@ public class PackageSetting extends SettingBase implements PackageStateInternal } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - public PackageSetting(String name, String realName, @NonNull File path, - String legacyNativeLibraryPath, String primaryCpuAbi, - String secondaryCpuAbi, String cpuAbiOverride, - long longVersionCode, int pkgFlags, int pkgPrivateFlags, - int sharedUserAppId, - String[] usesSdkLibraries, long[] usesSdkLibrariesVersionsMajor, - String[] usesStaticLibraries, long[] usesStaticLibrariesVersions, - Map<String, Set<String>> mimeGroups, - @NonNull UUID domainSetId) { + public PackageSetting(@NonNull String name, @Nullable String realName, @NonNull File path, + int pkgFlags, int pkgPrivateFlags, @NonNull UUID domainSetId) { super(pkgFlags, pkgPrivateFlags); this.mName = name; this.mRealName = realName; - this.usesSdkLibraries = usesSdkLibraries; - this.usesSdkLibrariesVersionsMajor = usesSdkLibrariesVersionsMajor; - this.usesStaticLibraries = usesStaticLibraries; - this.usesStaticLibrariesVersions = usesStaticLibrariesVersions; this.mPath = path; this.mPathString = path.toString(); - this.legacyNativeLibraryPath = legacyNativeLibraryPath; - this.mPrimaryCpuAbi = primaryCpuAbi; - this.mSecondaryCpuAbi = secondaryCpuAbi; - this.mCpuAbiOverride = cpuAbiOverride; - this.versionCode = longVersionCode; this.signatures = new PackageSignatures(); this.installSource = InstallSource.EMPTY; - this.mSharedUserAppId = sharedUserAppId; - mDomainSetId = domainSetId; - copyMimeGroups(mimeGroups); + this.mDomainSetId = domainSetId; mSnapshot = makeCache(); } @@ -536,9 +518,10 @@ public class PackageSetting extends SettingBase implements PackageStateInternal return this; } - public void setSharedUserAppId(int sharedUserAppId) { + public PackageSetting setSharedUserAppId(int sharedUserAppId) { mSharedUserAppId = sharedUserAppId; onChanged(); + return this; } public PackageSetting setIsPersistent(boolean isPersistent) { @@ -576,7 +559,7 @@ public class PackageSetting extends SettingBase implements PackageStateInternal + " " + mName + "/" + mAppId + "}"; } - protected void copyMimeGroups(@Nullable Map<String, Set<String>> newMimeGroups) { + private void copyMimeGroups(@Nullable Map<String, Set<String>> newMimeGroups) { if (newMimeGroups == null) { mimeGroups = null; return; @@ -1250,7 +1233,8 @@ public class PackageSetting extends SettingBase implements PackageStateInternal /** * @see #mPath */ - PackageSetting setPath(@NonNull File path) { + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + public PackageSetting setPath(@NonNull File path) { this.mPath = path; this.mPathString = path.toString(); onChanged(); @@ -1451,9 +1435,11 @@ public class PackageSetting extends SettingBase implements PackageStateInternal return this; } - public PackageSetting setMimeGroups(@NonNull Map<String, Set<String>> mimeGroups) { - this.mimeGroups = mimeGroups; - onChanged(); + public PackageSetting setMimeGroups(@Nullable Map<String, Set<String>> mimeGroups) { + if (mimeGroups != null) { + copyMimeGroups(mimeGroups); + onChanged(); + } return this; } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index e726d91c30a0e0090dc9946ab30f6a20f6f4f3e6..a39178ec4baa84a41664d5450c461e3adc6c8001 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -931,16 +931,24 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile sharedUserSetting.mDisabledPackages.remove(p); } p.getPkgState().setUpdatedSystemApp(false); - PackageSetting ret = addPackageLPw(name, p.getRealName(), p.getPath(), - p.getLegacyNativeLibraryPath(), p.getPrimaryCpuAbiLegacy(), - p.getSecondaryCpuAbiLegacy(), p.getCpuAbiOverride(), - p.getAppId(), p.getVersionCode(), p.getFlags(), p.getPrivateFlags(), - p.getUsesSdkLibraries(), p.getUsesSdkLibrariesVersionsMajor(), - p.getUsesStaticLibraries(), p.getUsesStaticLibrariesVersions(), p.getMimeGroups(), - mDomainVerificationManager.generateNewId()); + PackageSetting ret = addPackageLPw(name, p.getRealName(), p.getPath(), p.getAppId(), + p.getFlags(), p.getPrivateFlags(), mDomainVerificationManager.generateNewId()); if (ret != null) { + ret.setLegacyNativeLibraryPath(p.getLegacyNativeLibraryPath()); + ret.setPrimaryCpuAbi(p.getPrimaryCpuAbiLegacy()); + ret.setSecondaryCpuAbi(p.getSecondaryCpuAbiLegacy()); + ret.setCpuAbiOverride(p.getCpuAbiOverride()); + ret.setLongVersionCode(p.getVersionCode()); + ret.setUsesSdkLibraries(p.getUsesSdkLibraries()); + ret.setUsesSdkLibrariesVersionsMajor(p.getUsesSdkLibrariesVersionsMajor()); + ret.setUsesStaticLibraries(p.getUsesStaticLibraries()); + ret.setUsesStaticLibrariesVersions(p.getUsesStaticLibrariesVersions()); + ret.setMimeGroups(p.getMimeGroups()); ret.setAppMetadataFilePath(p.getAppMetadataFilePath()); ret.getPkgState().setUpdatedSystemApp(false); + ret.setIsPersistent(p.isPersistent()); + ret.setTargetSdkVersion(p.getTargetSdkVersion()); + ret.setRestrictUpdateHash(p.getRestrictUpdateHash()); } mDisabledSysPackages.remove(name); return ret; @@ -961,13 +969,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile } } - PackageSetting addPackageLPw(String name, String realName, File codePath, - String legacyNativeLibraryPathString, String primaryCpuAbiString, - String secondaryCpuAbiString, String cpuAbiOverrideString, int uid, long vc, - int pkgFlags, int pkgPrivateFlags, String[] usesSdkLibraries, - long[] usesSdkLibrariesVersions, String[] usesStaticLibraries, - long[] usesStaticLibrariesVersions, Map<String, Set<String>> mimeGroups, - @NonNull UUID domainSetId) { + PackageSetting addPackageLPw(String name, String realName, File codePath, int uid, int pkgFlags, + int pkgPrivateFlags, @NonNull UUID domainSetId) { PackageSetting p = mPackages.get(name); if (p != null) { if (p.getAppId() == uid) { @@ -977,11 +980,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile "Adding duplicate package, keeping first: " + name); return null; } - p = new PackageSetting(name, realName, codePath, legacyNativeLibraryPathString, - primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, vc, pkgFlags, - pkgPrivateFlags, 0 /*userId*/, usesSdkLibraries, usesSdkLibrariesVersions, - usesStaticLibraries, usesStaticLibrariesVersions, mimeGroups, domainSetId); - p.setAppId(uid); + p = new PackageSetting(name, realName, codePath, pkgFlags, pkgPrivateFlags, domainSetId) + .setAppId(uid); if (mAppIds.registerExistingAppId(uid, p, name)) { mPackages.put(name, p); return p; @@ -1092,16 +1092,21 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile int installUserId = installUser != null ? installUser.getIdentifier() : UserHandle.USER_SYSTEM; - pkgSetting = new PackageSetting(pkgName, realPkgName, codePath, - legacyNativeLibraryPath, primaryCpuAbi, secondaryCpuAbi, - null /*cpuAbiOverrideString*/, versionCode, pkgFlags, pkgPrivateFlags, - 0 /*sharedUserAppId*/, usesSdkLibraries, usesSdkLibrariesVersions, - usesStaticLibraries, usesStaticLibrariesVersions, - createMimeGroups(mimeGroupNames), domainSetId) + pkgSetting = new PackageSetting(pkgName, realPkgName, codePath, pkgFlags, + pkgPrivateFlags, domainSetId) + .setUsesSdkLibraries(usesSdkLibraries) + .setUsesSdkLibrariesVersionsMajor(usesSdkLibrariesVersions) + .setUsesStaticLibraries(usesStaticLibraries) + .setUsesStaticLibrariesVersions(usesStaticLibrariesVersions) + .setLegacyNativeLibraryPath(legacyNativeLibraryPath) + .setPrimaryCpuAbi(primaryCpuAbi) + .setSecondaryCpuAbi(secondaryCpuAbi) + .setLongVersionCode(versionCode) + .setMimeGroups(createMimeGroups(mimeGroupNames)) .setIsPersistent(isPersistent) .setTargetSdkVersion(targetSdkVersion) - .setRestrictUpdateHash(restrictUpdatedHash); - pkgSetting.setLastModifiedTime(codePath.lastModified()); + .setRestrictUpdateHash(restrictUpdatedHash) + .setLastModifiedTime(codePath.lastModified()); if (sharedUser != null) { pkgSetting.setSharedUserAppId(sharedUser.mAppId); } @@ -3066,6 +3071,12 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile serializer.attributeLongHex(null, "ft", pkg.getLastModifiedTime()); serializer.attributeLongHex(null, "ut", pkg.getLastUpdateTime()); serializer.attributeLong(null, "version", pkg.getVersionCode()); + serializer.attributeBoolean(null, "isPersistent", pkg.isPersistent()); + serializer.attributeInt(null, "targetSdkVersion", pkg.getTargetSdkVersion()); + if (pkg.getRestrictUpdateHash() != null) { + serializer.attributeBytesBase64(null, "restrictUpdateHash", + pkg.getRestrictUpdateHash()); + } if (pkg.getLegacyNativeLibraryPath() != null) { serializer.attribute(null, "nativeLibraryPath", pkg.getLegacyNativeLibraryPath()); } @@ -3129,6 +3140,12 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile serializer.attributeLongHex(null, "ft", pkg.getLastModifiedTime()); serializer.attributeLongHex(null, "ut", pkg.getLastUpdateTime()); serializer.attributeLong(null, "version", pkg.getVersionCode()); + serializer.attributeBoolean(null, "isPersistent", pkg.isPersistent()); + serializer.attributeInt(null, "targetSdkVersion", pkg.getTargetSdkVersion()); + if (pkg.getRestrictUpdateHash() != null) { + serializer.attributeBytesBase64(null, "restrictUpdateHash", + pkg.getRestrictUpdateHash()); + } if (!pkg.hasSharedUser()) { serializer.attributeInt(null, "userId", pkg.getAppId()); } else { @@ -3861,6 +3878,10 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile } long versionCode = parser.getAttributeLong(null, "version", 0); + boolean isPersistent = parser.getAttributeBoolean(null, "isPersistent", false); + int targetSdkVersion = parser.getAttributeInt(null, "targetSdkVersion", 0); + byte[] restrictUpdateHash = parser.getAttributeBytesBase64(null, "restrictUpdateHash", + null); int pkgFlags = 0; int pkgPrivateFlags = 0; @@ -3873,10 +3894,16 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile // debug invalid entries. The actual logic for migrating to a new ID is done in other // methods that use DomainVerificationManagerInternal#generateNewId UUID domainSetId = DomainVerificationManagerInternal.DISABLED_ID; - PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr), - legacyNativeLibraryPathStr, primaryCpuAbiStr, secondaryCpuAbiStr, cpuAbiOverrideStr, - versionCode, pkgFlags, pkgPrivateFlags, 0 /*sharedUserAppId*/, null, null, null, - null, null, domainSetId); + PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr), pkgFlags, + pkgPrivateFlags, domainSetId) + .setLegacyNativeLibraryPath(legacyNativeLibraryPathStr) + .setPrimaryCpuAbi(primaryCpuAbiStr) + .setSecondaryCpuAbi(secondaryCpuAbiStr) + .setCpuAbiOverride(cpuAbiOverrideStr) + .setLongVersionCode(versionCode) + .setIsPersistent(isPersistent) + .setTargetSdkVersion(targetSdkVersion) + .setRestrictUpdateHash(restrictUpdateHash); long timeStamp = parser.getAttributeLongHex(null, "ft", 0); if (timeStamp == 0) { timeStamp = parser.getAttributeLong(null, "ts", 0); @@ -3970,6 +3997,9 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile long loadingCompletedTime = 0; UUID domainSetId; String appMetadataFilePath = null; + boolean isPersistent = false; + int targetSdkVersion = 0; + byte[] restrictUpdateHash = null; try { name = parser.getAttributeValue(null, ATTR_NAME); realName = parser.getAttributeValue(null, "realName"); @@ -3993,6 +4023,9 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile } versionCode = parser.getAttributeLong(null, "version", 0); + isPersistent = parser.getAttributeBoolean(null, "isPersistent", false); + targetSdkVersion = parser.getAttributeInt(null, "targetSdkVersion", 0); + restrictUpdateHash = parser.getAttributeBytesBase64(null, "restrictUpdateHash", null); installerPackageName = parser.getAttributeValue(null, "installer"); installerPackageUid = parser.getAttributeInt(null, "installerUid", INVALID_UID); updateOwnerPackageName = parser.getAttributeValue(null, "updateOwner"); @@ -4088,11 +4121,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile + parser.getPositionDescription()); } else if (appId > 0) { packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr), - legacyNativeLibraryPathStr, primaryCpuAbiString, secondaryCpuAbiString, - cpuAbiOverrideString, appId, versionCode, pkgFlags, pkgPrivateFlags, - null /* usesSdkLibraries */, null /* usesSdkLibraryVersions */, - null /* usesStaticLibraries */, null /* usesStaticLibraryVersions */, - null /* mimeGroups */, domainSetId); + appId, pkgFlags, pkgPrivateFlags, domainSetId); if (PackageManagerService.DEBUG_SETTINGS) Log.i(PackageManagerService.TAG, "Reading package " + name + ": appId=" + appId + " pkg=" + packageSetting); @@ -4101,22 +4130,26 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile + appId + " while parsing settings at " + parser.getPositionDescription()); } else { + packageSetting.setLegacyNativeLibraryPath(legacyNativeLibraryPathStr); + packageSetting.setPrimaryCpuAbi(primaryCpuAbiString); + packageSetting.setSecondaryCpuAbi(secondaryCpuAbiString); + packageSetting.setCpuAbiOverride(cpuAbiOverrideString); + packageSetting.setLongVersionCode(versionCode); packageSetting.setLastModifiedTime(timeStamp); packageSetting.setLastUpdateTime(lastUpdateTime); } } else if (sharedUserAppId != 0) { if (sharedUserAppId > 0) { packageSetting = new PackageSetting(name.intern(), realName, - new File(codePathStr), legacyNativeLibraryPathStr, - primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, - versionCode, pkgFlags, pkgPrivateFlags, sharedUserAppId, - null /* usesSdkLibraries */, - null /* usesSdkLibrariesVersions */, - null /* usesStaticLibraries */, - null /* usesStaticLibraryVersions */, - null /* mimeGroups */, domainSetId); - packageSetting.setLastModifiedTime(timeStamp); - packageSetting.setLastUpdateTime(lastUpdateTime); + new File(codePathStr), pkgFlags, pkgPrivateFlags, domainSetId) + .setLegacyNativeLibraryPath(legacyNativeLibraryPathStr) + .setPrimaryCpuAbi(primaryCpuAbiString) + .setSecondaryCpuAbi(secondaryCpuAbiString) + .setCpuAbiOverride(cpuAbiOverrideString) + .setLongVersionCode(versionCode) + .setSharedUserAppId(sharedUserAppId) + .setLastModifiedTime(timeStamp) + .setLastUpdateTime(lastUpdateTime); mPendingPackages.add(packageSetting); if (PackageManagerService.DEBUG_SETTINGS) Log.i(PackageManagerService.TAG, "Reading package " + name @@ -4155,7 +4188,10 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile .setForceQueryableOverride(installedForceQueryable) .setLoadingProgress(loadingProgress) .setLoadingCompletedTime(loadingCompletedTime) - .setAppMetadataFilePath(appMetadataFilePath); + .setAppMetadataFilePath(appMetadataFilePath) + .setIsPersistent(isPersistent) + .setTargetSdkVersion(targetSdkVersion) + .setRestrictUpdateHash(restrictUpdateHash); // Handle legacy string here for single-user mode final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED); if (enabledStr != null) { @@ -4916,9 +4952,11 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile } pw.print(prefix); pw.print(" versionCode="); pw.print(ps.getVersionCode()); if (pkg != null) { - pw.print(" minSdk="); pw.print(pkg.getMinSdkVersion()); - pw.print(" targetSdk="); pw.println(pkg.getTargetSdkVersion()); - + pw.print(" minSdk="); + pw.print(pkg.getMinSdkVersion()); + } + pw.print(" targetSdk="); pw.println(ps.getTargetSdkVersion()); + if (pkg != null) { SparseIntArray minExtensionVersions = pkg.getMinExtensionVersions(); pw.print(prefix); pw.print(" minExtensionVersions=["); diff --git a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java index 99878679431c932aecdaea22ef3b96c58025d237..585e2e48fb854e677c01f09443e608c38d1d3021 100644 --- a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java +++ b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java @@ -16,6 +16,7 @@ package com.android.server.pm; +import static android.content.pm.Flags.sdkLibIndependence; import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST; @@ -951,10 +952,12 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable } } if (!pkg.getUsesSdkLibraries().isEmpty()) { + // Allow installation even if sdk-library dependency doesn't exist + boolean required = !sdkLibIndependence(); usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesSdkLibraries(), pkg.getUsesSdkLibrariesVersionsMajor(), pkg.getUsesSdkLibrariesCertDigests(), - pkg.getPackageName(), "sdk", true, pkg.getTargetSdkVersion(), usesLibraryInfos, - availablePackages, newLibraries); + pkg.getPackageName(), "sdk", required, pkg.getTargetSdkVersion(), + usesLibraryInfos, availablePackages, newLibraries); } return usesLibraryInfos; } diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java index d6e35e8b1fd3653697d93ef3db8ed2cdb8c411bd..a33e3532153b64129ae3931e92f2c46f0f3ff846 100644 --- a/services/core/java/com/android/server/policy/PermissionPolicyService.java +++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java @@ -347,8 +347,15 @@ public final class PermissionPolicyService extends SystemService { UserHandle user = UserHandle.getUserHandleForUid(uid); PermissionControllerManager manager = mPermControllerManagers.get(user); if (manager == null) { - manager = new PermissionControllerManager( - getUserContext(getContext(), user), PermissionThread.getHandler()); + try { + manager = new PermissionControllerManager( + getUserContext(getContext(), user), PermissionThread.getHandler()); + } catch (IllegalArgumentException exception) { + // There's a possible race condition when a user is being removed + Log.e(LOG_TAG, "Could not create PermissionControllerManager for user" + + user, exception); + return; + } mPermControllerManagers.put(user, manager); } manager.updateUserSensitiveForApp(uid); diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java index 1d5cac54d12bf65b18afd92a29345012091ed9dd..7f55836598b5feec677f78740189ff85e59e75cf 100644 --- a/services/core/java/com/android/server/vibrator/VibrationSettings.java +++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java @@ -833,18 +833,24 @@ final class VibrationSettings { private final SparseArray<Integer> mProcStatesCache = new SparseArray<>(); public boolean isUidForeground(int uid) { - return mProcStatesCache.get(uid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) - <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; + synchronized (this) { + return mProcStatesCache.get(uid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) + <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; + } } @Override public void onUidGone(int uid, boolean disabled) { - mProcStatesCache.delete(uid); + synchronized (this) { + mProcStatesCache.delete(uid); + } } @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { - mProcStatesCache.put(uid, procState); + synchronized (this) { + mProcStatesCache.put(uid, procState); + } } } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index a01113b26a1e019aecbc86194c88edfa8963fc49..9fa5ed2cfde97a45bc2716c810739b94d03df752 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -4030,6 +4030,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (mAppStopped) { abortAndClearOptionsAnimation(); } + if (mDisplayContent != null) { + mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this); + } } boolean isFinishing() { @@ -5388,12 +5391,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mLastDeferHidingClient = deferHidingClient; if (!visible) { - // If this activity is about to finish/stopped and now becomes invisible, remove it - // from the unknownApp list in case the activity does not want to draw anything, which - // keep the user waiting for the next transition to start. - if (finishing || isState(STOPPED)) { - displayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this); - } // Because starting window was transferred, this activity may be a trampoline which has // been occluded by next activity. If it has added windows, set client visibility // immediately to avoid the client getting RELAYOUT_RES_FIRST_TIME from relayout and @@ -5837,6 +5834,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A break; case STOPPED: mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_STOPPED); + if (mDisplayContent != null) { + mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this); + } break; case DESTROYED: if (app != null && (mVisible || mVisibleRequested)) { @@ -6517,7 +6517,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } // Reset the last saved PiP snap fraction on app stop. mDisplayContent.mPinnedTaskController.onActivityHidden(mActivityComponent); - mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this); if (isClientVisible()) { // Though this is usually unlikely to happen, still make sure the client is invisible. setClientVisible(false); diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java index 444470952c5dcbdf7ab98fe6db3fba7aa16b8820..c79a8b6b13a167bad426e6aa88399acd5359cda3 100644 --- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java +++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java @@ -378,8 +378,23 @@ class BLASTSyncEngine { if (!wc.isSyncFinished(this)) { allFinished = false; Slog.i(TAG, "Unfinished container: " + wc); + wc.forAllActivities(a -> { + if (a.isVisibleRequested()) { + if (a.isRelaunching()) { + Slog.i(TAG, " " + a + " is relaunching"); + } + a.forAllWindows(w -> { + Slog.i(TAG, " " + w + " " + w.mWinAnimator.drawStateToString()); + }, true /* traverseTopToBottom */); + } else if (a.mDisplayContent != null && !a.mDisplayContent + .mUnknownAppVisibilityController.allResolved()) { + Slog.i(TAG, " UnknownAppVisibility: " + a.mDisplayContent + .mUnknownAppVisibilityController.getDebugMessage()); + } + }); } } + for (int i = mDependencies.size() - 1; i >= 0; --i) { allFinished = false; Slog.i(TAG, "Unfinished dependency: " + mDependencies.get(i).mSyncId); diff --git a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java index 41c1e793dd90181b494690d4fca86ba1d9e4200d..c0713966d8de80d6d9b2a369e8cc7cc216a576a8 100644 --- a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java +++ b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java @@ -70,6 +70,9 @@ class UnknownAppVisibilityController { } boolean isVisibilityUnknown(ActivityRecord r) { + if (mUnknownApps.isEmpty()) { + return false; + } return mUnknownApps.containsKey(r); } @@ -90,6 +93,9 @@ class UnknownAppVisibilityController { } void appRemovedOrHidden(@NonNull ActivityRecord activity) { + if (mUnknownApps.isEmpty()) { + return; + } if (DEBUG_UNKNOWN_APP_VISIBILITY) { Slog.d(TAG, "App removed or hidden activity=" + activity); } @@ -117,8 +123,11 @@ class UnknownAppVisibilityController { * Notifies that {@param activity} has finished resuming. */ void notifyAppResumedFinished(@NonNull ActivityRecord activity) { - if (mUnknownApps.containsKey(activity) - && mUnknownApps.get(activity) == UNKNOWN_STATE_WAITING_RESUME) { + if (mUnknownApps.isEmpty()) { + return; + } + final Integer state = mUnknownApps.get(activity); + if (state != null && state == UNKNOWN_STATE_WAITING_RESUME) { if (DEBUG_UNKNOWN_APP_VISIBILITY) { Slog.d(TAG, "App resume finished activity=" + activity); } @@ -130,13 +139,16 @@ class UnknownAppVisibilityController { * Notifies that {@param activity} has relaid out. */ void notifyRelayouted(@NonNull ActivityRecord activity) { - if (!mUnknownApps.containsKey(activity)) { + if (mUnknownApps.isEmpty()) { + return; + } + final Integer state = mUnknownApps.get(activity); + if (state == null) { return; } if (DEBUG_UNKNOWN_APP_VISIBILITY) { Slog.d(TAG, "App relayouted appWindow=" + activity); } - int state = mUnknownApps.get(activity); if (state == UNKNOWN_STATE_WAITING_RELAYOUT || activity.mStartingWindow != null) { mUnknownApps.put(activity, UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE); mDisplayContent.notifyKeyguardFlagsChanged(); diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd index debd891400b6d540f7d4ef5426a0005665d4ad39..215934f4dc09f828078c4e5956607cadc1e02b88 100644 --- a/services/core/xsd/display-device-config/display-device-config.xsd +++ b/services/core/xsd/display-device-config/display-device-config.xsd @@ -272,12 +272,12 @@ <xs:element name="brightnessDecreaseDebounceMillis" type="xs:nonNegativeInteger"> <xs:annotation name="final"/> </xs:element> - <!-- Animation time for brightness increase in millis --> - <xs:element name="brightnessIncreaseDurationMillis" type="xs:nonNegativeInteger"> + <!-- Animation speed for brightness increase. In framework brightness units per second. --> + <xs:element name="screenBrightnessRampIncrease" type="nonNegativeDecimal"> <xs:annotation name="final"/> </xs:element> - <!-- Animation time for brightness decrease in millis --> - <xs:element name="brightnessDecreaseDurationMillis" type="xs:nonNegativeInteger"> + <!-- Animation speed for brightness decrease. In framework brightness units per second. --> + <xs:element name="screenBrightnessRampDecrease" type="nonNegativeDecimal"> <xs:annotation name="final"/> </xs:element> </xs:complexType> diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt index 2d27f0c7966082bb94e29736396fbd728e0889a8..f7e004375071aee24d80c3bd7b1d8d45d62bcc63 100644 --- a/services/core/xsd/display-device-config/schema/current.txt +++ b/services/core/xsd/display-device-config/schema/current.txt @@ -179,15 +179,15 @@ package com.android.server.display.config { public class HdrBrightnessConfig { ctor public HdrBrightnessConfig(); method public final java.math.BigInteger getBrightnessDecreaseDebounceMillis(); - method public final java.math.BigInteger getBrightnessDecreaseDurationMillis(); method public final java.math.BigInteger getBrightnessIncreaseDebounceMillis(); - method public final java.math.BigInteger getBrightnessIncreaseDurationMillis(); method @NonNull public final com.android.server.display.config.NonNegativeFloatToFloatMap getBrightnessMap(); + method public final java.math.BigDecimal getScreenBrightnessRampDecrease(); + method public final java.math.BigDecimal getScreenBrightnessRampIncrease(); method public final void setBrightnessDecreaseDebounceMillis(java.math.BigInteger); - method public final void setBrightnessDecreaseDurationMillis(java.math.BigInteger); method public final void setBrightnessIncreaseDebounceMillis(java.math.BigInteger); - method public final void setBrightnessIncreaseDurationMillis(java.math.BigInteger); method public final void setBrightnessMap(@NonNull com.android.server.display.config.NonNegativeFloatToFloatMap); + method public final void setScreenBrightnessRampDecrease(java.math.BigDecimal); + method public final void setScreenBrightnessRampIncrease(java.math.BigDecimal); } public class HighBrightnessMode { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java index 25e8475fcf4243d7f1f68136ac7ea43308bbf8aa..922f69c1e816fea77cc93c1eb76cccd8179d3027 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java @@ -40,6 +40,7 @@ import android.app.admin.PolicyUpdateReceiver; import android.app.admin.PolicyValue; import android.app.admin.TargetUser; import android.app.admin.UserRestrictionPolicyKey; +import android.app.admin.flags.FlagUtils; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -65,7 +66,6 @@ import android.util.Xml; import com.android.internal.util.XmlUtils; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; -import com.android.server.devicepolicy.flags.FlagUtils; import com.android.server.utils.Slogf; import libcore.io.IoUtils; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 5a620a3b87f53649b35054a6a13f715bfef5694c..8509155861f5c3fee2414ff8bea0d8d116e8a54d 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -330,6 +330,7 @@ import android.app.admin.SystemUpdatePolicy; import android.app.admin.UnsafeStateException; import android.app.admin.UserRestrictionPolicyKey; import android.app.admin.WifiSsidPolicy; +import android.app.admin.flags.FlagUtils; import android.app.backup.IBackupManager; import android.app.compat.CompatChanges; import android.app.role.OnRoleHoldersChangedListener; @@ -490,7 +491,6 @@ import com.android.server.SystemServerInitThreadPool; import com.android.server.SystemService; import com.android.server.SystemServiceManager; import com.android.server.devicepolicy.ActiveAdmin.TrustAgentInfo; -import com.android.server.devicepolicy.flags.FlagUtils; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.net.NetworkPolicyManagerInternal; import com.android.server.pdb.PersistentDataBlockManagerInternal; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/flags/Android.bp b/services/devicepolicy/java/com/android/server/devicepolicy/flags/Android.bp deleted file mode 100644 index 1a45782ccd39a56075d38d1838cbfe65b58f4460..0000000000000000000000000000000000000000 --- a/services/devicepolicy/java/com/android/server/devicepolicy/flags/Android.bp +++ /dev/null @@ -1,16 +0,0 @@ -package { - default_applicable_licenses: ["Android-Apache-2.0"], -} - -aconfig_declarations { - name: "device_policy_aconfig_flags", - package: "com.android.server.devicepolicy.flags", - srcs: [ - "flags.aconfig", - ], -} - -java_aconfig_library { - name: "device_policy_aconfig_flags_lib", - aconfig_declarations: "device_policy_aconfig_flags", -} diff --git a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt index f3ac7d55c5db7c726dae1616243470ab047b7791..12cd0f6e1a7c28b83c32d5b0ff2421c1306c2e31 100644 --- a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt +++ b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt @@ -143,8 +143,8 @@ class PackageManagerComponentLabelIconOverrideTest { val result: Result, val componentName: ComponentName? = ComponentName(pkgName, COMPONENT_CLASS_NAME) ) { - constructor(pkgName: String, appType: AppType, exception: Class<out Exception>) - : this(pkgName, appType, Result.Exception(exception)) + constructor(pkgName: String, appType: AppType, exception: Class<out Exception>) : + this(pkgName, appType, Result.Exception(exception)) val expectedLabel = when (result) { Result.Changed, Result.ChangedWithoutNotify, Result.NotChanged -> TEST_LABEL @@ -299,11 +299,9 @@ class PackageManagerComponentLabelIconOverrideTest { .hideAsFinal() private fun makePkgSetting(pkgName: String, pkg: AndroidPackageInternal) = - PackageSetting( - pkgName, null, File("/test"), - null, null, null, null, 0, 0, 0, 0, null, null, null, null, null, - UUID.fromString("3f9d52b7-d7b4-406a-a1da-d9f19984c72c") - ).apply { + PackageSetting(pkgName, null, File("/test"), 0, 0, + UUID.fromString("3f9d52b7-d7b4-406a-a1da-d9f19984c72c")) + .apply { if (params.isSystem) { this.flags = this.flags or ApplicationInfo.FLAG_SYSTEM } @@ -373,7 +371,7 @@ class PackageManagerComponentLabelIconOverrideTest { whenever(this.isCallerRecents(anyInt())) { false } } val mockAppsFilter: AppsFilterImpl = mockThrowOnUnmocked { - whenever(this.shouldFilterApplication(any<PackageDataSnapshot>(), anyInt(), + whenever(this.shouldFilterApplication(any<PackageDataSnapshot>(), anyInt(), any<PackageSetting>(), any<PackageSetting>(), anyInt())) { false } whenever(this.snapshot()) { this@mockThrowOnUnmocked } whenever(registerObserver(any())).thenCallRealMethod() diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java index cbedcaf97358379793f6214f4e398859db32ed2c..aaad669d5b8daafa1ff754579e68ea640a386096 100644 --- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java +++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java @@ -967,20 +967,12 @@ public class PackageManagerSettingsTests { PACKAGE_NAME, REAL_PACKAGE_NAME, INITIAL_CODE_PATH /*codePath*/, - null /*legacyNativeLibraryPathString*/, - "x86_64" /*primaryCpuAbiString*/, - "x86" /*secondaryCpuAbiString*/, - null /*cpuAbiOverrideString*/, - INITIAL_VERSION_CODE, ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_HAS_CODE, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED|ApplicationInfo.PRIVATE_FLAG_HIDDEN, - 0, - null /*usesSdkLibraries*/, - null /*usesSdkLibrariesVersions*/, - null /*usesStaticLibraries*/, - null /*usesStaticLibrariesVersions*/, - null /*mimeGroups*/, - UUID.randomUUID()); + UUID.randomUUID()) + .setPrimaryCpuAbi("x86_64") + .setSecondaryCpuAbi("x86") + .setLongVersionCode(INITIAL_VERSION_CODE); origPkgSetting01.setPkg(mockAndroidPackage(origPkgSetting01)); final PackageSetting testPkgSetting01 = new PackageSetting(origPkgSetting01); verifySettingCopy(origPkgSetting01, testPkgSetting01); @@ -989,23 +981,15 @@ public class PackageManagerSettingsTests { @Test public void testPackageStateCopy02() { final PackageSetting origPkgSetting01 = new PackageSetting( - PACKAGE_NAME /*pkgName*/, - REAL_PACKAGE_NAME /*realPkgName*/, + PACKAGE_NAME, + REAL_PACKAGE_NAME, INITIAL_CODE_PATH /*codePath*/, - null /*legacyNativeLibraryPathString*/, - "x86_64" /*primaryCpuAbiString*/, - "x86" /*secondaryCpuAbiString*/, - null /*cpuAbiOverrideString*/, - INITIAL_VERSION_CODE, ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_HAS_CODE, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED|ApplicationInfo.PRIVATE_FLAG_HIDDEN, - 0, - null /*usesSdkLibraries*/, - null /*usesSdkLibrariesVersions*/, - null /*usesStaticLibraries*/, - null /*usesStaticLibrariesVersions*/, - null /*mimeGroups*/, - UUID.randomUUID()); + UUID.randomUUID()) + .setPrimaryCpuAbi("x86_64") + .setSecondaryCpuAbi("x86") + .setLongVersionCode(INITIAL_VERSION_CODE); origPkgSetting01.setUserState(0, 100, 100, 1, true, false, false, false, 0, null, false, false, "lastDisabledCaller", new ArraySet<>(new String[]{"enabledComponent1"}), new ArraySet<>(new String[]{"disabledComponent1"}), 0, 0, "harmfulAppWarning", @@ -1028,20 +1012,10 @@ public class PackageManagerSettingsTests { PACKAGE_NAME /*pkgName*/, REAL_PACKAGE_NAME /*realPkgName*/, UPDATED_CODE_PATH /*codePath*/, - null /*legacyNativeLibraryPathString*/, - null /*primaryCpuAbiString*/, - null /*secondaryCpuAbiString*/, - null /*cpuAbiOverrideString*/, - UPDATED_VERSION_CODE, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, - 0, - null /*usesSdkLibraries*/, - null /*usesSdkLibrariesVersions*/, - null /*usesStaticLibraries*/, - null /*usesStaticLibrariesVersions*/, - null /*mimeGroups*/, - UUID.randomUUID()); + UUID.randomUUID()) + .setLongVersionCode(UPDATED_VERSION_CODE); testPkgSetting01.copyPackageSetting(origPkgSetting01, true); verifySettingCopy(origPkgSetting01, testPkgSetting01); verifyUserStatesCopy(origPkgSetting01.readUserState(0), @@ -1717,20 +1691,13 @@ public class PackageManagerSettingsTests { PACKAGE_NAME, REAL_PACKAGE_NAME, INITIAL_CODE_PATH /*codePath*/, - null /*legacyNativeLibraryPathString*/, - "x86_64" /*primaryCpuAbiString*/, - "x86" /*secondaryCpuAbiString*/, - null /*cpuAbiOverrideString*/, - INITIAL_VERSION_CODE, pkgFlags, 0 /*privateFlags*/, - sharedUserId, - null /*usesSdkLibraries*/, - null /*usesSdkLibrariesVersions*/, - null /*usesStaticLibraries*/, - null /*usesStaticLibrariesVersions*/, - null /*mimeGroups*/, - UUID.randomUUID()); + UUID.randomUUID()) + .setPrimaryCpuAbi("x86_64") + .setSecondaryCpuAbi("x86") + .setLongVersionCode(INITIAL_VERSION_CODE) + .setSharedUserAppId(sharedUserId); } private PackageSetting createPackageSetting(String packageName) { @@ -1738,20 +1705,12 @@ public class PackageManagerSettingsTests { packageName, packageName, INITIAL_CODE_PATH /*codePath*/, - null /*legacyNativeLibraryPathString*/, - "x86_64" /*primaryCpuAbiString*/, - "x86" /*secondaryCpuAbiString*/, - null /*cpuAbiOverrideString*/, - INITIAL_VERSION_CODE, 0, 0 /*privateFlags*/, - 0, - null /*usesSdkLibraries*/, - null /*usesSdkLibrariesVersions*/, - null /*usesStaticLibraries*/, - null /*usesStaticLibrariesVersions*/, - null /*mimeGroups*/, - UUID.randomUUID()); + UUID.randomUUID()) + .setPrimaryCpuAbi("x86_64") + .setSecondaryCpuAbi("x86") + .setLongVersionCode(INITIAL_VERSION_CODE); } static @NonNull List<UserInfo> createFakeUsers() { diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java index c37d21ae1cc05de3114a19f15cc1bca15482f261..179a9d5f748ea31ef06f9003fe0dbf879c0906a7 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java @@ -570,9 +570,9 @@ public final class DisplayDeviceConfigTest { assertNotNull(data); assertEquals(2, data.mMaxBrightnessLimits.size()); assertEquals(13000, data.mBrightnessDecreaseDebounceMillis); - assertEquals(10000, data.mBrightnessDecreaseDurationMillis); + assertEquals(0.1f, data.mScreenBrightnessRampDecrease, SMALL_DELTA); assertEquals(1000, data.mBrightnessIncreaseDebounceMillis); - assertEquals(11000, data.mBrightnessIncreaseDurationMillis); + assertEquals(0.11f, data.mScreenBrightnessRampIncrease, SMALL_DELTA); assertEquals(0.3f, data.mMaxBrightnessLimits.get(500f), SMALL_DELTA); assertEquals(0.6f, data.mMaxBrightnessLimits.get(1200f), SMALL_DELTA); @@ -841,9 +841,9 @@ public final class DisplayDeviceConfigTest { + " </point>\n" + " </brightnessMap>\n" + " <brightnessIncreaseDebounceMillis>1000</brightnessIncreaseDebounceMillis>\n" - + " <brightnessIncreaseDurationMillis>11000</brightnessIncreaseDurationMillis>\n" + + " <screenBrightnessRampIncrease>0.11</screenBrightnessRampIncrease>\n" + " <brightnessDecreaseDebounceMillis>13000</brightnessDecreaseDebounceMillis>\n" - + " <brightnessDecreaseDurationMillis>10000</brightnessDecreaseDurationMillis>\n" + + " <screenBrightnessRampDecrease>0.1</screenBrightnessRampDecrease>\n" + "</hdrBrightnessConfig>"; } diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java index ee187baf524e4b3be3d19fc08bfb715aa275162a..8d8274c61b208e8eca4d01fe8ec74ae5c0a63a7b 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java @@ -56,9 +56,9 @@ public class HdrClamperTest { private static final HdrBrightnessData TEST_HDR_DATA = new HdrBrightnessData( Map.of(500f, 0.6f), /* brightnessIncreaseDebounceMillis= */ 1000, - /* brightnessIncreaseDurationMillis= */ 2000, + /* screenBrightnessRampIncrease= */ 0.02f, /* brightnessDecreaseDebounceMillis= */ 3000, - /* brightnessDecreaseDurationMillis= */4000 + /* screenBrightnessRampDecrease= */0.04f ); private static final int WIDTH = 600; @@ -152,8 +152,7 @@ public class HdrClamperTest { mClock.fastForward(3000); mTestHandler.timeAdvance(); assertEquals(0.6f, mHdrClamper.getMaxBrightness(), FLOAT_TOLERANCE); - // 0.6 to HLG = 0.905727, rate = (1-0.905727) / 4 - assertEquals(0.023568f, mHdrClamper.getTransitionRate(), FLOAT_TOLERANCE); + assertEquals(0.04, mHdrClamper.getTransitionRate(), FLOAT_TOLERANCE); } @Test @@ -181,8 +180,7 @@ public class HdrClamperTest { mClock.fastForward(1000); mTestHandler.timeAdvance(); assertEquals(PowerManager.BRIGHTNESS_MAX, mHdrClamper.getMaxBrightness(), FLOAT_TOLERANCE); - // 0.6 to HLG = 0.905727, rate = (1-0.905727) / 2 - assertEquals(0.047137f, mHdrClamper.getTransitionRate(), FLOAT_TOLERANCE); + assertEquals(0.02f, mHdrClamper.getTransitionRate(), FLOAT_TOLERANCE); } @Test @@ -209,8 +207,7 @@ public class HdrClamperTest { mClock.fastForward(3000); mTestHandler.timeAdvance(); assertEquals(0.6f, mHdrClamper.getMaxBrightness(), FLOAT_TOLERANCE); - // 0.6 to HLG = 0.905727, rate = (1-0.905727) / 4 - assertEquals(0.023568f, mHdrClamper.getTransitionRate(), FLOAT_TOLERANCE); + assertEquals(0.04f, mHdrClamper.getTransitionRate(), FLOAT_TOLERANCE); } // MsgInfo.sendTime is calculated first by adding SystemClock.uptimeMillis() diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt index 2f6859c14742ad7090496e757348279609e94d47..be33b1b6f34fc272572fd4e7ded53972aeb2f2b1 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt +++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt @@ -165,8 +165,7 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) { null } whenever(mocks.settings.addPackageLPw(nullable(), nullable(), nullable(), nullable(), - nullable(), nullable(), nullable(), nullable(), nullable(), nullable(), nullable(), - nullable(), nullable(), nullable(), nullable(), nullable(), nullable())) { + nullable(), nullable(), nullable())) { val name: String = getArgument(0) val pendingAdd = mPendingPackageAdds.firstOrNull { it.first == name } ?: return@whenever null diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java index 37a6d22f038beb14051660f3cd3b39209838349d..eca19c8e8c4d6724c6518fa7922953d684c0c2ae 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java @@ -255,7 +255,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { public void testUnlockUserKeyIfUnsecuredPassesPrimaryUserAuthSecret() throws RemoteException { initSpAndSetCredential(PRIMARY_USER_ID, newPassword(null)); reset(mAuthSecretService); - mLocalService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID); + mService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID); verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class)); } @@ -267,7 +267,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { mService.setLockCredential(nonePassword(), password, PRIMARY_USER_ID); reset(mAuthSecretService); - mLocalService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID); + mService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID); verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class)); } @@ -285,39 +285,39 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { @Test public void testHeadlessSystemUserDoesNotPassAuthSecret() throws RemoteException { setupHeadlessTest(); - mLocalService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID); + mService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID); verify(mAuthSecretService, never()).setPrimaryUserCredential(any(byte[].class)); } @Test public void testHeadlessSecondaryUserPassesAuthSecret() throws RemoteException { setupHeadlessTest(); - mLocalService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID); + mService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID); verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class)); } @Test public void testHeadlessTertiaryUserPassesSameAuthSecret() throws RemoteException { setupHeadlessTest(); - mLocalService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID); + mService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID); var captor = ArgumentCaptor.forClass(byte[].class); verify(mAuthSecretService).setPrimaryUserCredential(captor.capture()); var value = captor.getValue(); reset(mAuthSecretService); - mLocalService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID); + mService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID); verify(mAuthSecretService).setPrimaryUserCredential(eq(value)); } @Test public void testHeadlessTertiaryUserPassesSameAuthSecretAfterReset() throws RemoteException { setupHeadlessTest(); - mLocalService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID); + mService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID); var captor = ArgumentCaptor.forClass(byte[].class); verify(mAuthSecretService).setPrimaryUserCredential(captor.capture()); var value = captor.getValue(); mService.clearAuthSecret(); reset(mAuthSecretService); - mLocalService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID); + mService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID); verify(mAuthSecretService).setPrimaryUserCredential(eq(value)); } diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java index 42be3d36620af52896899507fe556f442350ae32..5d6f36c005b4e35f5e256134a4a2fe869b73b022 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java @@ -19,7 +19,6 @@ package com.android.server.pm; import android.content.pm.SigningDetails; import android.util.SparseArray; -import com.android.server.pm.parsing.pkg.ParsedPackage; import com.android.server.pm.pkg.AndroidPackage; import com.android.server.pm.pkg.PackageUserStateImpl; @@ -159,17 +158,19 @@ public class PackageSettingBuilder { public PackageSetting build() { final PackageSetting packageSetting = new PackageSetting(mName, mRealName, - new File(mCodePath), mLegacyNativeLibraryPathString, mPrimaryCpuAbiString, - mSecondaryCpuAbiString, mCpuAbiOverrideString, mPVersionCode, mPkgFlags, - mPrivateFlags, mSharedUserId, null /* usesSdkLibraries */, - null /* usesSdkLibrariesVersions */, null /* usesStaticLibraries */, - null /* usesStaticLibrariesVersions */, mMimeGroups, mDomainSetId); - packageSetting.setSignatures(mSigningDetails != null - ? new PackageSignatures(mSigningDetails) - : new PackageSignatures()); - packageSetting.setPkg((ParsedPackage) mPkg); - packageSetting.setAppId(mAppId); - packageSetting.setVolumeUuid(this.mVolumeUuid); + new File(mCodePath), mPkgFlags, mPrivateFlags, mDomainSetId) + .setLegacyNativeLibraryPath(mLegacyNativeLibraryPathString) + .setPrimaryCpuAbi(mPrimaryCpuAbiString) + .setSecondaryCpuAbi(mSecondaryCpuAbiString) + .setCpuAbiOverride(mCpuAbiOverrideString) + .setLongVersionCode(mPVersionCode) + .setSharedUserAppId(mSharedUserId) + .setMimeGroups(mMimeGroups) + .setSignatures(mSigningDetails != null + ? new PackageSignatures(mSigningDetails) : new PackageSignatures()) + .setPkg(mPkg) + .setAppId(mAppId) + .setVolumeUuid(this.mVolumeUuid); if (mInstallSource != null) { packageSetting.setInstallSource(mInstallSource); } diff --git a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java index 75a8dd822914b6c3266ce713f8ae4bbca3e55fb1..085eddd2e73d808459a108441919d98fe7e8ef8d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.platform.test.annotations.Presubmit; @@ -94,10 +95,14 @@ public class UnknownAppVisibilityControllerTest extends WindowTestsBase { public void testRemoveFinishingInvisibleActivityFromUnknown() { final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build(); mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity); - activity.finishing = true; - activity.setVisibleRequested(true); - activity.setVisibility(false); + assertFalse(mDisplayContent.mUnknownAppVisibilityController.allResolved()); + activity.makeFinishingLocked(); assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved()); + + mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(activity); + assertTrue(mDisplayContent.mUnknownAppVisibilityController.isVisibilityUnknown(activity)); + activity.setState(ActivityRecord.State.STOPPED, "test"); + assertFalse(mDisplayContent.mUnknownAppVisibilityController.isVisibilityUnknown(activity)); } @Test