Merge "Optimize SystemFeaturesMetadata index lookup" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 21b1b17..f69fd55 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -303,6 +303,7 @@
 aconfig_declarations {
     name: "android.security.flags-aconfig",
     package: "android.security",
+    exportable: true,
     container: "system",
     srcs: ["core/java/android/security/*.aconfig"],
 }
@@ -320,6 +321,19 @@
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
+java_aconfig_library {
+    name: "android.security.flags-aconfig-java-export",
+    aconfig_declarations: "android.security.flags-aconfig",
+    mode: "exported",
+    min_sdk_version: "30",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.tethering",
+        "com.android.wifi",
+    ],
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
 cc_aconfig_library {
     name: "android_security_flags_aconfig_c_lib",
     aconfig_declarations: "android.security.flags-aconfig",
diff --git a/api/ApiDocs.bp b/api/ApiDocs.bp
index 1ebe0cd..796c841 100644
--- a/api/ApiDocs.bp
+++ b/api/ApiDocs.bp
@@ -129,6 +129,10 @@
 droidstubs {
     name: "framework-doc-stubs",
     defaults: ["android-non-updatable-doc-stubs-defaults"],
+    flags: [
+        // Ignore any compatibility errors, see check_api.last_released below for more information.
+        "--hide-category Compatibility",
+    ],
     srcs: [":all-modules-public-stubs-source-exportable"],
     api_levels_module: "api_versions_public",
     aidl: {
@@ -137,13 +141,39 @@
             "packages/modules/Media/apex/aidl/stable",
         ],
     },
+
+    // Pass the previously released API to support reverting flagged APIs. Without this, reverting
+    // a flagged API will cause it to be removed, even if it had previously been released. This
+    // has the side effect of causing compatibility issues to be reported but they are already
+    // checked elsewhere so they will be ignored, see `--hide-category Compatibility` above.
+    check_api: {
+        last_released: {
+            api_file: ":android.api.combined.public.latest",
+            removed_api_file: ":android-removed.api.combined.public.latest",
+        },
+    },
 }
 
 droidstubs {
     name: "framework-doc-system-stubs",
     defaults: ["framework-doc-stubs-sources-default"],
-    flags: ["--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\)"],
+    flags: [
+        "--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\)",
+        // Ignore any compatibility errors, see check_api.last_released below for more information.
+        "--hide-category Compatibility",
+    ],
     api_levels_module: "api_versions_system",
+
+    // Pass the previously released API to support reverting flagged APIs. Without this, reverting
+    // a flagged API will cause it to be removed, even if it had previously been released. This
+    // has the side effect of causing compatibility issues to be reported but they are already
+    // checked elsewhere so they will be ignored, see `--hide-category Compatibility` above.
+    check_api: {
+        last_released: {
+            api_file: ":android.api.combined.system.latest",
+            removed_api_file: ":android-removed.api.combined.system.latest",
+        },
+    },
 }
 
 /////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 8d35338..f3bb514 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -115,13 +115,20 @@
 # Performance
 per-file IpcDataCache.java = file:/PERFORMANCE_OWNERS
 
+# Processes, threads, and scheduling
+per-file Process.java = file:/PERFORMANCE_OWNERS
+
 # Memory
 per-file OomKillRecord.java = file:/MEMORY_OWNERS
 
 # MessageQueue and related classes
 per-file MessageQueue.java = mfasheh@google.com, shayba@google.com
 per-file Message.java = mfasheh@google.com, shayba@google.com
+per-file Looper.java = mfasheh@google.com, shayba@google.com
 per-file TestLooperManager.java = mfasheh@google.com, shayba@google.com
