Merge "Fixing the broken test" into main
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index 2545620..a627a39 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -48,3 +48,6 @@
 
 # SystemConfig
 per-file SystemConfig.java = file:/PACKAGE_MANAGER_OWNERS
+
+# CertBlocklister
+per-file Cert*.java = tweek@google.com, brambonne@google.com, prb@google.com, miguelaranda@google.com
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index a4026eb..c2cb5e9 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -803,22 +803,28 @@
         @Override
         public int onHealthCheckFailed(@Nullable VersionedPackage failedPackage,
                 @FailureReasons int failureReason, int mitigationCount) {
+            int impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
             if (!isDisabled() && (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH
                     || failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING)) {
                 if (Flags.recoverabilityDetection()) {
                     if (!Flags.deprecateFlagsAndSettingsResets()) {
-                        return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
+                        impact =  mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
                                 mayPerformReboot(failedPackage), failedPackage));
                     } else {
-                        return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount));
+                        impact =  mapRescueLevelToUserImpact(getRescueLevel(mitigationCount));
                     }
                 } else {
-                    return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
+                    impact =  mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
                             mayPerformReboot(failedPackage)));
                 }
-            } else {
-                return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
             }
+
+            Slog.i(TAG, "Checking available remediations for health check failure."
+                    + " failedPackage: "
+                    + (failedPackage == null ? null : failedPackage.getPackageName())
+                    + " failureReason: " + failureReason
+                    + " available impact: " + impact);
+            return impact;
         }
 
         @Override
@@ -827,6 +833,11 @@
             if (isDisabled()) {
                 return false;
             }
+            Slog.i(TAG, "Executing remediation."
+                    + " failedPackage: "
+                    + (failedPackage == null ? null : failedPackage.getPackageName())
+                    + " failureReason: " + failureReason
+                    + " mitigationCount: " + mitigationCount);
             if (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH
                     || failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING) {
                 final int level;
diff --git a/services/core/java/com/android/server/am/LmkdConnection.java b/services/core/java/com/android/server/am/LmkdConnection.java
index 598f086..4faadcb 100644
--- a/services/core/java/com/android/server/am/LmkdConnection.java
+++ b/services/core/java/com/android/server/am/LmkdConnection.java
@@ -91,10 +91,18 @@
     @GuardedBy("mLmkdSocketLock")
     private LocalSocket mLmkdSocket = null;
 
-    // socket I/O streams
-    @GuardedBy("mLmkdSocketLock")
+    // mutex to synchronize socket output stream with socket creation/destruction
+    private final Object mLmkdOutputStreamLock = new Object();
+
+    // socket output stream
+    @GuardedBy("mLmkdOutputStreamLock")
     private OutputStream mLmkdOutputStream = null;
-    @GuardedBy("mLmkdSocketLock")
+
+    // mutex to synchronize socket input stream with socket creation/destruction
+    private final Object mLmkdInputStreamLock = new Object();
+
+    // socket input stream
+    @GuardedBy("mLmkdInputStreamLock")
     private InputStream mLmkdInputStream = null;
 
     // buffer to store incoming data
@@ -148,9 +156,13 @@
                 return false;
             }
             // connection established
