Merge "Skip resetting the stack protector on eng builds"
diff --git a/core/api/current.txt b/core/api/current.txt
index 0e92850..46318ae 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -20611,6 +20611,7 @@
     field public static final int DUAL_MONO_MODE_RR = 3; // 0x3
     field public static final int ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR = 2; // 0x2
     field public static final int ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER = 1; // 0x1
+    field public static final int ENCAPSULATION_METADATA_TYPE_SUPPLEMENTARY_AUDIO_PLACEMENT = 3; // 0x3
     field public static final int ENCAPSULATION_MODE_ELEMENTARY_STREAM = 1; // 0x1
     field public static final int ENCAPSULATION_MODE_NONE = 0; // 0x0
     field public static final int ERROR = -1; // 0xffffffff
@@ -20629,6 +20630,9 @@
     field public static final int STATE_NO_STATIC_DATA = 2; // 0x2
     field public static final int STATE_UNINITIALIZED = 0; // 0x0
     field public static final int SUCCESS = 0; // 0x0
+    field public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_LEFT = 1; // 0x1
+    field public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_NORMAL = 0; // 0x0
+    field public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_RIGHT = 2; // 0x2
     field public static final int WRITE_BLOCKING = 0; // 0x0
     field public static final int WRITE_NON_BLOCKING = 1; // 0x1
   }
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index c38c887..2d86051d 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1696,7 +1696,10 @@
   public class Build {
     method public static boolean is64BitAbi(String);
     method public static boolean isDebuggable();
+    field @Nullable public static final String BRAND_FOR_ATTESTATION;
     field public static final boolean IS_EMULATOR;
+    field @Nullable public static final String MODEL_FOR_ATTESTATION;
+    field @Nullable public static final String PRODUCT_FOR_ATTESTATION;
   }
 
   public static class Build.VERSION {
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 249f486..832f23c 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -61,6 +61,17 @@
     /** The name of the overall product. */
     public static final String PRODUCT = getString("ro.product.name");
 
+    /**
+     * The product name for attestation. In non-default builds (like the AOSP build) the value of
+     * the 'PRODUCT' system property may be different to the one provisioned to KeyMint,
+     * and Keymint attestation would still attest to the product name, it's running on.
+     * @hide
+     */
+    @Nullable
+    @TestApi
+    public static final String PRODUCT_FOR_ATTESTATION =
+            getString("ro.product.name_for_attestation");
+
     /** The name of the industrial design. */
     public static final String DEVICE = getString("ro.product.device");
 
@@ -89,9 +100,31 @@
     /** The consumer-visible brand with which the product/hardware will be associated, if any. */
     public static final String BRAND = getString("ro.product.brand");
 
+    /**
+     * The product brand for attestation. In non-default builds (like the AOSP build) the value of
+     * the 'BRAND' system property may be different to the one provisioned to KeyMint,
+     * and Keymint attestation would still attest to the product brand, it's running on.
+     * @hide
+     */
+    @Nullable
+    @TestApi
+    public static final String BRAND_FOR_ATTESTATION =
+                getString("ro.product.brand_for_attestation");
+
     /** The end-user-visible name for the end product. */
     public static final String MODEL = getString("ro.product.model");
 
+    /**
+     * The product model for attestation. In non-default builds (like the AOSP build) the value of
+     * the 'MODEL' system property may be different to the one provisioned to KeyMint,
+     * and Keymint attestation would still attest to the product model, it's running on.
+     * @hide
+     */
+    @Nullable
+    @TestApi
+    public static final String MODEL_FOR_ATTESTATION =
+                getString("ro.product.model_for_attestation");
+
     /** The manufacturer of the device's primary system-on-chip. */
     @NonNull
     public static final String SOC_MANUFACTURER = SocProperties.soc_manufacturer().orElse(UNKNOWN);
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 23e1505..62211c4 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -1502,7 +1502,7 @@
                     parent = provider.createAccessibilityNodeInfo(virtualDescendantId);
                     if (parent == null) {
                         // Going up the parent relation we found a null predecessor,
-                        // so remove these disconnected nodes form the result.
+                        // so remove these disconnected nodes from the result.
                         final int currentResultSize = outInfos.size();
                         for (int i = currentResultSize - 1; i >= initialResultSize; i--) {
                             outInfos.remove(i);
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 0b0bfb1..26b0214 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -463,7 +463,7 @@
     AbsPositionScroller mPositionScroller;
 
     /**
-     * The offset in pixels form the top of the AdapterView to the top
+     * The offset in pixels from the top of the AdapterView to the top
      * of the currently selected view. Used to save and restore state.
      */
     int mSelectedTop = 0;
diff --git a/core/java/android/window/TaskFragmentTransaction.java b/core/java/android/window/TaskFragmentTransaction.java
index a821606..2de3dfd 100644
--- a/core/java/android/window/TaskFragmentTransaction.java
+++ b/core/java/android/window/TaskFragmentTransaction.java
@@ -126,7 +126,7 @@
     /** Change type: the status of the TaskFragment is changed. */
     public static final int TYPE_TASK_FRAGMENT_INFO_CHANGED = 2;
 
-    /** Change type: the TaskFragment is removed form the hierarchy. */
+    /** Change type: the TaskFragment is removed from the hierarchy. */
     public static final int TYPE_TASK_FRAGMENT_VANISHED = 3;
 
     /** Change type: the status of the parent leaf Task is changed. */
diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS
index 56da8e0..69660ae 100644
--- a/core/java/com/android/internal/app/OWNERS
+++ b/core/java/com/android/internal/app/OWNERS
@@ -11,6 +11,7 @@
 per-file *Assist* = file:/core/java/android/service/voice/OWNERS
 per-file *Hotword* = file:/core/java/android/service/voice/OWNERS
 per-file *Voice* = file:/core/java/android/service/voice/OWNERS
+per-file *VisualQuery* = file:/core/java/android/service/voice/OWNERS
 
 # System language settings
 per-file *Locale* = file:platform/packages/apps/Settings:/src/com/android/settings/localepicker/OWNERS
diff --git a/core/java/com/android/internal/util/TraceBuffer.java b/core/java/com/android/internal/util/TraceBuffer.java
index fe8a59e..bfcd65d 100644
--- a/core/java/com/android/internal/util/TraceBuffer.java
+++ b/core/java/com/android/internal/util/TraceBuffer.java
@@ -193,7 +193,7 @@
     }
 
     /**
-     * Removes all elements form the buffer
+     * Removes all elements from the buffer
      */
     public void resetBuffer() {
         synchronized (mBufferLock) {
diff --git a/core/java/com/android/internal/widget/RecyclerView.java b/core/java/com/android/internal/widget/RecyclerView.java
index e27557a..4a74d5f 100644
--- a/core/java/com/android/internal/widget/RecyclerView.java
+++ b/core/java/com/android/internal/widget/RecyclerView.java
@@ -10087,7 +10087,7 @@
         static final int FLAG_IGNORE = 1 << 7;
 
         /**
-         * When the View is detached form the parent, we set this flag so that we can take correct
+         * When the View is detached from the parent, we set this flag so that we can take correct
          * action when we need to remove it or add it back.
          */
         static final int FLAG_TMP_DETACHED = 1 << 8;
diff --git a/keystore/java/android/security/KeyStoreException.java b/keystore/java/android/security/KeyStoreException.java
index 6536e43..cb75779 100644
--- a/keystore/java/android/security/KeyStoreException.java
+++ b/keystore/java/android/security/KeyStoreException.java
@@ -265,7 +265,7 @@
     private static int initializeRkpStatusForRegularErrors(int errorCode) {
         // Check if the system code mistakenly called a constructor of KeyStoreException with
         // the OUT_OF_KEYS error code but without RKP status.
-        if (isRkpRelatedError(errorCode)) {
+        if (errorCode == ResponseCode.OUT_OF_KEYS) {
             Log.e(TAG, "RKP error code without RKP status");
             // Set RKP status to RKP_SERVER_REFUSED_ISSUANCE so that the caller never retries.
             return RKP_SERVER_REFUSED_ISSUANCE;
@@ -301,7 +301,7 @@
         super(message);
         mErrorCode = errorCode;
         mRkpStatus = rkpStatus;
-        if (!isRkpRelatedError(mErrorCode)) {
+        if (mErrorCode != ResponseCode.OUT_OF_KEYS) {
             Log.e(TAG, "Providing RKP status for error code " + errorCode + " has no effect.");
         }
     }
@@ -338,7 +338,7 @@
     public boolean isTransientFailure() {
         PublicErrorInformation failureInfo = getErrorInformation(mErrorCode);
         // Special-case handling for RKP failures:
-        if (mRkpStatus != RKP_SUCCESS && isRkpRelatedError(mErrorCode)) {
+        if (mRkpStatus != RKP_SUCCESS && mErrorCode == ResponseCode.OUT_OF_KEYS) {
             switch (mRkpStatus) {
                 case RKP_TEMPORARILY_UNAVAILABLE:
                 case RKP_FETCHING_PENDING_CONNECTIVITY:
@@ -376,11 +376,6 @@
         return (failureInfo.indicators & IS_SYSTEM_ERROR) != 0;
     }
 
-    private static boolean isRkpRelatedError(int errorCode) {
-        return errorCode == ResponseCode.OUT_OF_KEYS
-                  || errorCode == ResponseCode.OUT_OF_KEYS_REQUIRES_UPGRADE;
-    }
-
     /**
      * Returns the re-try policy for transient failures. Valid only if
      * {@link #isTransientFailure()} returns {@code True}.
@@ -388,7 +383,7 @@
     @RetryPolicy
     public int getRetryPolicy() {
         PublicErrorInformation failureInfo = getErrorInformation(mErrorCode);
-        // Special-case handling for RKP failures:
+        // Special-case handling for RKP failures (To be removed in API 34)
         if (mRkpStatus != RKP_SUCCESS) {
             switch (mRkpStatus) {
                 case RKP_TEMPORARILY_UNAVAILABLE:
@@ -404,10 +399,14 @@
                             ? RETRY_WITH_EXPONENTIAL_BACKOFF : RETRY_NEVER;
             }
         }
-        if ((failureInfo.indicators & IS_TRANSIENT_ERROR) != 0) {
-            return RETRY_WITH_EXPONENTIAL_BACKOFF;
-        } else {
-            return RETRY_NEVER;
+        switch (mErrorCode) {
+            case ResponseCode.OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE:
+                return RETRY_AFTER_NEXT_REBOOT;
+            case ResponseCode.OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY:
+                return RETRY_WHEN_CONNECTIVITY_AVAILABLE;
+            default:
+                return (failureInfo.indicators & IS_TRANSIENT_ERROR) != 0
+                        ? RETRY_WITH_EXPONENTIAL_BACKOFF : RETRY_NEVER;
         }
     }
 
@@ -657,8 +656,16 @@
                 new PublicErrorInformation(0, ERROR_KEY_DOES_NOT_EXIST));
         sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS,
                 new PublicErrorInformation(IS_SYSTEM_ERROR, ERROR_ATTESTATION_KEYS_UNAVAILABLE));
-        sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_REQUIRES_UPGRADE,
+        sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE,
                 new PublicErrorInformation(IS_SYSTEM_ERROR | IS_TRANSIENT_ERROR,
                         ERROR_DEVICE_REQUIRES_UPGRADE_FOR_ATTESTATION));
+        sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY,
+                new PublicErrorInformation(IS_SYSTEM_ERROR | IS_TRANSIENT_ERROR,
+                        ERROR_ATTESTATION_KEYS_UNAVAILABLE));
+        sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_TRANSIENT_ERROR,
+                new PublicErrorInformation(IS_SYSTEM_ERROR | IS_TRANSIENT_ERROR,
+                        ERROR_ATTESTATION_KEYS_UNAVAILABLE));
+        sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_PERMANENT_ERROR,
+                new PublicErrorInformation(IS_SYSTEM_ERROR, ERROR_ATTESTATION_KEYS_UNAVAILABLE));
     }
 }
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index 2830d7eff..4715045 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -801,25 +801,32 @@
             ));
 
             if (mSpec.isDevicePropertiesAttestationIncluded()) {
+                final String platformReportedBrand = TextUtils.isEmpty(Build.BRAND_FOR_ATTESTATION)
+                        ? Build.BRAND : Build.BRAND_FOR_ATTESTATION;
                 params.add(KeyStore2ParameterUtils.makeBytes(
                         KeymasterDefs.KM_TAG_ATTESTATION_ID_BRAND,
-                        Build.BRAND.getBytes(StandardCharsets.UTF_8)
+                        platformReportedBrand.getBytes(StandardCharsets.UTF_8)
                 ));
                 params.add(KeyStore2ParameterUtils.makeBytes(
                         KeymasterDefs.KM_TAG_ATTESTATION_ID_DEVICE,
                         Build.DEVICE.getBytes(StandardCharsets.UTF_8)
                 ));
+                final String platformReportedProduct =
+                        TextUtils.isEmpty(Build.PRODUCT_FOR_ATTESTATION) ? Build.PRODUCT :
+                                Build.PRODUCT_FOR_ATTESTATION;
                 params.add(KeyStore2ParameterUtils.makeBytes(
                         KeymasterDefs.KM_TAG_ATTESTATION_ID_PRODUCT,
-                        Build.PRODUCT.getBytes(StandardCharsets.UTF_8)
+                        platformReportedProduct.getBytes(StandardCharsets.UTF_8)
                 ));
                 params.add(KeyStore2ParameterUtils.makeBytes(
                         KeymasterDefs.KM_TAG_ATTESTATION_ID_MANUFACTURER,
                         Build.MANUFACTURER.getBytes(StandardCharsets.UTF_8)
                 ));
+                final String platformReportedModel = TextUtils.isEmpty(Build.MODEL_FOR_ATTESTATION)
+                        ? Build.MODEL : Build.MODEL_FOR_ATTESTATION;
                 params.add(KeyStore2ParameterUtils.makeBytes(
                         KeymasterDefs.KM_TAG_ATTESTATION_ID_MODEL,
-                        Build.MODEL.getBytes(StandardCharsets.UTF_8)
+                        platformReportedModel.getBytes(StandardCharsets.UTF_8)
                 ));
             }
 
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index d51f1e1..f61c427 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -266,15 +266,19 @@
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     public static final int ENCAPSULATION_MODE_HANDLE = 2;
 
-    /* Enumeration of metadata types permitted for use by
+    /**
+     * Enumeration of metadata types permitted for use by
      * encapsulation mode audio streams.
+     * @hide
      */
-    /** @hide */
-    @IntDef(prefix = { "ENCAPSULATION_METADATA_TYPE_" }, value = {
-        ENCAPSULATION_METADATA_TYPE_NONE, /* reserved */
-        ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER,
-        ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR,
-    })
+    @IntDef(prefix = {"ENCAPSULATION_METADATA_TYPE_"},
+            value =
+                    {
+                            ENCAPSULATION_METADATA_TYPE_NONE, /* reserved */
+                            ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER,
+                            ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR,
+                            ENCAPSULATION_METADATA_TYPE_SUPPLEMENTARY_AUDIO_PLACEMENT,
+                    })
     @Retention(RetentionPolicy.SOURCE)
     public @interface EncapsulationMetadataType {}
 
@@ -298,6 +302,45 @@
      */
     public static final int ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR = 2;
 
+    /**
+     * Encapsulation metadata type for placement of supplementary audio.
+     *
+     * A 32 bit integer constant, one of {@link #SUPPLEMENTARY_AUDIO_PLACEMENT_NORMAL}, {@link
+     * #SUPPLEMENTARY_AUDIO_PLACEMENT_LEFT}, {@link #SUPPLEMENTARY_AUDIO_PLACEMENT_RIGHT}.
+     */
+    public static final int ENCAPSULATION_METADATA_TYPE_SUPPLEMENTARY_AUDIO_PLACEMENT = 3;
+
+    /**
+     * Enumeration of supplementary audio placement types.
+     * @hide
+     */
+    @IntDef(prefix = {"SUPPLEMENTARY_AUDIO_PLACEMENT_"},
+            value =
+                    {
+                            SUPPLEMENTARY_AUDIO_PLACEMENT_NORMAL,
+                            SUPPLEMENTARY_AUDIO_PLACEMENT_LEFT,
+                            SUPPLEMENTARY_AUDIO_PLACEMENT_RIGHT,
+                    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SupplementaryAudioPlacement {}
+    // Important: The SUPPLEMENTARY_AUDIO_PLACEMENT values must be kept in sync with native header
+    // files.
+
+    /**
+     * Supplementary audio placement normal.
+     */
+    public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_NORMAL = 0;
+
+    /**
+     * Supplementary audio placement left.
+     */
+    public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_LEFT = 1;
+
+    /**
+     * Supplementary audio placement right.
+     */
+    public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_RIGHT = 2;
+
     /* Dual Mono handling is used when a stereo audio stream
      * contains separate audio content on the left and right channels.
      * Such information about the content of the stream may be found, for example, in
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 50a10bc..14d45d2 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -179,7 +179,7 @@
     private static final String EXTRA_TRANSIENT_STATE = "transient_state";
 
     /** Allow some time inbetween the long press for back and recents. */
-    private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
+    private static final int LOCK_TO_APP_GESTURE_TOLERANCE = 200;
     private static final long AUTODIM_TIMEOUT_MS = 2250;
 
     private final Context mContext;
@@ -1327,7 +1327,7 @@
 
                     // If we recently long-pressed the other button then they were
                     // long-pressed 'together'
-                    if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERENCE) {
+                    if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERANCE) {
                         stopLockTaskMode = true;
                         return true;
                     } else if (v.getId() == btnId1) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index df81c0e..90313eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -1042,7 +1042,7 @@
     }
 
     /**
-     * @return one of the static enum types in this view, calculated form the current state
+     * @return one of the static enum types in this view, calculated from the current state
      */
     public int calculateVisibleType() {
         if (mUserExpanding) {
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index abc4937..f10f930 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -1094,7 +1094,7 @@
     }
 
     /**
-     * Remove the revoked association form the cache and also remove the uid form the map if
+     * Remove the revoked association from the cache and also remove the uid from the map if
      * there are other associations with the same package still pending for role holder removal.
      *
      * @see #mRevokedAssociationsPendingRoleHolderRemoval
@@ -1113,7 +1113,7 @@
             final boolean shouldKeepUidForRemoval = any(
                     getPendingRoleHolderRemovalAssociationsForUser(userId),
                     ai -> packageName.equals(ai.getPackageName()));
-            // Do not remove the uid form the map since other associations with
+            // Do not remove the uid from the map since other associations with
             // the same packageName still pending for role holder removal.
             if (!shouldKeepUidForRemoval) {
                 mUidsPendingRoleHolderRemoval.remove(uid);
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 2207821..821927d 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -143,9 +143,10 @@
 
     static_libs: [
         "android.hardware.authsecret-V1.0-java",
-        "android.hardware.boot-V1.0-java",
-        "android.hardware.boot-V1.1-java",
-        "android.hardware.boot-V1.2-java",
+        "android.hardware.boot-V1.0-java", // HIDL
+        "android.hardware.boot-V1.1-java", // HIDL
+        "android.hardware.boot-V1.2-java", // HIDL
+        "android.hardware.boot-V1-java",   // AIDL
         "android.hardware.broadcastradio-V2.0-java",
         "android.hardware.health-V1.0-java", // HIDL
         "android.hardware.health-V2.0-java", // HIDL
diff --git a/services/core/java/android/os/BatteryStatsInternal.java b/services/core/java/android/os/BatteryStatsInternal.java
index d49cc11..4a2fc89 100644
--- a/services/core/java/android/os/BatteryStatsInternal.java
+++ b/services/core/java/android/os/BatteryStatsInternal.java
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import android.net.Network;
+
 import com.android.internal.os.BinderCallsStats;
 import com.android.internal.os.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes;
 
@@ -63,6 +65,15 @@
     public abstract void noteJobsDeferred(int uid, int numDeferred, long sinceLast);
 
     /**
+     * Informs battery stats of a data packet that woke up the CPU.
+     *
+     * @param network The network over which the packet arrived.
+     * @param elapsedMillis The time of the packet's arrival in elapsed timebase.
+     * @param uid The uid that received the packet.
+     */
+    public abstract void noteCpuWakingNetworkPacket(Network network, long elapsedMillis, int uid);
+
+    /**
      * Informs battery stats of binder stats for the given work source UID.
      */
     public abstract void noteBinderCallStats(int workSourceUid, long incrementalBinderCallCount,
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 606a09c..b02dd52 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -441,6 +441,11 @@
         }
 
         @Override
+        public void noteCpuWakingNetworkPacket(Network network, long elapsedMillis, int uid) {
+            Slog.d(TAG, "Wakeup due to incoming packet on network " + network + " to uid " + uid);
+        }
+
+        @Override
         public void noteBinderCallStats(int workSourceUid, long incrementatCallCount,
                 Collection<BinderCallsStats.CallStat> callStats) {
             synchronized (BatteryStatsService.this.mLock) {
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index 1321873..9d5173a 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -36,7 +36,7 @@
 import android.content.IntentSender;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
-import android.hardware.boot.V1_0.IBootControl;
+import android.hardware.boot.IBootControl;
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
 import android.os.Binder;
@@ -48,6 +48,7 @@
 import android.os.RecoverySystem;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
+import android.os.ServiceManager;
 import android.os.ShellCallback;
 import android.os.SystemProperties;
 import android.provider.DeviceConfig;
@@ -66,6 +67,7 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.pm.ApexManager;
+import com.android.server.recoverysystem.hal.BootControlHIDL;
 
 import libcore.io.IoUtils;
 
@@ -155,18 +157,20 @@
     /**
      * The action to perform upon new resume on reboot prepare request for a given client.
      */
-    @IntDef({ ROR_NEED_PREPARATION,
+    @IntDef({ROR_NEED_PREPARATION,
             ROR_SKIP_PREPARATION_AND_NOTIFY,
-            ROR_SKIP_PREPARATION_NOT_NOTIFY })
-    private @interface ResumeOnRebootActionsOnRequest {}
+            ROR_SKIP_PREPARATION_NOT_NOTIFY})
+    private @interface ResumeOnRebootActionsOnRequest {
+    }
 
     /**
      * The action to perform upon resume on reboot clear request for a given client.
      */
-    @IntDef({ ROR_NOT_REQUESTED,
+    @IntDef({ROR_NOT_REQUESTED,
             ROR_REQUESTED_NEED_CLEAR,
-            ROR_REQUESTED_SKIP_CLEAR })
-    private @interface ResumeOnRebootActionsOnClear {}
+            ROR_REQUESTED_SKIP_CLEAR})
+    private @interface ResumeOnRebootActionsOnClear {
+    }
 
     /**
      * Fatal arm escrow errors from lock settings that means the RoR is in a bad state. So clients
@@ -306,19 +310,26 @@
          * Throws remote exception if there's an error getting the boot control HAL.
          * Returns null if the boot control HAL's version is older than V1_2.
          */
-        public android.hardware.boot.V1_2.IBootControl getBootControl() throws RemoteException {
-            IBootControl bootControlV10 = IBootControl.getService(true);
-            if (bootControlV10 == null) {
-                throw new RemoteException("Failed to get boot control HAL V1_0.");
+        public IBootControl getBootControl() throws RemoteException {
+            String serviceName = IBootControl.DESCRIPTOR + "/default";
+            if (ServiceManager.isDeclared(serviceName)) {
+                Slog.i(TAG,
+                        "AIDL version of BootControl HAL present, using instance " + serviceName);
+                return IBootControl.Stub.asInterface(
+                        ServiceManager.waitForDeclaredService(serviceName));
             }
 
-            android.hardware.boot.V1_2.IBootControl bootControlV12 =
-                    android.hardware.boot.V1_2.IBootControl.castFrom(bootControlV10);
-            if (bootControlV12 == null) {
+            IBootControl bootcontrol = BootControlHIDL.getService();
+            if (!BootControlHIDL.isServicePresent()) {
+                Slog.e(TAG, "Neither AIDL nor HIDL version of the BootControl HAL is present.");
+                return null;
+            }
+
+            if (!BootControlHIDL.isV1_2ServicePresent()) {
                 Slog.w(TAG, "Device doesn't implement boot control HAL V1_2.");
                 return null;
             }
-            return bootControlV12;
+            return bootcontrol;
         }
 
         public void threadSleep(long millis) throws InterruptedException {
@@ -526,7 +537,7 @@
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.RECOVERY)
                 != PackageManager.PERMISSION_GRANTED
                 && mContext.checkCallingOrSelfPermission(android.Manifest.permission.REBOOT)
-                    != PackageManager.PERMISSION_GRANTED) {
+                != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Caller must have " + android.Manifest.permission.RECOVERY
                     + " or " + android.Manifest.permission.REBOOT + " for resume on reboot.");
         }
@@ -738,7 +749,7 @@
             return true;
         }
 
-        android.hardware.boot.V1_2.IBootControl bootControl;
+        IBootControl bootControl;
         try {
             bootControl = mInjector.getBootControl();
         } catch (RemoteException e) {
@@ -972,8 +983,8 @@
             CompressedApexInfoList apexInfoList = getCompressedApexInfoList(packageFile);
             if (apexInfoList == null) {
                 Log.i(TAG, "apex_info.pb not present in OTA package. "
-                            + "Assuming device doesn't support compressed"
-                            + "APEX, continueing without allocating space.");
+                        + "Assuming device doesn't support compressed"
+                        + "APEX, continueing without allocating space.");
                 return true;
             }
             ApexManager apexManager = ApexManager.getInstance();
@@ -1160,6 +1171,7 @@
 
         /**
          * Reads the status from the uncrypt service which is usually represented as a percentage.
+         *
          * @return an integer representing the percentage completed
          * @throws IOException if there was an error reading the socket
          */
@@ -1169,6 +1181,7 @@
 
         /**
          * Sends a confirmation to the uncrypt service.
+         *
          * @throws IOException if there was an error writing to the socket
          */
         public void sendAck() throws IOException {
diff --git a/services/core/java/com/android/server/recoverysystem/hal/BootControlHIDL.java b/services/core/java/com/android/server/recoverysystem/hal/BootControlHIDL.java
new file mode 100644
index 0000000..65325c2
--- /dev/null
+++ b/services/core/java/com/android/server/recoverysystem/hal/BootControlHIDL.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.recoverysystem.hal;
+
+import android.hardware.boot.IBootControl;
+import android.hardware.boot.V1_0.CommandResult;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+
+public class BootControlHIDL implements IBootControl {
+    private static final String TAG = "BootControlHIDL";
+
+    final android.hardware.boot.V1_0.IBootControl v1_hal;
+    final android.hardware.boot.V1_1.IBootControl v1_1_hal;
+    final android.hardware.boot.V1_2.IBootControl v1_2_hal;
+
+    public static boolean isServicePresent() {
+        try {
+            android.hardware.boot.V1_0.IBootControl.getService(true);
+        } catch (RemoteException e) {
+            return false;
+        }
+        return true;
+    }
+
+    public static boolean isV1_2ServicePresent() {
+        try {
+            android.hardware.boot.V1_2.IBootControl.getService(true);
+        } catch (RemoteException e) {
+            return false;
+        }
+        return true;
+    }
+
+    public static BootControlHIDL getService() throws RemoteException {
+        android.hardware.boot.V1_0.IBootControl v1_hal =
+                android.hardware.boot.V1_0.IBootControl.getService(true);
+        android.hardware.boot.V1_1.IBootControl v1_1_hal =
+                android.hardware.boot.V1_1.IBootControl.castFrom(v1_hal);
+        android.hardware.boot.V1_2.IBootControl v1_2_hal =
+                android.hardware.boot.V1_2.IBootControl.castFrom(v1_hal);
+        return new BootControlHIDL(v1_hal, v1_1_hal, v1_2_hal);
+    }
+
+    private BootControlHIDL(android.hardware.boot.V1_0.IBootControl v1_hal,
+            android.hardware.boot.V1_1.IBootControl v1_1_hal,
+            android.hardware.boot.V1_2.IBootControl v1_2_hal) throws RemoteException {
+        this.v1_hal = v1_hal;
+        this.v1_1_hal = v1_1_hal;
+        this.v1_2_hal = v1_2_hal;
+        if (v1_hal == null) {
+            throw new RemoteException("Failed to find V1.0 BootControl HIDL");
+        }
+        if (v1_2_hal != null) {
+            Slog.i(TAG, "V1.2 version of BootControl HIDL HAL available, using V1.2");
+        } else if (v1_1_hal != null) {
+            Slog.i(TAG, "V1.1 version of BootControl HIDL HAL available, using V1.1");
+        } else {
+            Slog.i(TAG, "V1.0 version of BootControl HIDL HAL available, using V1.0");
+        }
+    }
+
+    @Override
+    public IBinder asBinder() {
+        return null;
+    }
+
+    @Override
+    public int getActiveBootSlot() throws RemoteException {
+        if (v1_2_hal == null) {
+            throw new RemoteException("getActiveBootSlot() requires V1.2 BootControl HAL");
+        }
+        return v1_2_hal.getActiveBootSlot();
+    }
+
+    @Override
+    public int getCurrentSlot() throws RemoteException {
+        return v1_hal.getCurrentSlot();
+    }
+
+    @Override
+    public int getNumberSlots() throws RemoteException {
+        return v1_hal.getNumberSlots();
+    }
+
+    @Override
+    public int getSnapshotMergeStatus() throws RemoteException {
+        if (v1_1_hal == null) {
+            throw new RemoteException("getSnapshotMergeStatus() requires V1.1 BootControl HAL");
+        }
+        return v1_1_hal.getSnapshotMergeStatus();
+    }
+
+    @Override
+    public String getSuffix(int slot) throws RemoteException {
+        return v1_hal.getSuffix(slot);
+    }
+
+    @Override
+    public boolean isSlotBootable(int slot) throws RemoteException {
+        int ret = v1_hal.isSlotBootable(slot);
+        if (ret == -1) {
+            throw new RemoteException(
+                    "isSlotBootable() failed, Slot %d might be invalid.".formatted(slot));
+        }
+        return ret != 0;
+    }
+
+    @Override
+    public boolean isSlotMarkedSuccessful(int slot) throws RemoteException {
+        int ret = v1_hal.isSlotMarkedSuccessful(slot);
+        if (ret == -1) {
+            throw new RemoteException(
+                    "isSlotMarkedSuccessful() failed, Slot %d might be invalid.".formatted(slot));
+        }
+        return ret != 0;
+    }
+
+    @Override
+    public void markBootSuccessful() throws RemoteException {
+        CommandResult res = v1_hal.markBootSuccessful();
+        if (!res.success) {
+            throw new RemoteException("Error markBootSuccessful() " + res.errMsg);
+        }
+    }
+
+    @Override
+    public void setActiveBootSlot(int slot) throws RemoteException {
+        CommandResult res = v1_hal.setActiveBootSlot(slot);
+        if (!res.success) {
+            throw new RemoteException("Error setActiveBootSlot(%d) %s".formatted(slot, res.errMsg));
+        }
+    }
+
+    @Override
+    public void setSlotAsUnbootable(int slot) throws RemoteException {
+        CommandResult res = v1_hal.setSlotAsUnbootable(slot);
+        if (!res.success) {
+            throw new RemoteException(
+                    "Error setSlotAsUnbootable(%d) %s".formatted(slot, res.errMsg));
+        }
+    }
+
+    @Override
+    public void setSnapshotMergeStatus(int status) throws RemoteException {
+        if (v1_1_hal == null) {
+            throw new RemoteException("getSnapshotMergeStatus() requires V1.1 BootControl HAL");
+        }
+        if (!v1_1_hal.setSnapshotMergeStatus(status)) {
+            throw new RemoteException("Error setSnapshotMergeStatus(%d)".formatted(status));
+        }
+    }
+
+    @Override
+    public int getInterfaceVersion() throws RemoteException {
+        return 1;
+    }
+
+    @Override
+    public String getInterfaceHash() throws RemoteException {
+        return v1_hal.interfaceDescriptor();
+    }
+}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 7f22242..efbd7a8 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2278,7 +2278,7 @@
                 }
                 if (rootTask.getDisplayArea().isTopRootTask(rootTask)
                         && topRunningActivity.isState(RESUMED)) {
-                    // Kick off any lingering app transitions form the MoveTaskToFront
+                    // Kick off any lingering app transitions from the MoveTaskToFront
                     // operation, but only consider the top task and root-task on that
                     // display.
                     rootTask.executeAppTransition(targetOptions);
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/OWNERS b/services/tests/mockingservicestests/src/com/android/server/power/OWNERS
index d68066b..fb62520 100644
--- a/services/tests/mockingservicestests/src/com/android/server/power/OWNERS
+++ b/services/tests/mockingservicestests/src/com/android/server/power/OWNERS
@@ -1 +1,3 @@
 include /services/core/java/com/android/server/power/OWNERS
+
+per-file ThermalManagerServiceMockingTest.java=wvw@google.com,xwxw@google.com
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
index 5234bb7..63d6768 100644
--- a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
@@ -46,7 +46,7 @@
 import android.content.Context;
 import android.content.IntentSender;
 import android.content.pm.PackageManager;
-import android.hardware.boot.V1_2.IBootControl;
+import android.hardware.boot.IBootControl;
 import android.os.Handler;
 import android.os.IPowerManager;
 import android.os.IRecoverySystemProgressListener;
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
index 27e953f..f1cf48b 100644
--- a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
@@ -17,7 +17,7 @@
 package com.android.server.recoverysystem;
 
 import android.content.Context;
-import android.hardware.boot.V1_2.IBootControl;
+import android.hardware.boot.IBootControl;
 import android.os.PowerManager;
 
 import com.android.internal.widget.LockSettingsInternal;