+per-file Handler.java = mfasheh@google.com, shayba@google.com
+per-file HandlerThread.java = mfasheh@google.com, shayba@google.com
+per-file HandlerExecutor.java = mfasheh@google.com, shayba@google.com
 
 # Stats
 per-file IStatsBootstrapAtomService.aidl = file:/services/core/java/com/android/server/stats/OWNERS
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 19c6f51..9bd5237 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1326,7 +1326,7 @@
         try {
             getLockSettings().registerStrongAuthTracker(strongAuthTracker.getStub());
         } catch (RemoteException e) {
-            throw new RuntimeException("Could not register StrongAuthTracker");
+            e.rethrowFromSystemServer();
         }
     }
 
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index aeaeeca..8c7b335 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -88,8 +88,8 @@
 #include "nativebridge/native_bridge.h"
 
 #if defined(__BIONIC__)
+#include <android/dlext_private.h>
 extern "C" void android_reset_stack_guards();
-extern "C" void android_set_16kb_appcompat_mode(bool enable_app_compat);
 #endif
 
 namespace {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b22bc2b..0e0b518 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3019,6 +3019,16 @@
         mDexOptHelper.performPackageDexOptUpgradeIfNeeded();
     }
 
+    public void updateMetricsIfNeeded() {
+        final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+        if (displayManager != null) {
+            final Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
+            if (display != null) {
+                display.getMetrics(mMetrics);
+            }
+        }
+    }
+
     private void notifyPackageUseInternal(String packageName, int reason) {
         long time = System.currentTimeMillis();
         synchronized (mLock) {
diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
index 95e7b19..d9af3df 100644
--- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
+++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
@@ -564,8 +564,8 @@
                                                                             jobject clazz) {
     std::string path;
 
-    if (!getAttributePathForTask("FreezerState", getpid(), &path)) {
-        path = "";
+    if (!CgroupGetAttributePathForTask("FreezerState", getpid(), &path)) {
+        path.clear();
     }
 
     return env->NewStringUTF(path.c_str());
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0718f04..32f88f7 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1847,6 +1847,10 @@
         }
         t.traceEnd();
 
+        t.traceBegin("UpdateMetricsIfNeeded");
+        mPackageManagerService.updateMetricsIfNeeded();
+        t.traceEnd();
+
         t.traceBegin("PerformFstrimIfNeeded");
         try {
             mPackageManagerService.performFstrimIfNeeded();
diff --git a/services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java b/services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java
new file mode 100644
index 0000000..a2df73b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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 com.android.server.utils;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+@SmallTest
+@Presubmit
+@RunWith(JUnit4.class)
+public class LazyJniRegistrarTest {
+
+    @Test
+    public void testNativeMethodsResolve() throws Exception {
+        // Basic test with a few explicit invocations to make sure methods resolve and don't throw.
+        LazyJniRegistrar.registerConsumerIrService();
+        LazyJniRegistrar.registerGameManagerService();
+        LazyJniRegistrar.registerVrManagerService();
+    }
+
+    @Test
+    public void testAllNativeRegisterMethodsResolve() throws Exception {
+        // Catch-all test to make sure public static register* methods resolve and don't throw.
+        for (Method method : LazyJniRegistrar.class.getDeclaredMethods()) {
+            if (Modifier.isPublic(method.getModifiers())
+                    && Modifier.isStatic(method.getModifiers())
+                    && method.getName().startsWith("register")) {
+                method.invoke(null);
+            }
+        }
+    }
+
+    // TODO(b/302724778): Remove manual JNI load
+    static {
+        System.loadLibrary("servicestestjni");
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/utils/OWNERS b/services/tests/servicestests/src/com/android/server/utils/OWNERS
index f5b19a1..69b9fa2 100644
--- a/services/tests/servicestests/src/com/android/server/utils/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/utils/OWNERS
@@ -1,5 +1,6 @@
 per-file EventLoggerTest.java = file:/platform/frameworks/av:/media/janitors/media_solutions_OWNERS
 per-file EventLoggerTest.java = jmtrivi@google.com
+per-file LazyJniRegistrarTest.java = file:/PERFORMANCE_OWNERS
 
 # Bug component : 158088 = per-file AnrTimer*.java
 per-file AnrTimer*.java = file:/PERFORMANCE_OWNERS