-            mLmkdSocket = socket;
-            mLmkdOutputStream = ostream;
-            mLmkdInputStream = istream;
+            synchronized(mLmkdOutputStreamLock) {
+                synchronized(mLmkdInputStreamLock) {
+                    mLmkdSocket = socket;
+                    mLmkdOutputStream = ostream;
+                    mLmkdInputStream = istream;
+                }
+            }
             mMsgQueue.addOnFileDescriptorEventListener(mLmkdSocket.getFileDescriptor(),
                 EVENT_INPUT | EVENT_ERROR,
                 new MessageQueue.OnFileDescriptorEventListener() {
@@ -177,7 +189,13 @@
                 mMsgQueue.removeOnFileDescriptorEventListener(
                         mLmkdSocket.getFileDescriptor());
                 IoUtils.closeQuietly(mLmkdSocket);
-                mLmkdSocket = null;
+                synchronized(mLmkdOutputStreamLock) {
+                    synchronized(mLmkdInputStreamLock) {
+                        mLmkdOutputStream = null;
+                        mLmkdInputStream = null;
+                        mLmkdSocket = null;
+                    }
+                }
             }
             // wake up reply waiters if any
             synchronized (mReplyBufLock) {
@@ -262,24 +280,33 @@
     }
 
     private boolean write(ByteBuffer buf) {
-        synchronized (mLmkdSocketLock) {
-            try {
-                mLmkdOutputStream.write(buf.array(), 0, buf.position());
-            } catch (IOException ex) {
-                return false;
+        boolean result = false;
+
+        synchronized(mLmkdOutputStreamLock) {
+            if (mLmkdOutputStream != null) {
+                try {
+                    mLmkdOutputStream.write(buf.array(), 0, buf.position());
+                    result = true;
+                } catch (IOException ex) {
+                }
             }
-            return true;
         }
+
+        return result;
     }
 
     private int read(ByteBuffer buf) {
-        synchronized (mLmkdSocketLock) {
-            try {
-                return mLmkdInputStream.read(buf.array(), 0, buf.array().length);
-            } catch (IOException ex) {
+        int result = -1;
+
+        synchronized(mLmkdInputStreamLock) {
+            if (mLmkdInputStream != null) {
+                try {
+                    result = mLmkdInputStream.read(buf.array(), 0, buf.array().length);
+                } catch (IOException ex) {
+                }
             }
-            return -1;
         }
+        return result;
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 89c4f0f..9199004 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -4550,7 +4550,7 @@
                             PackageManagerException.INTERNAL_ERROR_SYSTEM_OVERLAY_STATIC);
                 }
             } else {
-                if ((scanFlags & SCAN_AS_VENDOR) != 0) {
+                if ((scanFlags & (SCAN_AS_VENDOR | SCAN_AS_ODM)) != 0) {
                     if (pkg.getTargetSdkVersion() < ScanPackageUtils.getVendorPartitionVersion()) {
                         Slog.w(TAG, "System overlay " + pkg.getPackageName()
                                 + " targets an SDK below the required SDK level of vendor"
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index c85ceac..4f28e02 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -154,12 +154,22 @@
             }
         }
 
+        Slog.i(TAG, "Checking available remediations for health check failure."
+                + " failedPackage: "
+                + (failedPackage == null ? null : failedPackage.getPackageName())
+                + " failureReason: " + failureReason
+                + " available impact: " + impact);
         return impact;
     }
 
     @Override
     public boolean execute(@Nullable VersionedPackage failedPackage,
             @FailureReasons int rollbackReason, int mitigationCount) {
+        Slog.i(TAG, "Executing remediation."
+                + " failedPackage: "
+                + (failedPackage == null ? null : failedPackage.getPackageName())
+                + " rollbackReason: " + rollbackReason
+                + " mitigationCount: " + mitigationCount);
         if (Flags.recoverabilityDetection()) {
             List<RollbackInfo> availableRollbacks = getAvailableRollbacks();
             if (rollbackReason == PackageWatchdog.FAILURE_REASON_NATIVE_CRASH) {
@@ -503,6 +513,10 @@
             @FailureReasons int rollbackReason) {
         assertInWorkerThread();
 
+        Slog.i(TAG, "Rolling back package. RollbackId: " + rollback.getRollbackId()
+                + " failedPackage: "
+                + (failedPackage == null ? null : failedPackage.getPackageName())
+                + " rollbackReason: " + rollbackReason);
         final RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
         int reasonToLog = WatchdogRollbackLogger.mapFailureReasonToMetric(rollbackReason);
         final String failedPackageToLog;
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 977a8a0..64dbc50 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -398,14 +398,17 @@
                 if (randomNum >= traceFrequency) {
                     return;
                 }
-                // Wait for 1s before starting tracing.
+                // For a small percentage a traces, we collect the initialization behavior.
+                boolean traceInitialization = ThreadLocalRandom.current().nextInt(10) < 1;
+                int traceDelay = traceInitialization ? 0 : 1000;
+                String traceTag = traceInitialization ? "camera_init" : "camera";
                 BackgroundThread.get().getThreadHandler().postDelayed(() -> {
                     try {
-                        mIProfcollect.trace_once("camera");
+                        mIProfcollect.trace_once(traceTag);
                     } catch (RemoteException e) {
                         Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage());
                     }
-                }, 1000);
+                }, traceDelay);
             }
         }, null);
     }