diff options
29 files changed, 431 insertions, 71 deletions
diff --git a/Android.bp b/Android.bp index 65ec01592fce..d4b63c427778 100644 --- a/Android.bp +++ b/Android.bp @@ -479,8 +479,6 @@ java_library { lint: { baseline_filename: "lint-baseline.xml", }, - // For jarjar repackaging - jarjar_prefix: "com.android.internal.hidden_from_bootclasspath", } java_library { @@ -511,6 +509,7 @@ java_library { lint: { baseline_filename: "lint-baseline.xml", }, + jarjar_prefix: "com.android.internal.hidden_from_bootclasspath", } java_library { diff --git a/core/api/current.txt b/core/api/current.txt index 8f5374c9dbc6..de2b41c602d2 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -193,7 +193,7 @@ package android { field public static final String MANAGE_DEVICE_POLICY_SYSTEM_APPS = "android.permission.MANAGE_DEVICE_POLICY_SYSTEM_APPS"; field public static final String MANAGE_DEVICE_POLICY_SYSTEM_DIALOGS = "android.permission.MANAGE_DEVICE_POLICY_SYSTEM_DIALOGS"; field public static final String MANAGE_DEVICE_POLICY_SYSTEM_UPDATES = "android.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES"; - field @FlaggedApi("com.android.net.thread.flags.thread_user_restriction_enabled") public static final String MANAGE_DEVICE_POLICY_THREAD_NETWORK = "android.permission.MANAGE_DEVICE_POLICY_THREAD_NETWORK"; + field @FlaggedApi("com.android.net.thread.platform.flags.thread_user_restriction_enabled") public static final String MANAGE_DEVICE_POLICY_THREAD_NETWORK = "android.permission.MANAGE_DEVICE_POLICY_THREAD_NETWORK"; field public static final String MANAGE_DEVICE_POLICY_TIME = "android.permission.MANAGE_DEVICE_POLICY_TIME"; field public static final String MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING = "android.permission.MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING"; field public static final String MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER = "android.permission.MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER"; @@ -12739,7 +12739,7 @@ package android.content.pm { field public static final String FEATURE_TELEPHONY_RADIO_ACCESS = "android.hardware.telephony.radio.access"; field public static final String FEATURE_TELEPHONY_SUBSCRIPTION = "android.hardware.telephony.subscription"; field @Deprecated public static final String FEATURE_TELEVISION = "android.hardware.type.television"; - field @FlaggedApi("com.android.net.thread.flags.thread_enabled_platform") public static final String FEATURE_THREAD_NETWORK = "android.hardware.thread_network"; + field @FlaggedApi("com.android.net.thread.platform.flags.thread_enabled_platform") public static final String FEATURE_THREAD_NETWORK = "android.hardware.thread_network"; field public static final String FEATURE_TOUCHSCREEN = "android.hardware.touchscreen"; field public static final String FEATURE_TOUCHSCREEN_MULTITOUCH = "android.hardware.touchscreen.multitouch"; field public static final String FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT = "android.hardware.touchscreen.multitouch.distinct"; @@ -33616,7 +33616,7 @@ package android.os { field public static final String DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI = "no_sharing_admin_configured_wifi"; field public static final String DISALLOW_SMS = "no_sms"; field public static final String DISALLOW_SYSTEM_ERROR_DIALOGS = "no_system_error_dialogs"; - field @FlaggedApi("com.android.net.thread.flags.thread_user_restriction_enabled") public static final String DISALLOW_THREAD_NETWORK = "no_thread_network"; + field @FlaggedApi("com.android.net.thread.platform.flags.thread_user_restriction_enabled") public static final String DISALLOW_THREAD_NETWORK = "no_thread_network"; field public static final String DISALLOW_ULTRA_WIDEBAND_RADIO = "no_ultra_wideband_radio"; field public static final String DISALLOW_UNIFIED_PASSWORD = "no_unified_password"; field public static final String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps"; diff --git a/core/api/system-current.txt b/core/api/system-current.txt index eca138b83dbe..194001adf78c 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -357,7 +357,7 @@ package android { field public static final String SYSTEM_APPLICATION_OVERLAY = "android.permission.SYSTEM_APPLICATION_OVERLAY"; field public static final String SYSTEM_CAMERA = "android.permission.SYSTEM_CAMERA"; field public static final String TETHER_PRIVILEGED = "android.permission.TETHER_PRIVILEGED"; - field @FlaggedApi("com.android.net.thread.flags.thread_enabled_platform") public static final String THREAD_NETWORK_PRIVILEGED = "android.permission.THREAD_NETWORK_PRIVILEGED"; + field @FlaggedApi("com.android.net.thread.platform.flags.thread_enabled_platform") public static final String THREAD_NETWORK_PRIVILEGED = "android.permission.THREAD_NETWORK_PRIVILEGED"; field public static final String TIS_EXTENSION_INTERFACE = "android.permission.TIS_EXTENSION_INTERFACE"; field public static final String TOGGLE_AUTOMOTIVE_PROJECTION = "android.permission.TOGGLE_AUTOMOTIVE_PROJECTION"; field public static final String TRIGGER_LOST_MODE = "android.permission.TRIGGER_LOST_MODE"; @@ -3482,7 +3482,7 @@ package android.content { field public static final String SYSTEM_CONFIG_SERVICE = "system_config"; field public static final String SYSTEM_UPDATE_SERVICE = "system_update"; field public static final String TETHERING_SERVICE = "tethering"; - field @FlaggedApi("com.android.net.thread.flags.thread_enabled_platform") public static final String THREAD_NETWORK_SERVICE = "thread_network"; + field @FlaggedApi("com.android.net.thread.platform.flags.thread_enabled_platform") public static final String THREAD_NETWORK_SERVICE = "thread_network"; field public static final String TIME_MANAGER_SERVICE = "time_manager"; field public static final String TRANSLATION_MANAGER_SERVICE = "translation"; field public static final String UI_TRANSLATION_SERVICE = "ui_translation"; diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index ced35549769a..bd5095809a80 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -7363,6 +7363,7 @@ public class Notification implements Parcelable /** * @hide */ + @SuppressWarnings("HiddenAbstractMethod") public abstract boolean areNotificationsVisiblyDifferent(Style other); /** diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index fa812672839e..6d54223af68a 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -4767,9 +4767,7 @@ public abstract class Context { * @see android.net.thread.ThreadNetworkManager * @hide */ - // TODO (b/325886480): update the flag to - // "com.android.net.thread.platform.flags.Flags.FLAG_THREAD_ENABLED_PLATFORM" - @FlaggedApi("com.android.net.thread.flags.thread_enabled_platform") + @FlaggedApi(com.android.net.thread.platform.flags.Flags.FLAG_THREAD_ENABLED_PLATFORM) @SystemApi public static final String THREAD_NETWORK_SERVICE = "thread_network"; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 1cfdc78f6e2f..92bfcefae4e1 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -3756,9 +3756,7 @@ public abstract class PackageManager { * The device is capable of communicating with other devices via * <a href="https://www.threadgroup.org">Thread</a> networking protocol. */ - // TODO (b/325886480): update the flag to - // "com.android.net.thread.platform.flags.Flags.FLAG_THREAD_ENABLED_PLATFORM" - @FlaggedApi("com.android.net.thread.flags.thread_enabled_platform") + @FlaggedApi(com.android.net.thread.platform.flags.Flags.FLAG_THREAD_ENABLED_PLATFORM) @SdkConstant(SdkConstantType.FEATURE) public static final String FEATURE_THREAD_NETWORK = "android.hardware.thread_network"; diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 0081d5edec07..ca87410ed438 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1867,9 +1867,7 @@ public class UserManager { * @see DevicePolicyManager#clearUserRestriction(ComponentName, String) * @see #getUserRestrictions() */ - // TODO (b/325886480): update the flag to - // "com.android.net.thread.platform.flags.Flags.FLAG_THREAD_USER_RESTRICTION_ENABLED" - @FlaggedApi("com.android.net.thread.flags.thread_user_restriction_enabled") + @FlaggedApi(com.android.net.thread.platform.flags.Flags.FLAG_THREAD_USER_RESTRICTION_ENABLED) public static final String DISALLOW_THREAD_NETWORK = "no_thread_network"; /** diff --git a/core/java/android/os/storage/OWNERS b/core/java/android/os/storage/OWNERS index 5e0a5635d4bd..a26fb6274f55 100644 --- a/core/java/android/os/storage/OWNERS +++ b/core/java/android/os/storage/OWNERS @@ -3,11 +3,15 @@ # Please assign new bugs to android-storage-triage@, not to individual people # Android Storage Team +aibra@google.com +akgaurav@google.com alukin@google.com ankitavyas@google.com dipankarb@google.com gargshivam@google.com +ishneet@google.com krishang@google.com +oeissa@google.com riyaghai@google.com sahanas@google.com shikhamalhotra@google.com diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java index a436e08a0a2d..2eece6d4a454 100644 --- a/core/java/android/view/InputDevice.java +++ b/core/java/android/view/InputDevice.java @@ -69,6 +69,7 @@ public final class InputDevice implements Parcelable { private final String mName; private final int mVendorId; private final int mProductId; + private final int mDeviceBus; private final String mDescriptor; private final InputDeviceIdentifier mIdentifier; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) @@ -468,8 +469,8 @@ public final class InputDevice implements Parcelable { * Called by native code */ private InputDevice(int id, int generation, int controllerNumber, String name, int vendorId, - int productId, String descriptor, boolean isExternal, int sources, int keyboardType, - KeyCharacterMap keyCharacterMap, @Nullable String keyboardLanguageTag, + int productId, int deviceBus, String descriptor, boolean isExternal, int sources, + int keyboardType, KeyCharacterMap keyCharacterMap, @Nullable String keyboardLanguageTag, @Nullable String keyboardLayoutType, boolean hasVibrator, boolean hasMicrophone, boolean hasButtonUnderPad, boolean hasSensor, boolean hasBattery, int usiVersionMajor, int usiVersionMinor, int associatedDisplayId) { @@ -479,6 +480,7 @@ public final class InputDevice implements Parcelable { mName = name; mVendorId = vendorId; mProductId = productId; + mDeviceBus = deviceBus; mDescriptor = descriptor; mIsExternal = isExternal; mSources = sources; @@ -512,6 +514,7 @@ public final class InputDevice implements Parcelable { mName = in.readString(); mVendorId = in.readInt(); mProductId = in.readInt(); + mDeviceBus = in.readInt(); mDescriptor = in.readString(); mIsExternal = in.readInt() != 0; mSources = in.readInt(); @@ -551,6 +554,7 @@ public final class InputDevice implements Parcelable { private String mName = ""; private int mVendorId = 0; private int mProductId = 0; + private int mDeviceBus = 0; private String mDescriptor = ""; private boolean mIsExternal = false; private int mSources = 0; @@ -604,6 +608,12 @@ public final class InputDevice implements Parcelable { return this; } + /** @see InputDevice#getDeviceBus() */ + public Builder setDeviceBus(int deviceBus) { + mDeviceBus = deviceBus; + return this; + } + /** @see InputDevice#getDescriptor() */ public Builder setDescriptor(String descriptor) { mDescriptor = descriptor; @@ -705,6 +715,7 @@ public final class InputDevice implements Parcelable { mName, mVendorId, mProductId, + mDeviceBus, mDescriptor, mIsExternal, mSources, @@ -846,6 +857,21 @@ public final class InputDevice implements Parcelable { } /** + * Gets the device bus used by given device, if available. + * <p> + * The device bus is the communication system used for transferring data + * (e.g. USB, Bluetooth etc.). This value comes from the kernel (from input.h). + * A value of 0 will be assigned where the device bus is not available. + * </p> + * + * @return The device bus of a given device + * @hide + */ + public int getDeviceBus() { + return mDeviceBus; + } + + /** * Gets the input device descriptor, which is a stable identifier for an input device. * <p> * An input device descriptor uniquely identifies an input device. Its value @@ -1444,6 +1470,7 @@ public final class InputDevice implements Parcelable { out.writeString(mName); out.writeInt(mVendorId); out.writeInt(mProductId); + out.writeInt(mDeviceBus); out.writeString(mDescriptor); out.writeInt(mIsExternal ? 1 : 0); out.writeInt(mSources); diff --git a/core/java/android/window/flags/OWNERS b/core/java/android/window/flags/OWNERS index 3fa376003123..fd73d35e00d2 100644 --- a/core/java/android/window/flags/OWNERS +++ b/core/java/android/window/flags/OWNERS @@ -1,2 +1,3 @@ per-file responsible_apis.aconfig = file:/BAL_OWNERS per-file large_screen_experiences_app_compat.aconfig = file:/LSE_APP_COMPAT_OWNERS +per-file accessibility.aconfig = file:/core/java/android/view/accessibility/OWNERS diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp index f97d41b6a122..baea3bc3e04f 100644 --- a/core/jni/android_view_InputDevice.cpp +++ b/core/jni/android_view_InputDevice.cpp @@ -83,7 +83,8 @@ jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& devi deviceInfo.getId(), deviceInfo.getGeneration(), deviceInfo.getControllerNumber(), nameObj.get(), static_cast<int32_t>(ident.vendor), - static_cast<int32_t>(ident.product), descriptorObj.get(), + static_cast<int32_t>(ident.product), + static_cast<int32_t>(ident.bus), descriptorObj.get(), deviceInfo.isExternal(), deviceInfo.getSources(), deviceInfo.getKeyboardType(), kcmObj.get(), keyboardLanguageTagObj.get(), keyboardLayoutTypeObj.get(), @@ -113,7 +114,7 @@ int register_android_view_InputDevice(JNIEnv* env) gInputDeviceClassInfo.clazz = MakeGlobalRefOrDie(env, gInputDeviceClassInfo.clazz); gInputDeviceClassInfo.ctor = GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz, "<init>", - "(IIILjava/lang/String;IILjava/lang/" + "(IIILjava/lang/String;IIILjava/lang/" "String;ZIILandroid/view/KeyCharacterMap;Ljava/" "lang/String;Ljava/lang/String;ZZZZZIII)V"); diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 2a2e9038c27a..cc1649464626 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -1828,7 +1828,7 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, // If this zygote isn't root, it won't be able to create a process group, // since the directory is owned by root. - if (!is_system_server && getuid() == 0) { + if (getuid() == 0) { const int rc = createProcessGroup(uid, getpid()); if (rc != 0) { fail_fn(rc == -EROFS ? CREATE_ERROR("createProcessGroup failed, kernel missing " diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 04a70df6920f..c7324a210128 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2237,7 +2237,7 @@ <!-- @SystemApi @hide Allows changing Thread network state and access to Thread network credentials such as Network Key and PSKc. <p>Not for use by third-party applications. - @FlaggedApi("com.android.net.thread.flags.thread_enabled_platform") --> + @FlaggedApi("com.android.net.thread.platform.flags.thread_enabled_platform") --> <permission android:name="android.permission.THREAD_NETWORK_PRIVILEGED" android:protectionLevel="signature|privileged" /> @@ -3524,7 +3524,7 @@ <!-- Allows an application to set policy related to <a href="https://www.threadgroup.org">Thread</a> network. - @FlaggedApi("com.android.net.thread.flags.thread_user_restriction_enabled") + @FlaggedApi("com.android.net.thread.platform.flags.thread_user_restriction_enabled") --> <permission android:name="android.permission.MANAGE_DEVICE_POLICY_THREAD_NETWORK" android:protectionLevel="internal|role" /> diff --git a/packages/CrashRecovery/framework/Android.bp b/packages/CrashRecovery/framework/Android.bp index c0d93531a1e6..9480327253f4 100644 --- a/packages/CrashRecovery/framework/Android.bp +++ b/packages/CrashRecovery/framework/Android.bp @@ -3,7 +3,7 @@ soong_config_module_type { module_type: "filegroup", config_namespace: "ANDROID", bool_variables: [ - "move_crashrecovery_files", + "crashrecovery_files_in_platform", ], properties: [ "srcs", @@ -12,14 +12,13 @@ soong_config_module_type { platform_filegroup { name: "framework-crashrecovery-sources", - srcs: [ - "java/**/*.java", - "java/**/*.aidl", - ], soong_config_variables: { - // if the flag is enabled, then files would be moved to module - move_crashrecovery_files: { - srcs: [], + // if this flag is enabled, then files are part of platform + crashrecovery_files_in_platform: { + srcs: [ + "java/**/*.java", + "java/**/*.aidl", + ], }, }, path: "java", @@ -31,7 +30,7 @@ soong_config_module_type { module_type: "filegroup", config_namespace: "ANDROID", bool_variables: [ - "move_crashrecovery_files", + "crashrecovery_files_in_module", ], properties: [ "srcs", @@ -40,10 +39,9 @@ soong_config_module_type { module_filegroup { name: "framework-crashrecovery-module-sources", - srcs: [], soong_config_variables: { - // if the flag is enabled, then files would be moved to module - move_crashrecovery_files: { + // if this flag is enabled, then files are part of module + crashrecovery_files_in_module: { srcs: [ "java/**/*.java", "java/**/*.aidl", diff --git a/packages/CrashRecovery/services/Android.bp b/packages/CrashRecovery/services/Android.bp index ab10b5a23676..961b41f4a633 100644 --- a/packages/CrashRecovery/services/Android.bp +++ b/packages/CrashRecovery/services/Android.bp @@ -3,7 +3,7 @@ soong_config_module_type { module_type: "filegroup", config_namespace: "ANDROID", bool_variables: [ - "move_crashrecovery_files", + "crashrecovery_files_in_platform", ], properties: [ "srcs", @@ -12,15 +12,14 @@ soong_config_module_type { platform_filegroup { name: "services-crashrecovery-sources", - srcs: [ - "java/**/*.java", - "java/**/*.aidl", - ":statslog-crashrecovery-java-gen", - ], soong_config_variables: { - // if the flag is enabled, then files would be moved to module - move_crashrecovery_files: { - srcs: [], + // if this flag is enabled, then files are part of platform + crashrecovery_files_in_platform: { + srcs: [ + "java/**/*.java", + "java/**/*.aidl", + ":statslog-crashrecovery-java-gen", + ], }, }, visibility: ["//frameworks/base:__subpackages__"], @@ -31,7 +30,7 @@ soong_config_module_type { module_type: "filegroup", config_namespace: "ANDROID", bool_variables: [ - "move_crashrecovery_files", + "crashrecovery_files_in_module", ], properties: [ "srcs", @@ -40,10 +39,9 @@ soong_config_module_type { module_filegroup { name: "services-crashrecovery-module-sources", - srcs: [], soong_config_variables: { - // if the flag is enabled, then files would be moved to module - move_crashrecovery_files: { + // if this flag is enabled, then files are part of module + crashrecovery_files_in_module: { srcs: [ "java/**/*.java", "java/**/*.aidl", diff --git a/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java index ce8fb6568bd5..5d71b7d98fdc 100644 --- a/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java +++ b/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java @@ -38,13 +38,13 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; +import android.util.BackgroundThread; import android.util.LongArrayQueue; import android.util.Slog; import android.util.Xml; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.os.BackgroundThread; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.XmlUtils; import com.android.modules.utils.TypedXmlPullParser; diff --git a/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java index 5fb47dd9b95a..0fb932735ab4 100644 --- a/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java +++ b/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java @@ -75,6 +75,9 @@ final class RollbackPackageHealthObserver implements PackageHealthObserver { private static final int PERSISTENT_MASK = ApplicationInfo.FLAG_PERSISTENT | ApplicationInfo.FLAG_SYSTEM; + private static final String PROP_DISABLE_HIGH_IMPACT_ROLLBACK_FLAG = + "persist.device_config.configuration.disable_high_impact_rollback"; + private final Context mContext; private final Handler mHandler; private final ApexManager mApexManager; @@ -605,6 +608,10 @@ final class RollbackPackageHealthObserver implements PackageHealthObserver { // Apply all available low impact rollbacks. mHandler.post(() -> rollbackAllLowImpact(availableRollbacks, rollbackReason)); } else if (minRollbackImpactLevel == PackageManager.ROLLBACK_USER_IMPACT_HIGH) { + // Check disable_high_impact_rollback device config before performing rollback + if (SystemProperties.getBoolean(PROP_DISABLE_HIGH_IMPACT_ROLLBACK_FLAG, false)) { + return; + } // Rollback one package at a time. If that doesn't resolve the issue, rollback // next with same impact level. mHandler.post(() -> rollbackHighImpact(availableRollbacks, rollbackReason)); @@ -718,7 +725,9 @@ final class RollbackPackageHealthObserver implements PackageHealthObserver { impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_70; break; case PackageManager.ROLLBACK_USER_IMPACT_HIGH: - impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_90; + if (!SystemProperties.getBoolean(PROP_DISABLE_HIGH_IMPACT_ROLLBACK_FLAG, false)) { + impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_90; + } break; default: impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_0; diff --git a/packages/CrashRecovery/services/java/com/android/util/BackgroundThread.java b/packages/CrashRecovery/services/java/com/android/util/BackgroundThread.java new file mode 100644 index 000000000000..a6ae68f62f10 --- /dev/null +++ b/packages/CrashRecovery/services/java/com/android/util/BackgroundThread.java @@ -0,0 +1,103 @@ +/* + * * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import android.annotation.NonNull; +import android.os.Handler; +import android.os.HandlerThread; + +import com.android.internal.annotations.GuardedBy; + +import java.util.concurrent.Executor; + +/** + * Thread for asynchronous event processing. This thread is configured as + * {@link android.os.Process#THREAD_PRIORITY_BACKGROUND}, which means fewer CPU + * resources will be dedicated to it, and it will "have less chance of impacting + * the responsiveness of the user interface." + * <p> + * This thread is best suited for tasks that the user is not actively waiting + * for, or for tasks that the user expects to be executed eventually. + * + * @see com.android.internal.os.BackgroundThread + * + * TODO: b/326916057 depend on modules-utils-backgroundthread instead + * @hide + */ +public final class BackgroundThread extends HandlerThread { + private static final Object sLock = new Object(); + + @GuardedBy("sLock") + private static BackgroundThread sInstance; + @GuardedBy("sLock") + private static Handler sHandler; + @GuardedBy("sLock") + private static HandlerExecutor sHandlerExecutor; + + private BackgroundThread() { + super(BackgroundThread.class.getName(), android.os.Process.THREAD_PRIORITY_BACKGROUND); + } + + @GuardedBy("sLock") + private static void ensureThreadLocked() { + if (sInstance == null) { + sInstance = new BackgroundThread(); + sInstance.start(); + sHandler = new Handler(sInstance.getLooper()); + sHandlerExecutor = new HandlerExecutor(sHandler); + } + } + + /** + * Get the singleton instance of this class. + * + * @return the singleton instance of this class + */ + @NonNull + public static BackgroundThread get() { + synchronized (sLock) { + ensureThreadLocked(); + return sInstance; + } + } + + /** + * Get the singleton {@link Handler} for this class. + * + * @return the singleton {@link Handler} for this class. + */ + @NonNull + public static Handler getHandler() { + synchronized (sLock) { + ensureThreadLocked(); + return sHandler; + } + } + + /** + * Get the singleton {@link Executor} for this class. + * + * @return the singleton {@link Executor} for this class. + */ + @NonNull + public static Executor getExecutor() { + synchronized (sLock) { + ensureThreadLocked(); + return sHandlerExecutor; + } + } +} diff --git a/packages/CrashRecovery/services/java/com/android/util/HandlerExecutor.java b/packages/CrashRecovery/services/java/com/android/util/HandlerExecutor.java new file mode 100644 index 000000000000..948ebcca0263 --- /dev/null +++ b/packages/CrashRecovery/services/java/com/android/util/HandlerExecutor.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import android.annotation.NonNull; +import android.os.Handler; + +import java.util.Objects; +import java.util.concurrent.Executor; +import java.util.concurrent.RejectedExecutionException; + +/** + * An adapter {@link Executor} that posts all executed tasks onto the given + * {@link Handler}. + * + * TODO: b/326916057 depend on modules-utils-backgroundthread instead + * @hide + */ +public class HandlerExecutor implements Executor { + private final Handler mHandler; + + public HandlerExecutor(@NonNull Handler handler) { + mHandler = Objects.requireNonNull(handler); + } + + @Override + public void execute(Runnable command) { + if (!mHandler.post(command)) { + throw new RejectedExecutionException(mHandler + " is shutting down"); + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index 6dbf70754b3b..4a5d84a361ec 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.app.ActivityTaskManager; import android.app.AlarmManager; import android.app.AlarmManager.AlarmClockInfo; +import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.Context; @@ -376,7 +377,7 @@ public class PhoneStatusBarPolicy } @Override - public void onConfigChanged(ZenModeConfig config) { + public void onConsolidatedPolicyChanged(NotificationManager.Policy policy) { updateVolumeZen(); } diff --git a/rs/java/android/renderscript/ScriptC.java b/rs/java/android/renderscript/ScriptC.java index 4a2f3da0eb06..e9f6031e5048 100644 --- a/rs/java/android/renderscript/ScriptC.java +++ b/rs/java/android/renderscript/ScriptC.java @@ -38,12 +38,12 @@ public class ScriptC extends Script { private static final String TAG = "ScriptC"; /** - * In targetSdkVersion 35 and above, Renderscript's ScriptC stops being supported + * In targetSdkVersion 36 and above, Renderscript's ScriptC stops being supported * and an exception is thrown when the class is instantiated. - * In targetSdkVersion 34 and below, Renderscript's ScriptC still works. + * In targetSdkVersion 35 and below, Renderscript's ScriptC still works. */ @ChangeId - @EnabledAfter(targetSdkVersion = 35) + @EnabledAfter(targetSdkVersion = 36) private static final long RENDERSCRIPT_SCRIPTC_DEPRECATION_CHANGE_ID = 297019750L; /** @@ -113,9 +113,9 @@ public class ScriptC extends Script { throw new UnsupportedOperationException(s); } - // Throw an exception if the target API is 35 or above + // Throw an exception if the target API is 36 or above String message = - "ScriptC scripts are not supported when targeting an API Level >= 35. Please refer " + "ScriptC scripts are not supported when targeting an API Level >= 36. Please refer " + "to https://developer.android.com/guide/topics/renderscript/migration-guide " + "for proposed alternatives."; Slog.w(TAG, message); diff --git a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java index 08e597701ea2..8e2484e616ab 100644 --- a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java +++ b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java @@ -369,15 +369,15 @@ public final class KeyboardMetricsCollector { if (inputDevice == null || inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) { return; } - int vendorId = inputDevice.getVendorId(); - int productId = inputDevice.getProductId(); if (keyboardSystemEvent == null) { Slog.w(TAG, "Invalid keyboard event logging, keycode = " + Arrays.toString(keyCodes) + ", modifier state = " + modifierState); return; } FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED, - vendorId, productId, keyboardSystemEvent.getIntValue(), keyCodes, modifierState); + inputDevice.getVendorId(), inputDevice.getProductId(), + keyboardSystemEvent.getIntValue(), keyCodes, modifierState, + inputDevice.getDeviceBus()); if (DEBUG) { Slog.d(TAG, "Logging Keyboard system event: " + keyboardSystemEvent.mName); @@ -402,7 +402,7 @@ public final class KeyboardMetricsCollector { // Push the atom to Statsd FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_CONFIGURED, event.isFirstConfiguration(), event.getVendorId(), event.getProductId(), - proto.getBytes()); + proto.getBytes(), event.getDeviceBus()); if (DEBUG) { Slog.d(TAG, "Logging Keyboard configuration event: " + event); @@ -467,6 +467,10 @@ public final class KeyboardMetricsCollector { return mInputDevice.getProductId(); } + public int getDeviceBus() { + return mInputDevice.getDeviceBus(); + } + public boolean isFirstConfiguration() { return mIsFirstConfiguration; } @@ -479,6 +483,7 @@ public final class KeyboardMetricsCollector { public String toString() { return "InputDevice = {VendorId = " + Integer.toHexString(getVendorId()) + ", ProductId = " + Integer.toHexString(getProductId()) + + ", Device Bus = " + Integer.toHexString(getDeviceBus()) + "}, isFirstConfiguration = " + mIsFirstConfiguration + ", LayoutConfigurations = " + mLayoutConfigurations; } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index c11356b7308e..2fceb5b91bb2 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -728,7 +728,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * Map of uid -> UidStateCallbackInfo objects holding the data received from * {@link IUidObserver#onUidStateChanged(int, int, long, int)} callbacks. In order to avoid * creating a new object for every callback received, we hold onto the object created for each - * uid and reuse it. + * uid and reuse it until the uid stays alive. * * Note that the lock used for accessing this object should not be used for anything else and we * should not be acquiring new locks or doing any heavy work while this lock is held since this @@ -801,6 +801,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { Clock.systemUTC()); } + @VisibleForTesting + UidState getUidStateForTest(int uid) { + synchronized (mUidRulesFirstLock) { + return mUidState.get(uid); + } + } + static class Dependencies { final Context mContext; final NetworkStatsManager mNetworkStatsManager; @@ -1256,6 +1263,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } @Override public void onUidGone(int uid, boolean disabled) { + synchronized (mUidStateCallbackInfos) { + mUidStateCallbackInfos.remove(uid); + } + // TODO: b/327058756 - Remove any pending UID_MSG_STATE_CHANGED on the handler. mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget(); } }; @@ -5899,7 +5910,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { void handleUidGone(int uid) { Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone"); try { - boolean updated; + final boolean updated; synchronized (mUidRulesFirstLock) { updated = removeUidStateUL(uid); } diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java b/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java index d6e246fc7ee1..6e416857abbf 100644 --- a/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java @@ -25,6 +25,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -42,6 +44,7 @@ import android.content.rollback.RollbackManager; import android.crashrecovery.flags.Flags; import android.os.Handler; import android.os.MessageQueue; +import android.os.SystemProperties; import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.runner.AndroidJUnit4; @@ -65,6 +68,7 @@ import org.mockito.quality.Strictness; import org.mockito.stubbing.Answer; import java.time.Duration; +import java.util.HashMap; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -90,7 +94,7 @@ public class RollbackPackageHealthObserverTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - + private HashMap<String, String> mSystemSettingsMap; private MockitoSession mSession; private static final String APP_A = "com.package.a"; private static final String APP_B = "com.package.b"; @@ -99,6 +103,9 @@ public class RollbackPackageHealthObserverTest { private static final long VERSION_CODE_2 = 2L; private static final String LOG_TAG = "RollbackPackageHealthObserverTest"; + private static final String PROP_DISABLE_HIGH_IMPACT_ROLLBACK_FLAG = + "persist.device_config.configuration.disable_high_impact_rollback"; + private SystemConfig mSysConfig; @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder(); @@ -111,11 +118,34 @@ public class RollbackPackageHealthObserverTest { .initMocks(this) .strictness(Strictness.LENIENT) .spyStatic(PackageWatchdog.class) + .spyStatic(SystemProperties.class) .startMocking(); + mSystemSettingsMap = new HashMap<>(); // Mock PackageWatchdog doAnswer((Answer<PackageWatchdog>) invocationOnMock -> mMockPackageWatchdog) .when(() -> PackageWatchdog.getInstance(mMockContext)); + + // Mock SystemProperties setter and various getters + doAnswer((Answer<Void>) invocationOnMock -> { + String key = invocationOnMock.getArgument(0); + String value = invocationOnMock.getArgument(1); + + mSystemSettingsMap.put(key, value); + return null; + } + ).when(() -> SystemProperties.set(anyString(), anyString())); + + doAnswer((Answer<Boolean>) invocationOnMock -> { + String key = invocationOnMock.getArgument(0); + boolean defaultValue = invocationOnMock.getArgument(1); + + String storedValue = mSystemSettingsMap.get(key); + return storedValue == null ? defaultValue : Boolean.parseBoolean(storedValue); + } + ).when(() -> SystemProperties.getBoolean(anyString(), anyBoolean())); + + SystemProperties.set(PROP_DISABLE_HIGH_IMPACT_ROLLBACK_FLAG, Boolean.toString(false)); } @After @@ -609,6 +639,32 @@ public class RollbackPackageHealthObserverTest { observer.onBootLoop(1)); } + @Test + public void onBootLoop_impactLevelHighDisableHighImpactRollback_onePackage() + throws PackageManager.NameNotFoundException { + mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION); + SystemProperties.set(PROP_DISABLE_HIGH_IMPACT_ROLLBACK_FLAG, Boolean.toString(true)); + VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2); + VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE); + PackageRollbackInfo packageRollbackInfo = new PackageRollbackInfo(appAFrom, appATo, + null, null, false, false, + null); + RollbackInfo rollbackInfo1 = new RollbackInfo(1, List.of(packageRollbackInfo), + false, null, 111, + PackageManager.ROLLBACK_USER_IMPACT_HIGH); + RollbackPackageHealthObserver observer = + spy(new RollbackPackageHealthObserver(mMockContext, mApexManager)); + + when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager); + // Make the rollbacks available + when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(rollbackInfo1)); + when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager); + when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null); + + assertEquals(PackageWatchdog.PackageHealthObserverImpact.USER_IMPACT_LEVEL_0, + observer.onBootLoop(1)); + } + /** * When the rollback impact level is manual only return user impact level 0. (User impact level * 0 is ignored by package watchdog) @@ -924,6 +980,50 @@ public class RollbackPackageHealthObserverTest { assertThat(argument.getAllValues()).isEqualTo(List.of(rollbackId2)); } + /** + * Don't roll back if kill switch is enabled. + */ + @Test + public void executeBootLoopMitigation_impactLevelHighKillSwitchTrue_rollbackHigh() + throws PackageManager.NameNotFoundException { + mSetFlagsRule.enableFlags(Flags.FLAG_RECOVERABILITY_DETECTION); + SystemProperties.set(PROP_DISABLE_HIGH_IMPACT_ROLLBACK_FLAG, Boolean.toString(true)); + int rollbackId1 = 1; + VersionedPackage appBFrom = new VersionedPackage(APP_B, VERSION_CODE_2); + VersionedPackage appBTo = new VersionedPackage(APP_B, VERSION_CODE); + PackageRollbackInfo packageRollbackInfoB = new PackageRollbackInfo(appBFrom, appBTo, + null, null , false, false, + null); + RollbackInfo rollbackInfo1 = new RollbackInfo(rollbackId1, List.of(packageRollbackInfoB), + false, null, 111, + PackageManager.ROLLBACK_USER_IMPACT_HIGH); + int rollbackId2 = 2; + VersionedPackage appAFrom = new VersionedPackage(APP_A, VERSION_CODE_2); + VersionedPackage appATo = new VersionedPackage(APP_A, VERSION_CODE); + PackageRollbackInfo packageRollbackInfoA = new PackageRollbackInfo(appAFrom, appATo, + null, null , false, false, + null); + RollbackInfo rollbackInfo2 = new RollbackInfo(rollbackId2, List.of(packageRollbackInfoA), + false, null, 111, + PackageManager.ROLLBACK_USER_IMPACT_HIGH); + RollbackPackageHealthObserver observer = + spy(new RollbackPackageHealthObserver(mMockContext, mApexManager)); + ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class); + + when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager); + // Make the rollbacks available + when(mRollbackManager.getAvailableRollbacks()).thenReturn( + List.of(rollbackInfo1, rollbackInfo2)); + when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager); + when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null); + + observer.executeBootLoopMitigation(1); + waitForIdleHandler(observer.getHandler(), Duration.ofSeconds(10)); + + verify(mRollbackManager, never()).commitRollback( + argument.capture(), any(), any()); + } + private void waitForIdleHandler(Handler handler, Duration timeout) { final MessageQueue queue = handler.getLooper().getQueue(); final CountDownLatch latch = new CountDownLatch(1); diff --git a/services/tests/servicestests/src/com/android/server/input/KeyboardMetricsCollectorTests.kt b/services/tests/servicestests/src/com/android/server/input/KeyboardMetricsCollectorTests.kt index 84af9dd75571..218b7c07b3dc 100644 --- a/services/tests/servicestests/src/com/android/server/input/KeyboardMetricsCollectorTests.kt +++ b/services/tests/servicestests/src/com/android/server/input/KeyboardMetricsCollectorTests.kt @@ -30,6 +30,7 @@ private fun createKeyboard( deviceId: Int, vendorId: Int, productId: Int, + deviceBus: Int, languageTag: String?, layoutType: String? ): InputDevice = @@ -42,6 +43,7 @@ private fun createKeyboard( .setExternal(true) .setVendorId(vendorId) .setProductId(productId) + .setDeviceBus(deviceBus) .setKeyboardLanguageTag(languageTag) .setKeyboardLayoutType(layoutType) .build() @@ -67,6 +69,7 @@ class KeyboardMetricsCollectorTests { const val DEVICE_ID = 1 const val DEFAULT_VENDOR_ID = 123 const val DEFAULT_PRODUCT_ID = 456 + const val DEFAULT_DEVICE_BUS = 789 } @Test @@ -77,6 +80,7 @@ class KeyboardMetricsCollectorTests { DEVICE_ID, DEFAULT_VENDOR_ID, DEFAULT_PRODUCT_ID, + DEFAULT_DEVICE_BUS, null, null ) @@ -92,6 +96,7 @@ class KeyboardMetricsCollectorTests { DEVICE_ID, DEFAULT_VENDOR_ID, DEFAULT_PRODUCT_ID, + DEFAULT_DEVICE_BUS, null, null ) @@ -107,6 +112,7 @@ class KeyboardMetricsCollectorTests { DEVICE_ID, DEFAULT_VENDOR_ID, DEFAULT_PRODUCT_ID, + DEFAULT_DEVICE_BUS, "de-CH", "qwertz" ) @@ -135,6 +141,11 @@ class KeyboardMetricsCollectorTests { DEFAULT_PRODUCT_ID, event.productId ) + assertEquals( + "KeyboardConfigurationEvent should pick device bus from provided InputDevice", + DEFAULT_DEVICE_BUS, + event.deviceBus + ) assertTrue(event.isFirstConfiguration) assertEquals( @@ -178,6 +189,7 @@ class KeyboardMetricsCollectorTests { DEVICE_ID, DEFAULT_VENDOR_ID, DEFAULT_PRODUCT_ID, + DEFAULT_DEVICE_BUS, "und", // Undefined language tag "azerty" ) diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java index a529382bfb26..b1e62f9c9a82 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -149,6 +149,7 @@ import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkPolicy; +import android.net.NetworkPolicyManager; import android.net.NetworkStateSnapshot; import android.net.NetworkTemplate; import android.net.TelephonyNetworkSpecifier; @@ -1620,6 +1621,12 @@ public class NetworkPolicyManagerServiceTest { verify(mActivityManagerInternal).notifyNetworkPolicyRulesUpdated(UID_A, procStateSeq); } + private void callAndWaitOnUidGone(int uid) throws Exception { + // The disabled argument is used only for ephemeral apps and does not matter here. + mUidObserver.onUidGone(uid, false /* disabled */); + waitForUidEventHandlerIdle(); + } + private void callAndWaitOnUidStateChanged(int uid, int procState, long procStateSeq) throws Exception { callAndWaitOnUidStateChanged(uid, procState, procStateSeq, @@ -2250,6 +2257,15 @@ public class NetworkPolicyManagerServiceTest { assertTrue(mService.isUidNetworkingBlocked(UID_A, false)); } + private boolean isUidState(int uid, int procState, int procStateSeq, int capability) { + final NetworkPolicyManager.UidState uidState = mService.getUidStateForTest(uid); + if (uidState == null) { + return false; + } + return uidState.uid == uid && uidState.procStateSeq == procStateSeq + && uidState.procState == procState && uidState.capability == capability; + } + @Ignore("Temporarily disabled until the feature is enabled") @Test @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE) @@ -2371,6 +2387,31 @@ public class NetworkPolicyManagerServiceTest { } @Test + public void testUidStateChangeAfterUidGone() throws Exception { + final int testProcStateSeq = 51; + final int testProcState = PROCESS_STATE_IMPORTANT_FOREGROUND; + + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // First callback for uid. + callOnUidStatechanged(UID_B, testProcState, testProcStateSeq, PROCESS_CAPABILITY_NONE); + assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + assertTrue(isUidState(UID_B, testProcState, testProcStateSeq, PROCESS_CAPABILITY_NONE)); + + callAndWaitOnUidGone(UID_B); + try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) { + // Even though the procState is the same, the uid had exited - so this should be + // processed as a fresh callback. + callOnUidStatechanged(UID_B, testProcState, testProcStateSeq + 1, + PROCESS_CAPABILITY_NONE); + assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED)); + } + waitForUidEventHandlerIdle(); + assertTrue(isUidState(UID_B, testProcState, testProcStateSeq + 1, PROCESS_CAPABILITY_NONE)); + } + + @Test public void testLowPowerStandbyAllowlist() throws Exception { // Chain background is also enabled but these procstates are important enough to be exempt. callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_TOP, 0); diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java index feca3268a95c..84925f933c5f 100644 --- a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java +++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java @@ -38,6 +38,7 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase { private static final int VENDOR_ID = 0x123; private static final int PRODUCT_ID = 0x456; + private static final int DEVICE_BUS = 0x789; private static final int META_KEY = KeyEvent.KEYCODE_META_LEFT; private static final int META_ON = MODIFIER.get(KeyEvent.KEYCODE_META_LEFT); private static final int ALT_KEY = KeyEvent.KEYCODE_ALT_LEFT; @@ -224,7 +225,7 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase { @Override public void setUp() { super.setUp(); - mPhoneWindowManager.overrideKeyEventSource(VENDOR_ID, PRODUCT_ID); + mPhoneWindowManager.overrideKeyEventSource(VENDOR_ID, PRODUCT_ID, DEVICE_BUS); mPhoneWindowManager.overrideLaunchHome(); mPhoneWindowManager.overrideSearchKeyBehavior( PhoneWindowManager.SEARCH_BEHAVIOR_TARGET_ACTIVITY); @@ -240,6 +241,7 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase { int expectedKey, int expectedModifierState) { sendKeyCombination(testKeys, 0); mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent, - expectedKey, expectedModifierState, "Failed while executing " + testName); + expectedKey, expectedModifierState, DEVICE_BUS, + "Failed while executing " + testName); } } diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java index 186676772a6a..9aaf291a82ba 100644 --- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java +++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java @@ -423,10 +423,15 @@ class TestPhoneWindowManager { doReturn(isShowing).when(mKeyguardServiceDelegate).isShowing(); } - void overrideKeyEventSource(int vendorId, int productId) { - InputDevice device = new InputDevice.Builder().setId(1).setVendorId(vendorId).setProductId( - productId).setSources(InputDevice.SOURCE_KEYBOARD).setKeyboardType( - InputDevice.KEYBOARD_TYPE_ALPHABETIC).build(); + void overrideKeyEventSource(int vendorId, int productId, int deviceBus) { + InputDevice device = new InputDevice.Builder() + .setId(1) + .setVendorId(vendorId) + .setProductId(productId) + .setDeviceBus(deviceBus) + .setSources(InputDevice.SOURCE_KEYBOARD) + .setKeyboardType(InputDevice.KEYBOARD_TYPE_ALPHABETIC) + .build(); doReturn(mInputManager).when(mContext).getSystemService(eq(InputManager.class)); doReturn(device).when(mInputManager).getInputDevice(anyInt()); } @@ -604,10 +609,10 @@ class TestPhoneWindowManager { } void assertShortcutLogged(int vendorId, int productId, KeyboardLogEvent logEvent, - int expectedKey, int expectedModifierState, String errorMsg) { + int expectedKey, int expectedModifierState, int deviceBus, String errorMsg) { waitForIdle(); verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED, vendorId, productId, logEvent.getIntValue(), new int[]{expectedKey}, - expectedModifierState), description(errorMsg)); + expectedModifierState, deviceBus), description(errorMsg)); } } diff --git a/tests/Input/src/com/android/test/input/InputDeviceTest.java b/tests/Input/src/com/android/test/input/InputDeviceTest.java index d075b5f01ef9..5434c82b07bd 100644 --- a/tests/Input/src/com/android/test/input/InputDeviceTest.java +++ b/tests/Input/src/com/android/test/input/InputDeviceTest.java @@ -51,6 +51,7 @@ public class InputDeviceTest { assertEquals(device.getName(), outDevice.getName()); assertEquals(device.getVendorId(), outDevice.getVendorId()); assertEquals(device.getProductId(), outDevice.getProductId()); + assertEquals(device.getDeviceBus(), outDevice.getDeviceBus()); assertEquals(device.getDescriptor(), outDevice.getDescriptor()); assertEquals(device.isExternal(), outDevice.isExternal()); assertEquals(device.getSources(), outDevice.getSources()); @@ -79,6 +80,7 @@ public class InputDeviceTest { .setName("Test Device " + DEVICE_ID) .setVendorId(44) .setProductId(45) + .setDeviceBus(3) .setDescriptor("descriptor") .setExternal(true) .setSources(InputDevice.SOURCE_HDMI) |