Merge "[HSG] Allow class directive without policy" into main
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 031380d..f815df6 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5431,7 +5431,7 @@
     /**
      * Activities that can be safely invoked from a browser must support this
      * category.  For example, if the user is viewing a web page or an e-mail
-     * and clicks on a link in the text, the Intent generated execute that
+     * and clicks on a link in the text, the Intent generated to execute that
      * link will require the BROWSABLE category, so that only activities
      * supporting this category will be considered as possible actions.  By
      * supporting this category, you are promising that there is nothing
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index 0125905..2fe4871 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -70,6 +70,13 @@
 
     private static final String TAG = "Looper";
 
+    private static class NoImagePreloadHolder {
+        // Enable/Disable verbose logging with a system prop. e.g.
+        // adb shell 'setprop log.looper.slow.verbose false && stop && start'
+        private static final boolean sVerboseLogging =
+                SystemProperties.getBoolean("log.looper.slow.verbose", false);
+    }
+
     // sThreadLocal.get() will return null unless you've called prepare().
     @UnsupportedAppUsage
     static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
@@ -246,17 +253,21 @@
             }
         }
         if (logSlowDelivery) {
+            boolean slow = false;
+
+            if (!me.mSlowDeliveryDetected || NoImagePreloadHolder.sVerboseLogging) {
+                slow = showSlowLog(slowDeliveryThresholdMs, msg.when, dispatchStart,
+                        "delivery", msg);
+            }
             if (me.mSlowDeliveryDetected) {
-                if ((dispatchStart - msg.when) <= 10) {
+                if (!slow && (dispatchStart - msg.when) <= 10) {
                     Slog.w(TAG, "Drained");
                     me.mSlowDeliveryDetected = false;
                 }
-            } else {
-                if (showSlowLog(slowDeliveryThresholdMs, msg.when, dispatchStart, "delivery",
-                        msg)) {
-                    // Once we write a slow delivery log, suppress until the queue drains.
-                    me.mSlowDeliveryDetected = true;
-                }
+            } else if (slow) {
+                // A slow delivery is detected, suppressing further logs unless verbose logging
+                // is enabled.
+                me.mSlowDeliveryDetected = true;
             }
         }
         if (logSlowDispatch) {
@@ -322,6 +333,23 @@
 
     @android.ravenwood.annotation.RavenwoodReplace
     private static int getThresholdOverride() {
+        // Allow overriding the threshold for all processes' main looper with a system prop.
+        // e.g. adb shell 'setprop log.looper.any.main.slow 1 && stop && start'
+        if (myLooper() == getMainLooper()) {
+            final int globalOverride = SystemProperties.getInt("log.looper.any.main.slow", -1);
+            if (globalOverride >= 0) {
+                return globalOverride;
+            }
+        }
+
+        // Allow overriding the threshold for all threads within a process with a system prop.
+        // e.g. adb shell 'setprop log.looper.1000.any.slow 1 && stop && start'
+        final int processOverride = SystemProperties.getInt("log.looper."
+                + Process.myUid() + ".any.slow", -1);
+        if (processOverride >= 0) {
+            return processOverride;
+        }
+
         return SystemProperties.getInt("log.looper."
                 + Process.myUid() + "."
                 + Thread.currentThread().getName()
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index d91963f..6bb8b0a 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -4479,7 +4479,7 @@
         /**
          * @hide
          */
-        public Transaction setDesintationFrame(SurfaceControl sc, @NonNull Rect destinationFrame) {
+        public Transaction setDestinationFrame(SurfaceControl sc, @NonNull Rect destinationFrame) {
             checkPreconditions(sc);
             nativeSetDestinationFrame(mNativeObject, sc.mNativeObject,
                     destinationFrame.left, destinationFrame.top, destinationFrame.right,
@@ -4490,7 +4490,7 @@
         /**
          * @hide
          */
-        public Transaction setDesintationFrame(SurfaceControl sc, int width, int height) {
+        public Transaction setDestinationFrame(SurfaceControl sc, int width, int height) {
             checkPreconditions(sc);
             nativeSetDestinationFrame(mNativeObject, sc.mNativeObject, 0, 0, width, height);
             return this;
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index f0d2a34..31d8556 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -1092,7 +1092,7 @@
                     }
                 }
 
-                surfaceUpdateTransaction.setDesintationFrame(mBlastSurfaceControl, mSurfaceWidth,
+                surfaceUpdateTransaction.setDestinationFrame(mBlastSurfaceControl, mSurfaceWidth,
                             mSurfaceHeight);
 
                 if (isHardwareAccelerated()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
index e74342e..1931ea9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
@@ -529,9 +529,12 @@
             Slog.w(TAG, "Trying to remove a task that was never added? (no taskToken)");
             return;
         }
+        // Cache it to avoid NPE and make sure to remove it from recents history.
+        // mTaskToken can be cleared in onTaskVanished() when the task is removed.
+        final WindowContainerToken taskToken = mTaskToken;
         mShellExecutor.execute(() -> {
             WindowContainerTransaction wct = new WindowContainerTransaction();
-            wct.removeTask(mTaskToken);
+            wct.removeTask(taskToken);
             mTaskViewTransitions.closeTaskView(wct, this);
         });
     }
diff --git a/location/java/android/location/Geocoder.java b/location/java/android/location/Geocoder.java
index cdde7c6..9746dab 100644
--- a/location/java/android/location/Geocoder.java
+++ b/location/java/android/location/Geocoder.java
@@ -83,8 +83,11 @@
      * succeed.
      */
     public static boolean isPresent() {
-        ILocationManager lm = Objects.requireNonNull(ILocationManager.Stub.asInterface(
-                ServiceManager.getService(Context.LOCATION_SERVICE)));
+        ILocationManager lm = ILocationManager.Stub.asInterface(
+                ServiceManager.getService(Context.LOCATION_SERVICE));
+        if (lm == null) {
+            return false;
+        }
         try {
             return lm.isGeocodeAvailable();
         } catch (RemoteException e) {
diff --git a/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp
index e4f88a6..e63c59d 100644
--- a/media/tests/MediaRouter/Android.bp
+++ b/media/tests/MediaRouter/Android.bp
@@ -9,7 +9,7 @@
 
 android_test {
     name: "mediaroutertest",
-    team: "trendy_team_android_media_solutions",
+    team: "trendy_team_android_media_better_together",
 
     srcs: ["**/*.java"],
 
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java b/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java
index 369ef6a..97f86b1 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java
@@ -209,6 +209,8 @@
         this(vcnContext, subscriptionGroup, config, snapshot, vcnCallback, new Dependencies());
     }
 
+    // WARNING: This constructor executes on the binder thread. Thread safety MUST be ensured when
+    // accessing data within this constructor and any methods called from here.
     @VisibleForTesting(visibility = Visibility.PRIVATE)
     public Vcn(
             @NonNull VcnContext vcnContext,
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java b/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java
index 99c848f..38fcf09 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java
@@ -36,7 +36,6 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
-import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
 import android.util.Slog;
 
@@ -46,6 +45,7 @@
 
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 
 /**
@@ -56,12 +56,14 @@
  *
  * @hide
  */
+// TODO(b/388919146): Implement a more generic solution to prevent concurrent modifications on
+// mListeners and mRequests
 // TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
 @TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
 public class VcnNetworkProvider extends NetworkProvider {
     private static final String TAG = VcnNetworkProvider.class.getSimpleName();
 
-    private final Set<NetworkRequestListener> mListeners = new ArraySet<>();
+    private final Set<NetworkRequestListener> mListeners = ConcurrentHashMap.newKeySet();
 
     private final Context mContext;
     private final Handler mHandler;
@@ -72,7 +74,7 @@
      *
      * <p>NetworkRequests are immutable once created, and therefore can be used as stable keys.
      */
-    private final Set<NetworkRequest> mRequests = new ArraySet<>();
+    private final Set<NetworkRequest> mRequests = ConcurrentHashMap.newKeySet();
 
     public VcnNetworkProvider(@NonNull Context context, @NonNull Looper looper) {
         this(context, looper, new Dependencies());
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 0d0cdd8..a0e5433 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -137,6 +137,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.pm.RoSystemFeatures;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
@@ -1325,7 +1326,7 @@
         mContext.enforceCallingOrSelfPermission(
                 Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN,
                 "Requires MANAGE_WEAK_ESCROW_TOKEN permission.");
-        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+        if (!RoSystemFeatures.hasFeatureAutomotive(mContext)) {
             throw new IllegalArgumentException(
                     "Weak escrow token are only for automotive devices.");
         }
@@ -3613,7 +3614,7 @@
         }
 
         // Escrow tokens are enabled on automotive builds.
-        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+        if (RoSystemFeatures.hasFeatureAutomotive(mContext)) {
             return;
         }
 
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index a8e6f68..dae481a 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -1999,9 +1999,9 @@
         // Create new lib file without signature info
         incfs::NewFileParams libFileParams = {
                 .size = entry.uncompressed_length,
-                .signature = {},
                 // Metadata of the new lib file is its relative path
                 .metadata = {targetLibPath.c_str(), (IncFsSize)targetLibPath.size()},
+                .signature = {},
         };
         incfs::FileId libFileId = idFromMetadata(targetLibPath);
         if (auto res = mIncFs->makeFile(ifs->control, targetLibPathAbsolute, 0755, libFileId,