Merge "Add BinderLeakTest and BInderLeakTest_legacy to general-tests" into main
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index f2c39be..4a73bf0 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -50,7 +50,7 @@
         },
         api_lint: {
             enabled: true,
-            new_since: ":android.api.public.latest",
+            new_since: ":android.api.combined.public.latest",
             baseline_file: ":non-updatable-lint-baseline.txt",
         },
     },
@@ -130,7 +130,7 @@
         },
         api_lint: {
             enabled: true,
-            new_since: ":android.api.system.latest",
+            new_since: ":android.api.combined.system.latest",
             baseline_file: ":non-updatable-system-lint-baseline.txt",
         },
     },
@@ -185,7 +185,7 @@
         },
         api_lint: {
             enabled: true,
-            new_since: ":android.api.test.latest",
+            new_since: ":android.api.combined.test.latest",
             baseline_file: ":non-updatable-test-lint-baseline.txt",
         },
     },
@@ -269,7 +269,7 @@
         },
         api_lint: {
             enabled: true,
-            new_since: ":android.api.module-lib.latest",
+            new_since: ":android.api.combined.module-lib.latest",
             baseline_file: ":non-updatable-module-lib-lint-baseline.txt",
         },
     },
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 2a7dbab..e7e3a85 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -364,12 +364,12 @@
     public static final int GESTURE_SWIPE_UP_AND_RIGHT = 14;
 
     /**
-     * The user has performed an down and left gesture on the touch screen.
+     * The user has performed a down and left gesture on the touch screen.
      */
     public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 15;
 
     /**
-     * The user has performed an down and right gesture on the touch screen.
+     * The user has performed a down and right gesture on the touch screen.
      */
     public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16;
 
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 7ee3413..497d47a 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -2015,7 +2015,7 @@
      *     null for no callback
      * @param handler {@link Handler} identifying the callback thread,
      *     null for the main thread
-     * @return An {@link AccountManagerFuture} which resolves to a Boolean indicated wether it
+     * @return An {@link AccountManagerFuture} which resolves to a Boolean indicated whether it
      * succeeded.
      * @hide
      */
diff --git a/core/java/android/app/prediction/OWNERS b/core/java/android/app/prediction/OWNERS
index fe012da..73168fb 100644
--- a/core/java/android/app/prediction/OWNERS
+++ b/core/java/android/app/prediction/OWNERS
@@ -1,2 +1,4 @@
+pinyaoting@google.com
+hyunyoungs@google.com
 adamcohen@google.com
 sunnygoyal@google.com
diff --git a/core/java/android/os/VintfObject.java b/core/java/android/os/VintfObject.java
index 5056557..bb89e07 100644
--- a/core/java/android/os/VintfObject.java
+++ b/core/java/android/os/VintfObject.java
@@ -17,8 +17,11 @@
 package android.os;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.TestApi;
+import android.app.ActivityThread;
 
+import java.io.IOException;
 import java.util.Map;
 
 /**
@@ -113,5 +116,20 @@
     @TestApi
     public static native Long getTargetFrameworkCompatibilityMatrixVersion();
 
+    /**
+     * Executes a shell command using shell user identity, and return the standard output in string.
+     *
+     * @hide
+     */
+    private static @Nullable String runShellCommand(@NonNull String command) throws IOException {
+        var activityThread = ActivityThread.currentActivityThread();
+        var instrumentation = activityThread.getInstrumentation();
+        var automation = instrumentation.getUiAutomation();
+        var pfd = automation.executeShellCommand(command);
+        try (var is = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
+            return new String(is.readAllBytes());
+        }
+    }
+
     private VintfObject() {}
 }
diff --git a/core/java/android/permission/OWNERS b/core/java/android/permission/OWNERS
index d2f4b50..857bacd 100644
--- a/core/java/android/permission/OWNERS
+++ b/core/java/android/permission/OWNERS
@@ -1,14 +1,13 @@
 # Bug component: 137825
 
-augale@google.com
 evanseverson@google.com
 fayey@google.com
 jaysullivan@google.com
 joecastro@google.com
-kvakil@google.com
 mrulhania@google.com
 ntmyren@google.com
 rmacgregor@google.com
 theianchen@google.com
 yutingfang@google.com
 zhanghai@google.com
+kiranmr@google.com
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index 064bc69..5c49e24 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -129,7 +129,7 @@
         }
         ViewGroup effective = null;
         ViewParent nextParent = focused.getParent();
-        do {
+        while (nextParent instanceof ViewGroup) {
             if (nextParent == root) {
                 return effective != null ? effective : root;
             }
@@ -143,7 +143,7 @@
                 effective = vg;
             }
             nextParent = nextParent.getParent();
-        } while (nextParent instanceof ViewGroup);
+        }
         return root;
     }
 
diff --git a/core/java/com/android/internal/content/om/OverlayConfigParser.java b/core/java/com/android/internal/content/om/OverlayConfigParser.java
index faaf7d5..8132652 100644
--- a/core/java/com/android/internal/content/om/OverlayConfigParser.java
+++ b/core/java/com/android/internal/content/om/OverlayConfigParser.java
@@ -24,6 +24,8 @@
 import android.content.pm.PackagePartitions.SystemPartition;
 import android.os.Build;
 import android.os.FileUtils;
+import android.os.SystemProperties;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.Xml;
@@ -241,6 +243,18 @@
         }
     }
 
+    @FunctionalInterface
+    public interface SysPropWrapper{
+        /**
+         * Get system property
+         *
+         * @param property the key to look up.
+         *
+         * @return The property value if found, empty string otherwise.
+         */
+        String get(String property);
+    }
+
     /**
      * Retrieves overlays configured within the partition in increasing priority order.
      *
@@ -320,6 +334,76 @@
     }
 
     /**
+     * Expand the property inside a rro configuration path.
+     *
+     * A RRO configuration can contain a property, this method expands
+     * the property to its value.
+     *
+     * Only read only properties allowed, prefixed with ro. Other
+     * properties will raise exception.
+     *
+     * Only a single property in the path is allowed.
+     *
+     * Example "${ro.boot.hardware.sku}/config.xml" would expand to
+     *     "G020N/config.xml"
+     *
+     * @param configPath path to expand
+     * @param sysPropWrapper method used for reading properties
+     *
+     * @return The expanded path. Returns null if configPath is null.
+     */
+    @VisibleForTesting
+    public static String expandProperty(String configPath,
+            SysPropWrapper sysPropWrapper) {
+        if (configPath == null) {
+            return null;
+        }
+
+        int propStartPos = configPath.indexOf("${");
+        if (propStartPos == -1) {
+            // No properties inside the string, return as is
+            return configPath;
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        sb.append(configPath.substring(0, propStartPos));
+
+        // Read out the end position
+        int propEndPos = configPath.indexOf("}", propStartPos);
+        if (propEndPos == -1) {
+            throw new IllegalStateException("Malformed property, unmatched braces, in: "
+                    + configPath);
+        }
+
+        // Confirm that there is only one property inside the string
+        if (configPath.indexOf("${", propStartPos + 2) != -1) {
+            throw new IllegalStateException("Only a single property supported in path: "
+                    + configPath);
+        }
+
+        final String propertyName = configPath.substring(propStartPos + 2, propEndPos);
+        if (!propertyName.startsWith("ro.")) {
+            throw new IllegalStateException("Only read only properties can be used when "
+                    + "merging RRO config files: " + propertyName);
+        }
+        final String propertyValue = sysPropWrapper.get(propertyName);
+        if (TextUtils.isEmpty(propertyValue)) {
+            throw new IllegalStateException("Property is empty or doesn't exist: " + propertyName);
+        }
+        Log.d(TAG, String.format("Using property in overlay config path: \"%s\"", propertyName));
+        sb.append(propertyValue);
+
+        // propEndPos points to '}', need to step to next character, might be outside of string
+        propEndPos = propEndPos + 1;
+        // Append the remainder, if exists
+        if (propEndPos < configPath.length()) {
+            sb.append(configPath.substring(propEndPos));
+        }
+
+        return sb.toString();
+    }
+
+    /**
      * Parses a <merge> tag within an overlay configuration file.
      *
      * Merge tags allow for other configuration files to be "merged" at the current parsing
@@ -331,10 +415,21 @@
             @Nullable OverlayScanner scanner,
             @Nullable Map<String, ParsedOverlayInfo> packageManagerOverlayInfos,
             @NonNull ParsingContext parsingContext) {
-        final String path = parser.getAttributeValue(null, "path");
+        final String path;
+
+        try {
+            SysPropWrapper sysPropWrapper = p -> {
+                return SystemProperties.get(p, "");
+            };
+            path = expandProperty(parser.getAttributeValue(null, "path"), sysPropWrapper);
+        } catch (IllegalStateException e) {
+            throw new IllegalStateException(String.format("<merge> path expand error in %s at %s",
+                    configFile, parser.getPositionDescription()), e);
+        }
+
         if (path == null) {
-            throw new IllegalStateException(String.format("<merge> without path in %s at %s"
-                    + configFile, parser.getPositionDescription()));
+            throw new IllegalStateException(String.format("<merge> without path in %s at %s",
+                    configFile, parser.getPositionDescription()));
         }
 
         if (path.startsWith("/")) {
diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
index 9fc7ddb..0e5049e 100644
--- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
@@ -1911,12 +1911,16 @@
             } else if (parser.getName().equals("package")) {
                 final TypedArray sa = res.obtainAttributes(parser,
                         R.styleable.AndroidManifestQueriesPackage);
-                final String packageName = sa.getNonConfigurationString(
-                        R.styleable.AndroidManifestQueriesPackage_name, 0);
-                if (TextUtils.isEmpty(packageName)) {
-                    return input.error("Package name is missing from package tag.");
+                try {
+                    final String packageName = sa.getNonConfigurationString(
+                            R.styleable.AndroidManifestQueriesPackage_name, 0);
+                    if (TextUtils.isEmpty(packageName)) {
+                        return input.error("Package name is missing from package tag.");
+                    }
+                    pkg.addQueriesPackage(packageName.intern());
+                } finally {
+                    sa.recycle();
                 }
-                pkg.addQueriesPackage(packageName.intern());
             } else if (parser.getName().equals("provider")) {
                 final TypedArray sa = res.obtainAttributes(parser,
                         R.styleable.AndroidManifestQueriesProvider);
diff --git a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
new file mode 100644
index 0000000..1340156
--- /dev/null
+++ b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
@@ -0,0 +1,55 @@
+/*
+ * 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.internal.ravenwood;
+
+/**
+ * Class to interact with the Ravenwood environment.
+ */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
+public class RavenwoodEnvironment {
+    private static RavenwoodEnvironment sInstance = new RavenwoodEnvironment();
+
+    private RavenwoodEnvironment() {
+    }
+
+    /**
+     * @return the singleton instance.
+     */
+    public static RavenwoodEnvironment getInstance() {
+        return sInstance;
+    }
+
+    /**
+     * USE IT SPARINGLY! Returns true if it's running on Ravenwood, hostside test environment.
+     *
+     * <p>Using this allows code to behave differently on a real device and on Ravenwood, but
+     * generally speaking, that's a bad idea because we want the test target code to behave
+     * differently.
+     *
+     * <p>This should be only used when different behavior is absolutely needed.
+     *
+     * <p>If someone needs it without having access to the SDK, the following hack would work too.
+     * <code>System.getProperty("java.class.path").contains("ravenwood")</code>
+     */
+    @android.ravenwood.annotation.RavenwoodReplace
+    public boolean isRunningOnRavenwood() {
+        return false;
+    }
+
+    public boolean isRunningOnRavenwood$ravenwood() {
+        return true;
+    }
+}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 6412ddb..3024b94 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -478,4 +478,8 @@
         "libnativehelper",
         "libvintf",
     ],
+
+    required: [
+        "vintf",
+    ],
 }
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index 8dc9d0a..7a4854b 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -32,6 +32,8 @@
 static jmethodID gHashMapPut;
 static jclass gLongClazz;
 static jmethodID gLongValueOf;
+static jclass gVintfObjectClazz;
+static jmethodID gRunCommand;
 
 namespace android {
 
@@ -47,6 +49,56 @@
 using vintf::Vndk;
 using vintf::CheckFlags::ENABLE_ALL_CHECKS;
 
+// Instead of VintfObject::GetXxx(), we construct
+// HalManifest/CompatibilityMatrix objects by calling `vintf` through
+// UiAutomation.executeShellCommand() so that the commands are executed
+// using shell identity. Otherwise, we would need to allow "apps" to access
+// files like apex-info-list.xml which we don't want to open to apps.
+// This is okay because VintfObject is @TestApi and only used in CTS tests.
+
+static std::string runCmd(JNIEnv* env, const char* cmd) {
+    jstring jstr = (jstring)env->CallStaticObjectMethod(gVintfObjectClazz, gRunCommand,
+                                                        env->NewStringUTF(cmd));
+    std::string output;
+    if (jstr) {
+        auto cstr = env->GetStringUTFChars(jstr, nullptr);
+        output = std::string(cstr);
+        env->ReleaseStringUTFChars(jstr, cstr);
+    } else {
+        LOG(WARNING) << "Failed to run " << cmd;
+        env->ExceptionDescribe();
+        env->ExceptionClear();
+    }
+    return output;
+}
+
+template <typename T>
+static std::shared_ptr<const T> fromXml(const std::string& content) {
+    std::shared_ptr<T> object = std::make_unique<T>();
+    std::string error;
+    if (fromXml(object.get(), content, &error)) {
+        return object;
+    }
+    LOG(WARNING) << "Unabled to parse: " << error;
+    return nullptr;
+}
+
+static std::shared_ptr<const HalManifest> getDeviceHalManifest(JNIEnv* env) {
+    return fromXml<HalManifest>(runCmd(env, "vintf dm"));
+}
+
+static std::shared_ptr<const HalManifest> getFrameworkHalManifest(JNIEnv* env) {
+    return fromXml<HalManifest>(runCmd(env, "vintf fm"));
+}
+
+static std::shared_ptr<const CompatibilityMatrix> getDeviceCompatibilityMatrix(JNIEnv* env) {
+    return fromXml<CompatibilityMatrix>(runCmd(env, "vintf dcm"));
+}
+
+static std::shared_ptr<const CompatibilityMatrix> getFrameworkCompatibilityMatrix(JNIEnv* env) {
+    return fromXml<CompatibilityMatrix>(runCmd(env, "vintf fcm"));
+}
+
 template<typename V>
 static inline jobjectArray toJavaStringArray(JNIEnv* env, const V& v) {
     size_t i;
@@ -83,12 +135,10 @@
 {
     std::vector<std::string> cStrings;
 
-    tryAddSchema(VintfObject::GetDeviceHalManifest(), "device manifest", &cStrings);
-    tryAddSchema(VintfObject::GetFrameworkHalManifest(), "framework manifest", &cStrings);
-    tryAddSchema(VintfObject::GetDeviceCompatibilityMatrix(), "device compatibility matrix",
-                 &cStrings);
-    tryAddSchema(VintfObject::GetFrameworkCompatibilityMatrix(), "framework compatibility matrix",
-                 &cStrings);
+    tryAddSchema(getDeviceHalManifest(env), "device manifest", &cStrings);
+    tryAddSchema(getFrameworkHalManifest(env), "framework manifest", &cStrings);
+    tryAddSchema(getDeviceCompatibilityMatrix(env), "device compatibility matrix", &cStrings);
+    tryAddSchema(getFrameworkCompatibilityMatrix(env), "framework compatibility matrix", &cStrings);
 
     return toJavaStringArray(env, cStrings);
 }
@@ -108,15 +158,13 @@
 
 static jobjectArray android_os_VintfObject_getHalNamesAndVersions(JNIEnv* env, jclass) {
     std::set<std::string> halNames;
-    tryAddHalNamesAndVersions(VintfObject::GetDeviceHalManifest(),
-            "device manifest", &halNames);
-    tryAddHalNamesAndVersions(VintfObject::GetFrameworkHalManifest(),
-            "framework manifest", &halNames);
+    tryAddHalNamesAndVersions(getDeviceHalManifest(env), "device manifest", &halNames);
+    tryAddHalNamesAndVersions(getFrameworkHalManifest(env), "framework manifest", &halNames);
     return toJavaStringArray(env, halNames);
 }
 
 static jstring android_os_VintfObject_getSepolicyVersion(JNIEnv* env, jclass) {
-    std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
+    std::shared_ptr<const HalManifest> manifest = getDeviceHalManifest(env);
     if (manifest == nullptr || manifest->type() != SchemaType::DEVICE) {
         LOG(WARNING) << __FUNCTION__ << "Cannot get device manifest";
         return nullptr;
@@ -126,8 +174,7 @@
 }
 
 static jstring android_os_VintfObject_getPlatformSepolicyVersion(JNIEnv* env, jclass) {
-    std::shared_ptr<const CompatibilityMatrix> matrix =
-            VintfObject::GetFrameworkCompatibilityMatrix();
+    std::shared_ptr<const CompatibilityMatrix> matrix = getFrameworkCompatibilityMatrix(env);
     if (matrix == nullptr || matrix->type() != SchemaType::FRAMEWORK) {
         jniThrowRuntimeException(env, "Cannot get framework compatibility matrix");
         return nullptr;
@@ -148,7 +195,7 @@
 }
 
 static jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) {
-    std::shared_ptr<const HalManifest> manifest = VintfObject::GetFrameworkHalManifest();
+    std::shared_ptr<const HalManifest> manifest = getFrameworkHalManifest(env);
     if (manifest == nullptr || manifest->type() != SchemaType::FRAMEWORK) {
         LOG(WARNING) << __FUNCTION__ << "Cannot get framework manifest";
         return nullptr;
@@ -163,7 +210,7 @@
 }
 
 static jobject android_os_VintfObject_getTargetFrameworkCompatibilityMatrixVersion(JNIEnv* env, jclass) {
-    std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
+    std::shared_ptr<const HalManifest> manifest = getDeviceHalManifest(env);
     if (manifest == nullptr || manifest->level() == Level::UNSPECIFIED) {
         return nullptr;
     }
@@ -188,19 +235,20 @@
 
 const char* const kVintfObjectPathName = "android/os/VintfObject";
 
-int register_android_os_VintfObject(JNIEnv* env)
-{
-
+int register_android_os_VintfObject(JNIEnv* env) {
     gString = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/String"));
     gHashMapClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/util/HashMap"));
     gHashMapInit = GetMethodIDOrDie(env, gHashMapClazz, "<init>", "()V");
-    gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz,
-            "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+    gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz, "put",
+                                   "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
     gLongClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Long"));
     gLongValueOf = GetStaticMethodIDOrDie(env, gLongClazz, "valueOf", "(J)Ljava/lang/Long;");
+    gVintfObjectClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, kVintfObjectPathName));
+    gRunCommand = GetStaticMethodIDOrDie(env, gVintfObjectClazz, "runShellCommand",
+                                         "(Ljava/lang/String;)Ljava/lang/String;");
 
     return RegisterMethodsOrDie(env, kVintfObjectPathName, gVintfObjectMethods,
-            NELEM(gVintfObjectMethods));
+                                NELEM(gVintfObjectMethods));
 }
 
 extern int register_android_os_VintfRuntimeInfo(JNIEnv* env);
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 871feb6..99909a1 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -211,6 +211,8 @@
         "src/com/android/internal/util/**/*.java",
         "src/com/android/internal/power/EnergyConsumerStatsTest.java",
         ":FrameworksCoreTests{.aapt.srcjar}",
+        "src/com/android/internal/ravenwood/**/*.java",
+
         ":FrameworksCoreTests-aidl",
         ":FrameworksCoreTests-helpers",
         ":FrameworksCoreTestDoubles-sources",
diff --git a/core/tests/coretests/src/com/android/internal/content/res/OverlayConfigParserTest.java b/core/tests/coretests/src/com/android/internal/content/res/OverlayConfigParserTest.java
new file mode 100644
index 0000000..4eccbe5
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/content/res/OverlayConfigParserTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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.internal.content.res;
+
+import static com.android.internal.content.om.OverlayConfigParser.SysPropWrapper;
+
+import static org.junit.Assert.assertEquals;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.content.om.OverlayConfigParser;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class OverlayConfigParserTest {
+    @Test(expected = IllegalStateException.class)
+    public void testMergePropNotRoProp() {
+        SysPropWrapper sysProp = p -> {
+            return "dummy_value";
+        };
+        OverlayConfigParser.expandProperty("${persist.value}/path", sysProp);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testMergePropMissingEndBracket() {
+        SysPropWrapper sysProp = p -> {
+            return "dummy_value";
+        };
+        OverlayConfigParser.expandProperty("${ro.value/path", sysProp);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testMergeOnlyPropStart() {
+        SysPropWrapper sysProp = p -> {
+            return "dummy_value";
+        };
+        OverlayConfigParser.expandProperty("path/${", sysProp);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testMergePropInProp() {
+        SysPropWrapper sysProp = p -> {
+            return "dummy_value";
+        };
+        OverlayConfigParser.expandProperty("path/${${ro.value}}", sysProp);
+    }
+
+    /**
+     * The path is only allowed to contain one property.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testMergePropMultipleProps() {
+        SysPropWrapper sysProp = p -> {
+            return "dummy_value";
+        };
+        OverlayConfigParser.expandProperty("${ro.value}/path${ro.value2}/path", sysProp);
+    }
+
+    @Test
+    public void testMergePropOneProp() {
+        final SysPropWrapper sysProp = p -> {
+            if ("ro.value".equals(p)) {
+                return "dummy_value";
+            } else {
+                return "invalid";
+            }
+        };
+
+        // Property in the beginnig of the string
+        String result = OverlayConfigParser.expandProperty("${ro.value}/path",
+                sysProp);
+        assertEquals("dummy_value/path", result);
+
+        // Property in the middle of the string
+        result = OverlayConfigParser.expandProperty("path/${ro.value}/file",
+                sysProp);
+        assertEquals("path/dummy_value/file", result);
+
+        // Property at the of the string
+        result = OverlayConfigParser.expandProperty("path/${ro.value}",
+                sysProp);
+        assertEquals("path/dummy_value", result);
+
+        // Property is the entire string
+        result = OverlayConfigParser.expandProperty("${ro.value}",
+                sysProp);
+        assertEquals("dummy_value", result);
+    }
+
+    @Test
+    public void testMergePropNoProp() {
+        final SysPropWrapper sysProp = p -> {
+            return "dummy_value";
+        };
+
+        final String path = "no_props/path";
+        String result = OverlayConfigParser.expandProperty(path, sysProp);
+        assertEquals(path, result);
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java b/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java
new file mode 100644
index 0000000..d1ef61b
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java
@@ -0,0 +1,38 @@
+/*
+ * 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.internal.ravenwood;
+
+import static junit.framework.TestCase.assertEquals;
+
+import android.platform.test.ravenwood.RavenwoodRule;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class RavenwoodEnvironmentTest {
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule();
+
+    @Test
+    public void testIsRunningOnRavenwood() {
+        assertEquals(RavenwoodRule.isUnderRavenwood(),
+                RavenwoodEnvironment.getInstance().isRunningOnRavenwood());
+    }
+}
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index d915b74..1c20141 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -143,7 +143,7 @@
          * the decoder will try to pick the best matching config based on the
          * system's screen depth, and characteristics of the original image such
          * as if it has per-pixel alpha (requiring a config that also does).
-         * 
+         *
          * Image are loaded with the {@link Bitmap.Config#ARGB_8888} config by
          * default.
          */
@@ -183,7 +183,7 @@
 
         /**
          * If true (which is the default), the resulting bitmap will have its
-         * color channels pre-multipled by the alpha channel.
+         * color channels pre-multiplied by the alpha channel.
          *
          * <p>This should NOT be set to false for images to be directly drawn by
          * the view system or through a {@link Canvas}. The view system and
@@ -221,9 +221,9 @@
          * if {@link #inScaled} is set (which it is by default} and this
          * density does not match {@link #inTargetDensity}, then the bitmap
          * will be scaled to the target density before being returned.
-         * 
+         *
          * <p>If this is 0,
-         * {@link BitmapFactory#decodeResource(Resources, int)}, 
+         * {@link BitmapFactory#decodeResource(Resources, int)},
          * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)},
          * and {@link BitmapFactory#decodeResourceStream}
          * will fill in the density associated with the resource.  The other
@@ -242,29 +242,29 @@
          * This is used in conjunction with {@link #inDensity} and
          * {@link #inScaled} to determine if and how to scale the bitmap before
          * returning it.
-         * 
+         *
          * <p>If this is 0,
-         * {@link BitmapFactory#decodeResource(Resources, int)}, 
+         * {@link BitmapFactory#decodeResource(Resources, int)},
          * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)},
          * and {@link BitmapFactory#decodeResourceStream}
          * will fill in the density associated the Resources object's
          * DisplayMetrics.  The other
          * functions will leave it as-is and no scaling for density will be
          * performed.
-         * 
+         *
          * @see #inDensity
          * @see #inScreenDensity
          * @see #inScaled
          * @see android.util.DisplayMetrics#densityDpi
          */
         public int inTargetDensity;
-        
+
         /**
          * The pixel density of the actual screen that is being used.  This is
          * purely for applications running in density compatibility code, where
          * {@link #inTargetDensity} is actually the density the application
          * sees rather than the real screen density.
-         * 
+         *
          * <p>By setting this, you
          * allow the loading code to avoid scaling a bitmap that is currently
          * in the screen density up/down to the compatibility density.  Instead,
@@ -274,18 +274,18 @@
          * Bitmap.getScaledWidth} and {@link Bitmap#getScaledHeight
          * Bitmap.getScaledHeight} to account for any different between the
          * bitmap's density and the target's density.
-         * 
+         *
          * <p>This is never set automatically for the caller by
          * {@link BitmapFactory} itself.  It must be explicitly set, since the
          * caller must deal with the resulting bitmap in a density-aware way.
-         * 
+         *
          * @see #inDensity
          * @see #inTargetDensity
          * @see #inScaled
          * @see android.util.DisplayMetrics#densityDpi
          */
         public int inScreenDensity;
-        
+
         /**
          * When this flag is set, if {@link #inDensity} and
          * {@link #inTargetDensity} are not 0, the
@@ -345,7 +345,7 @@
          * ignored.
          *
          * In {@link android.os.Build.VERSION_CODES#KITKAT} and below, this
-         * field works in conjuction with inPurgeable. If inPurgeable is false,
+         * field works in conjunction with inPurgeable. If inPurgeable is false,
          * then this field is ignored. If inPurgeable is true, then this field
          * determines whether the bitmap can share a reference to the input
          * data (inputstream, array, etc.) or if it must make a deep copy.
@@ -583,11 +583,11 @@
                 opts.inDensity = density;
             }
         }
-        
+
         if (opts.inTargetDensity == 0 && res != null) {
             opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
         }
-        
+
         return decodeStream(is, pad, opts);
     }
 
@@ -611,8 +611,8 @@
     public static Bitmap decodeResource(Resources res, int id, Options opts) {
         validate(opts);
         Bitmap bm = null;
-        InputStream is = null; 
-        
+        InputStream is = null;
+
         try {
             final TypedValue value = new TypedValue();
             is = res.openRawResource(id, value);
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index d1aceaf..5291f7b 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -52,7 +52,7 @@
  * Canvas and Drawables</a> developer guide.</p></div>
  */
 public class Canvas extends BaseCanvas {
-    private static int sCompatiblityVersion = 0;
+    private static int sCompatibilityVersion = 0;
     private static boolean sCompatibilityRestore = false;
     private static boolean sCompatibilitySetBitmap = false;
 
@@ -71,7 +71,7 @@
 
     // Maximum bitmap size as defined in Skia's native code
     // (see SkCanvas.cpp, SkDraw.cpp)
-    private static final int MAXMIMUM_BITMAP_SIZE = 32766;
+    private static final int MAXIMUM_BITMAP_SIZE = 32766;
 
     // Use a Holder to allow static initialization of Canvas in the boot image.
     private static class NoImagePreloadHolder {
@@ -316,7 +316,7 @@
      * @see #getMaximumBitmapHeight()
      */
     public int getMaximumBitmapWidth() {
-        return MAXMIMUM_BITMAP_SIZE;
+        return MAXIMUM_BITMAP_SIZE;
     }
 
     /**
@@ -327,7 +327,7 @@
      * @see #getMaximumBitmapWidth()
      */
     public int getMaximumBitmapHeight() {
-        return MAXMIMUM_BITMAP_SIZE;
+        return MAXIMUM_BITMAP_SIZE;
     }
 
     // the SAVE_FLAG constants must match their native equivalents
@@ -408,7 +408,7 @@
     public static final int ALL_SAVE_FLAG = 0x1F;
 
     private static void checkValidSaveFlags(int saveFlags) {
-        if (sCompatiblityVersion >= Build.VERSION_CODES.P
+        if (sCompatibilityVersion >= Build.VERSION_CODES.P
                 && saveFlags != ALL_SAVE_FLAG) {
             throw new IllegalArgumentException(
                     "Invalid Layer Save Flag - only ALL_SAVE_FLAGS is allowed");
@@ -817,7 +817,7 @@
     }
 
     private static void checkValidClipOp(@NonNull Region.Op op) {
-        if (sCompatiblityVersion >= Build.VERSION_CODES.P
+        if (sCompatibilityVersion >= Build.VERSION_CODES.P
                 && op != Region.Op.INTERSECT && op != Region.Op.DIFFERENCE) {
             throw new IllegalArgumentException(
                     "Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed");
@@ -1383,7 +1383,7 @@
     }
 
     /*package*/ static void setCompatibilityVersion(int apiLevel) {
-        sCompatiblityVersion = apiLevel;
+        sCompatibilityVersion = apiLevel;
         sCompatibilityRestore = apiLevel < Build.VERSION_CODES.M;
         sCompatibilitySetBitmap = apiLevel < Build.VERSION_CODES.O;
         nSetCompatibilityVersion(apiLevel);
diff --git a/graphics/java/android/graphics/ComposePathEffect.java b/graphics/java/android/graphics/ComposePathEffect.java
index 3fc9eb5..7d59ece 100644
--- a/graphics/java/android/graphics/ComposePathEffect.java
+++ b/graphics/java/android/graphics/ComposePathEffect.java
@@ -20,13 +20,13 @@
 
     /**
      * Construct a PathEffect whose effect is to apply first the inner effect
-     * and the the outer pathEffect (e.g. outer(inner(path))).
+     * and the outer pathEffect (e.g. outer(inner(path))).
      */
     public ComposePathEffect(PathEffect outerpe, PathEffect innerpe) {
         native_instance = nativeCreate(outerpe.native_instance,
                                        innerpe.native_instance);
     }
-    
+
     private static native long nativeCreate(long nativeOuterpe,
                                             long nativeInnerpe);
 }
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index f50de16..91fa1a6 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -215,7 +215,7 @@
 
     @CriticalNative
     private static native long nGetFamilyReleaseFunc();
-    // By passing -1 to weigth argument, the weight value is resolved by OS/2 table in the font.
+    // By passing -1 to weight argument, the weight value is resolved by OS/2 table in the font.
     // By passing -1 to italic argument, the italic value is resolved by OS/2 table in the font.
     private static native boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex,
             int weight, int isItalic);
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 52b0b95..2d3ffb5 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -127,7 +127,7 @@
             parser.setInput(is, null);
             parser.nextTag();
             return readFamilies(parser, systemFontDir, oemCustomization, updatableFontMap,
-                    lastModifiedDate, configVersion, false /* filter out the non-exising files */);
+                    lastModifiedDate, configVersion, false /* filter out the non-existing files */);
         }
     }
 
@@ -254,7 +254,7 @@
      * @param parser An XML parser.
      * @param fontDir a font directory name.
      * @param updatableFontMap a updated font file map.
-     * @param allowNonExistingFile true to allow font file that doesn't exists
+     * @param allowNonExistingFile true to allow font file that doesn't exist.
      * @return a FontFamily instance. null if no font files are available in this FontFamily.
      */
     public static @Nullable FontConfig.FontFamily readFamily(XmlPullParser parser, String fontDir,
diff --git a/graphics/java/android/graphics/FrameInfo.java b/graphics/java/android/graphics/FrameInfo.java
index b3615ff..8f12828 100644
--- a/graphics/java/android/graphics/FrameInfo.java
+++ b/graphics/java/android/graphics/FrameInfo.java
@@ -24,7 +24,7 @@
 /**
  * Class that contains all the timing information for the current frame. This
  * is used in conjunction with the hardware renderer to provide
- * continous-monitoring jank events
+ * continuous-monitoring jank events
  *
  * All times in nanoseconds from CLOCK_MONOTONIC/System.nanoTime()
  *
diff --git a/graphics/java/android/graphics/Interpolator.java b/graphics/java/android/graphics/Interpolator.java
index 1045464..418922f7 100644
--- a/graphics/java/android/graphics/Interpolator.java
+++ b/graphics/java/android/graphics/Interpolator.java
@@ -25,13 +25,13 @@
         mFrameCount = 2;
         native_instance = nativeConstructor(valueCount, 2);
     }
-    
+
     public Interpolator(int valueCount, int frameCount) {
         mValueCount = valueCount;
         mFrameCount = frameCount;
         native_instance = nativeConstructor(valueCount, frameCount);
     }
-    
+
     /**
      * Reset the Interpolator to have the specified number of values and an
      * implicit keyFrame count of 2 (just a start and end). After this call the
@@ -40,7 +40,7 @@
     public void reset(int valueCount) {
         reset(valueCount, 2);
     }
-    
+
     /**
      * Reset the Interpolator to have the specified number of values and
      * keyFrames. After this call the values for each keyFrame must be assigned
@@ -51,20 +51,20 @@
         mFrameCount = frameCount;
         nativeReset(native_instance, valueCount, frameCount);
     }
-    
+
     public final int getKeyFrameCount() {
         return mFrameCount;
     }
-    
+
     public final int getValueCount() {
         return mValueCount;
     }
-    
+
     /**
      * Assign the keyFrame (specified by index) a time value and an array of key
-     * values (with an implicity blend array of [0, 0, 1, 1] giving linear
+     * values (with an implicitly blend array of [0, 0, 1, 1] giving linear
      * transition to the next set of key values).
-     * 
+     *
      * @param index The index of the key frame to assign
      * @param msec The time (in mililiseconds) for this key frame. Based on the
      *        SystemClock.uptimeMillis() clock
@@ -77,7 +77,7 @@
     /**
      * Assign the keyFrame (specified by index) a time value and an array of key
      * values and blend array.
-     * 
+     *
      * @param index The index of the key frame to assign
      * @param msec The time (in mililiseconds) for this key frame. Based on the
      *        SystemClock.uptimeMillis() clock
@@ -96,7 +96,7 @@
         }
         nativeSetKeyFrame(native_instance, index, msec, values, blend);
     }
-    
+
     /**
      * Set a repeat count (which may be fractional) for the interpolator, and
      * whether the interpolator should mirror its repeats. The default settings
@@ -107,7 +107,7 @@
             nativeSetRepeatMirror(native_instance, repeatCount, mirror);
         }
     }
-    
+
     public enum Result {
         NORMAL,
         FREEZE_START,
@@ -127,7 +127,7 @@
      * return whether the specified time was within the range of key times
      * (NORMAL), was before the first key time (FREEZE_START) or after the last
      * key time (FREEZE_END). In any event, computed values are always returned.
-     * 
+     *
      * @param msec The time (in milliseconds) used to sample into the
      *        Interpolator. Based on the SystemClock.uptimeMillis() clock
      * @param values Where to write the computed values (may be NULL).
@@ -143,13 +143,13 @@
             default: return Result.FREEZE_END;
         }
     }
-    
+
     @Override
     protected void finalize() throws Throwable {
         nativeDestructor(native_instance);
         native_instance = 0;  // Other finalizers can still call us.
     }
-    
+
     private int mValueCount;
     private int mFrameCount;
     private long native_instance;
diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java
index 0aa6f12..fe73a1a 100644
--- a/graphics/java/android/graphics/LightingColorFilter.java
+++ b/graphics/java/android/graphics/LightingColorFilter.java
@@ -16,8 +16,8 @@
 
 // This file was generated from the C++ include file: SkColorFilter.h
 // Any changes made to this file will be discarded by the build.
-// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, 
-// or one of the auxilary file specifications in device/tools/gluemaker.
+// To change this file, either edit the include, or device/tools/gluemaker/main.cpp,
+// or one of the auxiliary file specifications in device/tools/gluemaker.
 
 package android.graphics;
 
diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java
index 56d912b..0879371 100644
--- a/graphics/java/android/graphics/LinearGradient.java
+++ b/graphics/java/android/graphics/LinearGradient.java
@@ -63,7 +63,7 @@
      * @param colors       The sRGB colors to be distributed along the gradient line
      * @param positions    May be null. The relative positions [0..1] of
      *                     each corresponding color in the colors array. If this is null,
-     *                     the the colors are distributed evenly along the gradient line.
+     *                     the colors are distributed evenly along the gradient line.
      * @param tile         The Shader tiling mode
      */
     public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int[] colors,
@@ -82,7 +82,7 @@
      * @param colors       The colors to be distributed along the gradient line
      * @param positions    May be null. The relative positions [0..1] of
      *                     each corresponding color in the colors array. If this is null,
-     *                     the the colors are distributed evenly along the gradient line.
+     *                     the colors are distributed evenly along the gradient line.
      * @param tile         The Shader tiling mode
      *
      * @throws IllegalArgumentException if there are less than two colors, the colors do
diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java
index bc58feb..66553d8 100644
--- a/graphics/java/android/graphics/Matrix.java
+++ b/graphics/java/android/graphics/Matrix.java
@@ -559,7 +559,7 @@
 
     /**
      * Set the matrix to the scale and translate values that map the source rectangle to the
-     * destination rectangle, returning true if the the result can be represented.
+     * destination rectangle, returning true if the result can be represented.
      *
      * @param src the source rectangle to map from.
      * @param dst the destination rectangle to map to.
diff --git a/graphics/java/android/graphics/Mesh.java b/graphics/java/android/graphics/Mesh.java
index a4bce9e..6be8332 100644
--- a/graphics/java/android/graphics/Mesh.java
+++ b/graphics/java/android/graphics/Mesh.java
@@ -271,7 +271,7 @@
      * not have a uniform with that name or if the uniform is declared with a type other than int
      * or int[1] then an IllegalArgumentException is thrown.
      *
-     * @param uniformName name matching the int uniform delcared in the shader program.
+     * @param uniformName name matching the int uniform declared in the shader program.
      * @param value       value corresponding to the int uniform with the given name.
      */
     public void setIntUniform(@NonNull String uniformName, int value) {
@@ -283,7 +283,7 @@
      * not have a uniform with that name or if the uniform is declared with a type other than ivec2
      * or int[2] then an IllegalArgumentException is thrown.
      *
-     * @param uniformName name matching the int uniform delcared in the shader program.
+     * @param uniformName name matching the int uniform declared in the shader program.
      * @param value1      first value corresponding to the int uniform with the given name.
      * @param value2      second value corresponding to the int uniform with the given name.
      */
@@ -296,7 +296,7 @@
      * not have a uniform with that name or if the uniform is declared with a type other than ivec3
      * or int[3] then an IllegalArgumentException is thrown.
      *
-     * @param uniformName name matching the int uniform delcared in the shader program.
+     * @param uniformName name matching the int uniform declared in the shader program.
      * @param value1      first value corresponding to the int uniform with the given name.
      * @param value2      second value corresponding to the int uniform with the given name.
      * @param value3      third value corresponding to the int uniform with the given name.
@@ -310,7 +310,7 @@
      * not have a uniform with that name or if the uniform is declared with a type other than ivec4
      * or int[4] then an IllegalArgumentException is thrown.
      *
-     * @param uniformName name matching the int uniform delcared in the shader program.
+     * @param uniformName name matching the int uniform declared in the shader program.
      * @param value1      first value corresponding to the int uniform with the given name.
      * @param value2      second value corresponding to the int uniform with the given name.
      * @param value3      third value corresponding to the int uniform with the given name.
@@ -327,7 +327,7 @@
      * int (for N=1), ivecN, or int[N], where N is the length of the values param, then an
      * IllegalArgumentException is thrown.
      *
-     * @param uniformName name matching the int uniform delcared in the shader program.
+     * @param uniformName name matching the int uniform declared in the shader program.
      * @param values      int values corresponding to the vec4 int uniform with the given name.
      */
     public void setIntUniform(@NonNull String uniformName, @NonNull int[] values) {
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index af20957..382269f 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -22,12 +22,12 @@
  * The NinePatch class permits drawing a bitmap in nine or more sections.
  * Essentially, it allows the creation of custom graphics that will scale the
  * way that you define, when content added within the image exceeds the normal
- * bounds of the graphic. For a thorough explanation of a NinePatch image, 
- * read the discussion in the 
+ * bounds of the graphic. For a thorough explanation of a NinePatch image,
+ * read the discussion in the
  * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">2D
  * Graphics</a> document.
  * <p>
- * The <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-Patch</a> 
+ * The <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-Patch</a>
  * tool offers an extremely handy way to create your NinePatch images,
  * using a WYSIWYG graphics editor.
  * </p>
@@ -104,7 +104,7 @@
         this(bitmap, chunk, null);
     }
 
-    /** 
+    /**
      * Create a drawable projection from a bitmap to nine patches.
      *
      * @param bitmap The bitmap describing the patches.
@@ -122,7 +122,7 @@
     protected void finalize() throws Throwable {
         try {
             if (mNativeChunk != 0) {
-                // only attempt to destroy correctly initilized chunks
+                // only attempt to destroy correctly initialized chunks
                 nativeFinalize(mNativeChunk);
                 mNativeChunk = 0;
             }
@@ -169,8 +169,8 @@
     public Bitmap getBitmap() {
         return mBitmap;
     }
-    
-    /** 
+
+    /**
      * Draws the NinePatch. This method will use the paint returned by {@link #getPaint()}.
      *
      * @param canvas A container for the current matrix and clip used to draw the NinePatch.
@@ -180,7 +180,7 @@
         canvas.drawPatch(this, location, mPaint);
     }
 
-    /** 
+    /**
      * Draws the NinePatch. This method will use the paint returned by {@link #getPaint()}.
      *
      * @param canvas A container for the current matrix and clip used to draw the NinePatch.
@@ -190,7 +190,7 @@
         canvas.drawPatch(this, location, mPaint);
     }
 
-    /** 
+    /**
      * Draws the NinePatch. This method will ignore the paint returned
      * by {@link #getPaint()} and use the specified paint instead.
      *
diff --git a/graphics/java/android/graphics/PathMeasure.java b/graphics/java/android/graphics/PathMeasure.java
index 5500c52..2c6cfa5 100644
--- a/graphics/java/android/graphics/PathMeasure.java
+++ b/graphics/java/android/graphics/PathMeasure.java
@@ -25,14 +25,14 @@
      * setPath.
      *
      * Note that once a path is associated with the measure object, it is
-     * undefined if the path is subsequently modified and the the measure object
+     * undefined if the path is subsequently modified and the measure object
      * is used. If the path is modified, you must call setPath with the path.
      */
     public PathMeasure() {
         mPath = null;
         native_instance = native_create(0, false);
     }
-    
+
     /**
      * Create a PathMeasure object associated with the specified path object
      * (already created and specified). The measure object can now return the
@@ -40,7 +40,7 @@
      * path.
      *
      * Note that once a path is associated with the measure object, it is
-     * undefined if the path is subsequently modified and the the measure object
+     * undefined if the path is subsequently modified and the measure object
      * is used. If the path is modified, you must call setPath with the path.
      *
      * @param path The path that will be measured by this object
@@ -121,7 +121,7 @@
      * such as <code>dst.rLineTo(0, 0)</code>.</p>
      */
     public boolean getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo) {
-        // Skia used to enforce this as part of it's API, but has since relaxed that restriction
+        // Skia used to enforce this as part of its API, but has since relaxed that restriction
         // so to maintain consistency in our API we enforce the preconditions here.
         float length = getLength();
         if (startD < 0) {
diff --git a/graphics/java/android/graphics/Rasterizer.java b/graphics/java/android/graphics/Rasterizer.java
index 29d82fa..5750954 100644
--- a/graphics/java/android/graphics/Rasterizer.java
+++ b/graphics/java/android/graphics/Rasterizer.java
@@ -16,8 +16,8 @@
 
 // This file was generated from the C++ include file: SkRasterizer.h
 // Any changes made to this file will be discarded by the build.
-// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, 
-// or one of the auxilary file specifications in device/tools/gluemaker.
+// To change this file, either edit the include, or device/tools/gluemaker/main.cpp,
+// or one of the auxiliary file specifications in device/tools/gluemaker.
 
 package android.graphics;
 
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 411a10b..5211e3a 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -165,7 +165,7 @@
     public String toShortString() {
         return toShortString(new StringBuilder(32));
     }
-    
+
     /**
      * Return a string representation of the rectangle in a compact form.
      * @hide
@@ -184,7 +184,7 @@
      *
      * <p>You can later recover the Rect from this string through
      * {@link #unflattenFromString(String)}.
-     * 
+     *
      * @return Returns a new String of the form "left top right bottom"
      */
     @NonNull
@@ -314,7 +314,7 @@
     public final int height() {
         return bottom - top;
     }
-    
+
     /**
      * @return the horizontal center of the rectangle. If the computed value
      *         is fractional, this method returns the largest integer that is
@@ -323,7 +323,7 @@
     public final int centerX() {
         return (left + right) >> 1;
     }
-    
+
     /**
      * @return the vertical center of the rectangle. If the computed value
      *         is fractional, this method returns the largest integer that is
@@ -332,14 +332,14 @@
     public final int centerY() {
         return (top + bottom) >> 1;
     }
-    
+
     /**
      * @return the exact horizontal center of the rectangle as a float.
      */
     public final float exactCenterX() {
         return (left + right) * 0.5f;
     }
-    
+
     /**
      * @return the exact vertical center of the rectangle as a float.
      */
@@ -493,7 +493,7 @@
      * @param top The top of the rectangle being tested for containment
      * @param right The right side of the rectangle being tested for containment
      * @param bottom The bottom of the rectangle being tested for containment
-     * @return true iff the the 4 specified sides of a rectangle are inside or
+     * @return true iff the 4 specified sides of a rectangle are inside or
      *              equal to this rectangle
      */
     public boolean contains(int left, int top, int right, int bottom) {
@@ -548,7 +548,7 @@
         }
         return false;
     }
-    
+
     /**
      * If the specified rectangle intersects this rectangle, return true and set
      * this rectangle to that intersection, otherwise return false and do not
@@ -670,7 +670,7 @@
     public void union(@NonNull Rect r) {
         union(r.left, r.top, r.right, r.bottom);
     }
-    
+
     /**
      * Update this Rect to enclose itself and the [x,y] coordinate. There is no
      * check to see that this rectangle is non-empty.
diff --git a/graphics/java/android/graphics/RectF.java b/graphics/java/android/graphics/RectF.java
index ff50a0c..5b9b764 100644
--- a/graphics/java/android/graphics/RectF.java
+++ b/graphics/java/android/graphics/RectF.java
@@ -38,7 +38,7 @@
     public float top;
     public float right;
     public float bottom;
-    
+
     /**
      * Create a new empty RectF. All coordinates are initialized to 0.
      */
@@ -78,7 +78,7 @@
             bottom = r.bottom;
         }
     }
-    
+
     public RectF(@Nullable Rect r) {
         if (r == null) {
             left = top = right = bottom = 0.0f;
@@ -121,7 +121,7 @@
     public String toShortString() {
         return toShortString(new StringBuilder(32));
     }
-    
+
     /**
      * Return a string representation of the rectangle in a compact form.
      * @hide
@@ -134,7 +134,7 @@
         sb.append(','); sb.append(bottom); sb.append(']');
         return sb.toString();
     }
-    
+
     /**
      * Print short representation to given writer.
      * @hide
@@ -183,14 +183,14 @@
     public final float centerY() {
         return (top + bottom) * 0.5f;
     }
-    
+
     /**
      * Set the rectangle to (0,0,0,0)
      */
     public void setEmpty() {
         left = right = top = bottom = 0;
     }
-    
+
     /**
      * Set the rectangle's coordinates to the specified values. Note: no range
      * checking is performed, so it is up to the caller to ensure that
@@ -220,7 +220,7 @@
         this.right  = src.right;
         this.bottom = src.bottom;
     }
-    
+
     /**
      * Copy the coordinates from src into this rectangle.
      *
@@ -261,7 +261,7 @@
         left = newLeft;
         top = newTop;
     }
-    
+
     /**
      * Inset the rectangle by (dx,dy). If dx is positive, then the sides are
      * moved inwards, making the rectangle narrower. If dx is negative, then the
@@ -293,7 +293,7 @@
         return left < right && top < bottom  // check for empty first
                 && x >= left && x < right && y >= top && y < bottom;
     }
-    
+
     /**
      * Returns true iff the 4 specified sides of a rectangle are inside or equal
      * to this rectangle. i.e. is this rectangle a superset of the specified
@@ -303,7 +303,7 @@
      * @param top The top of the rectangle being tested for containment
      * @param right The right side of the rectangle being tested for containment
      * @param bottom The bottom of the rectangle being tested for containment
-     * @return true iff the the 4 specified sides of a rectangle are inside or
+     * @return true iff the 4 specified sides of a rectangle are inside or
      *              equal to this rectangle
      */
     public boolean contains(float left, float top, float right, float bottom) {
@@ -313,7 +313,7 @@
                 && this.left <= left && this.top <= top
                 && this.right >= right && this.bottom >= bottom;
     }
-    
+
     /**
      * Returns true iff the specified rectangle r is inside or equal to this
      * rectangle. An empty rectangle never contains another rectangle.
@@ -329,7 +329,7 @@
                 && left <= r.left && top <= r.top
                 && right >= r.right && bottom >= r.bottom;
     }
-    
+
     /**
      * If the rectangle specified by left,top,right,bottom intersects this
      * rectangle, return true and set this rectangle to that intersection,
@@ -367,7 +367,7 @@
         }
         return false;
     }
-    
+
     /**
      * If the specified rectangle intersects this rectangle, return true and set
      * this rectangle to that intersection, otherwise return false and do not
@@ -382,7 +382,7 @@
     public boolean intersect(@NonNull RectF r) {
         return intersect(r.left, r.top, r.right, r.bottom);
     }
-    
+
     /**
      * If rectangles a and b intersect, return true and set this rectangle to
      * that intersection, otherwise return false and do not change this
@@ -406,7 +406,7 @@
         }
         return false;
     }
-    
+
     /**
      * Returns true if this rectangle intersects the specified rectangle.
      * In no event is this rectangle modified. No check is performed to see
@@ -426,7 +426,7 @@
         return this.left < right && left < this.right
                 && this.top < bottom && top < this.bottom;
     }
-    
+
     /**
      * Returns true iff the two specified rectangles intersect. In no event are
      * either of the rectangles modified. To record the intersection,
@@ -441,7 +441,7 @@
         return a.left < b.right && b.left < a.right
                 && a.top < b.bottom && b.top < a.bottom;
     }
-    
+
     /**
      * Set the dst integer Rect by rounding this rectangle's coordinates
      * to their nearest integer values.
@@ -489,7 +489,7 @@
             }
         }
     }
-    
+
     /**
      * Update this Rect to enclose itself and the specified rectangle. If the
      * specified rectangle is empty, nothing is done. If this rectangle is empty
@@ -500,7 +500,7 @@
     public void union(@NonNull RectF r) {
         union(r.left, r.top, r.right, r.bottom);
     }
-    
+
     /**
      * Update this Rect to enclose itself and the [x,y] coordinate. There is no
      * check to see that this rectangle is non-empty.
@@ -520,7 +520,7 @@
             bottom = y;
         }
     }
-    
+
     /**
      * Swap top/bottom or left/right if there are flipped (i.e. left > right
      * and/or top > bottom). This can be called if
@@ -548,7 +548,7 @@
     public int describeContents() {
         return 0;
     }
-    
+
     /**
      * Write this rectangle to the specified parcel. To restore a rectangle from
      * a parcel, use readFromParcel()
@@ -561,7 +561,7 @@
         out.writeFloat(right);
         out.writeFloat(bottom);
     }
-    
+
     public static final @android.annotation.NonNull Parcelable.Creator<RectF> CREATOR = new Parcelable.Creator<RectF>() {
         /**
          * Return a new rectangle from the data in the specified parcel.
@@ -572,7 +572,7 @@
             r.readFromParcel(in);
             return r;
         }
-        
+
         /**
          * Return an array of rectangles of the specified size.
          */
@@ -581,7 +581,7 @@
             return new RectF[size];
         }
     };
-    
+
     /**
      * Set the rectangle's coordinates from the data stored in the specified
      * parcel. To write a rectangle to a parcel, call writeToParcel().
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 2732569..0650b78 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -765,12 +765,12 @@
      * Default value is false. See
      * {@link #setProjectBackwards(boolean)} for a description of what this entails.
      *
-     * @param shouldRecieve True if this RenderNode is a projection receiver, false otherwise.
+     * @param shouldReceive True if this RenderNode is a projection receiver, false otherwise.
      *                      Default is false.
      * @return True if the value changed, false if the new value was the same as the previous value.
      */
-    public boolean setProjectionReceiver(boolean shouldRecieve) {
-        return nSetProjectionReceiver(mNativeRenderNode, shouldRecieve);
+    public boolean setProjectionReceiver(boolean shouldReceive) {
+        return nSetProjectionReceiver(mNativeRenderNode, shouldReceive);
     }
 
     /**
@@ -1799,7 +1799,7 @@
     private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject);
 
     @CriticalNative
-    private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve);
+    private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldReceive);
 
     @CriticalNative
     private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top,
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index dd82fed..c1b531f 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -318,7 +318,7 @@
     }
 
     /**
-     * Releases the the texture content. This is needed in single buffered mode to allow the image
+     * Releases the texture content. This is needed in single buffered mode to allow the image
      * content producer to take ownership of the image buffer.
      * <p>
      * For more information see {@link #SurfaceTexture(int, boolean)}.
@@ -431,7 +431,7 @@
      * error.
      * <p>
      * Note that while calling this method causes all the buffers to be freed
-     * from the perspective of the the SurfaceTexture, if there are additional
+     * from the perspective of the SurfaceTexture, if there are additional
      * references on the buffers (e.g. if a buffer is referenced by a client or
      * by OpenGL ES as a texture) then those buffer will remain allocated.
      * <p>
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 4c4e8fa..fd78816 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -600,7 +600,7 @@
          * {@link #setWeight} and {@link #setItalic}.
          *
          * If {@link #setWeight} is not called, the fallback family keeps the default weight.
-         * Similary, if {@link #setItalic} is not called, the fallback family keeps the default
+         * Similarly, if {@link #setItalic} is not called, the fallback family keeps the default
          * italic information. For example, calling {@code builder.setFallback("sans-serif-light")}
          * is equivalent to calling {@code builder.setFallback("sans-serif").setWeight(300)} in
          * terms of fallback. The default weight and italic information are overridden by calling
@@ -794,7 +794,7 @@
         /**
          * Returns the maximum capacity of custom fallback families.
          *
-         * This includes the the first font family passed to the constructor.
+         * This includes the first font family passed to the constructor.
          * It is guaranteed that the value will be greater than or equal to 64.
          *
          * @return the maximum number of font families for the custom fallback
@@ -816,7 +816,7 @@
         /**
          * Sets a system fallback by name.
          *
-         * You can specify generic font familiy names or OEM specific family names. If the system
+         * You can specify generic font family names or OEM specific family names. If the system
          * don't have a specified fallback, the default fallback is used instead.
          * For more information about generic font families, see <a
          * href="https://www.w3.org/TR/css-fonts-4/#generic-font-families">CSS specification</a>
diff --git a/graphics/java/android/graphics/Xfermode.java b/graphics/java/android/graphics/Xfermode.java
index 81769e2..6bb22a1 100644
--- a/graphics/java/android/graphics/Xfermode.java
+++ b/graphics/java/android/graphics/Xfermode.java
@@ -16,8 +16,8 @@
 
 // This file was generated from the C++ include file: SkXfermode.h
 // Any changes made to this file will be discarded by the build.
-// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, 
-// or one of the auxilary file specifications in device/tools/gluemaker.
+// To change this file, either edit the include, or device/tools/gluemaker/main.cpp,
+// or one of the auxiliary file specifications in device/tools/gluemaker.
 
 package android.graphics;
 
@@ -28,7 +28,7 @@
  * Xfermode is the base class for objects that are called to implement custom
  * "transfer-modes" in the drawing pipeline. The static function Create(Modes)
  * can be called to return an instance of any of the predefined subclasses as
- * specified in the Modes enum. When an Xfermode is assigned to an Paint, then
+ * specified in the Modes enum. When an Xfermode is assigned to a Paint, then
  * objects drawn with that paint have the xfermode applied.
  */
 public class Xfermode {
diff --git a/graphics/java/android/graphics/YuvImage.java b/graphics/java/android/graphics/YuvImage.java
index ce35b55..b0c7f20 100644
--- a/graphics/java/android/graphics/YuvImage.java
+++ b/graphics/java/android/graphics/YuvImage.java
@@ -63,7 +63,7 @@
     private int mWidth;
 
     /**
-     * The height of the the image.
+     * The height of the image.
      */
     private int mHeight;
 
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index 688425a..7ee7d6b 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -98,7 +98,7 @@
      * extra content to reveal within the clip path when performing affine transformations on the
      * layers.
      *
-     * Each layers will reserve 25% of it's width and height.
+     * Each layers will reserve 25% of its width and height.
      *
      * As a result, the view port of the layers is smaller than their intrinsic width and height.
      */
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 4972e92..7f2feac 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -839,7 +839,7 @@
     }
 
     /**
-     * Describes the current state, as a union of primitve states, such as
+     * Describes the current state, as a union of primitive states, such as
      * {@link android.R.attr#state_focused},
      * {@link android.R.attr#state_selected}, etc.
      * Some drawables may modify their imagery based on the selected state.
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 166a795..29d033e 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -936,7 +936,7 @@
     }
 
     /**
-     * Retrn the inner radius of the ring
+     * Return the inner radius of the ring
      *
      * @see #setInnerRadius(int)
      * @attr ref android.R.styleable#GradientDrawable_innerRadius
diff --git a/graphics/java/android/graphics/drawable/shapes/PathShape.java b/graphics/java/android/graphics/drawable/shapes/PathShape.java
index 393fdee..299f6d5 100644
--- a/graphics/java/android/graphics/drawable/shapes/PathShape.java
+++ b/graphics/java/android/graphics/drawable/shapes/PathShape.java
@@ -93,7 +93,7 @@
             && Float.compare(pathShape.mStdHeight, mStdHeight) == 0
             && Float.compare(pathShape.mScaleX, mScaleX) == 0
             && Float.compare(pathShape.mScaleY, mScaleY) == 0
-            // Path does not have equals implementation but incase it gains one, use it here
+            // Path does not have equals implementation but in case it gains one, use it here
             && Objects.equals(mPath, pathShape.mPath);
     }
 
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index 28cc051..9aea246 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -787,7 +787,7 @@
             return false;
         }
 
-        // ByteBuffer#equals compares all bytes which is not performant for e.g HashMap. Since
+        // ByteBuffer#equals compares all bytes which is not performant for e.g. HashMap. Since
         // underlying native font object holds buffer address, check if this buffer points exactly
         // the same address as a shortcut of equality. For being compatible with of API30 or before,
         // check buffer position even if the buffer points the same address.
diff --git a/graphics/java/android/graphics/fonts/FontFileUtil.java b/graphics/java/android/graphics/fonts/FontFileUtil.java
index ff38282..abcafb6 100644
--- a/graphics/java/android/graphics/fonts/FontFileUtil.java
+++ b/graphics/java/android/graphics/fonts/FontFileUtil.java
@@ -34,7 +34,7 @@
  */
 public class FontFileUtil {
 
-    private FontFileUtil() {}  // Do not instanciate
+    private FontFileUtil() {}  // Do not instantiate
 
     /**
      * Unpack the weight value from packed integer.
@@ -87,7 +87,7 @@
         }
 
         if (weight != -1 && italic != -1) {
-            // Both weight/italic style are specifeid by variation settings.
+            // Both weight/italic style are specified by variation settings.
             // No need to look into OS/2 table.
             // TODO: Good to look HVAR table to check if this font supports wght/ital axes.
             return pack(weight, italic == 1);
diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java
index 3ef714ed..6e20034 100644
--- a/graphics/java/android/graphics/fonts/SystemFonts.java
+++ b/graphics/java/android/graphics/fonts/SystemFonts.java
@@ -151,7 +151,7 @@
                 } else if (defaultFamily != null) {
                     familyListSet.familyList.add(defaultFamily);
                 } else {
-                    // There is no valid for for default fallback. Ignore.
+                    // There is no valid for default fallback. Ignore.
                 }
             }
         }
diff --git a/graphics/java/android/graphics/text/LineBreaker.java b/graphics/java/android/graphics/text/LineBreaker.java
index 0e3fb16..06ff4c5 100644
--- a/graphics/java/android/graphics/text/LineBreaker.java
+++ b/graphics/java/android/graphics/text/LineBreaker.java
@@ -368,8 +368,8 @@
      * @see LineBreaker#computeLineBreaks
      */
     public static class Result {
-        // Following two contstant must be synced with minikin's line breaker.
-        // TODO(nona): Remove these constatns by introducing native methods.
+        // Following two constants must be synced with minikin's line breaker.
+        // TODO(nona): Remove these constants by introducing native methods.
         private static final int TAB_MASK = 0x20000000;
         private static final int HYPHEN_MASK = 0xFF;
         private static final int START_HYPHEN_MASK = 0x18;  // 0b11000
diff --git a/graphics/java/android/graphics/text/PositionedGlyphs.java b/graphics/java/android/graphics/text/PositionedGlyphs.java
index 7932e33..fe20089 100644
--- a/graphics/java/android/graphics/text/PositionedGlyphs.java
+++ b/graphics/java/android/graphics/text/PositionedGlyphs.java
@@ -137,7 +137,7 @@
      * Returns the glyph ID used for drawing the glyph at the given index.
      *
      * @param index the glyph index
-     * @return An glyph ID of the font.
+     * @return A glyph ID of the font.
      */
     @IntRange(from = 0)
     public int getGlyphId(@IntRange(from = 0) int index) {
diff --git a/nfc/java/android/nfc/cardemulation/HostApduService.java b/nfc/java/android/nfc/cardemulation/HostApduService.java
index 7cd2533..ea3fd0d 100644
--- a/nfc/java/android/nfc/cardemulation/HostApduService.java
+++ b/nfc/java/android/nfc/cardemulation/HostApduService.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SuppressLint;
 import android.app.Service;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -481,6 +482,7 @@
      *
      * @param frame A description of the polling frame.
      */
+    @SuppressLint("OnNameExpected")
     @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
     public void processPollingFrames(@NonNull List<Bundle> frame) {
     }
diff --git a/ravenwood/ravenwood-annotation-allowed-classes.txt b/ravenwood/ravenwood-annotation-allowed-classes.txt
index 13908f1..56eb658 100644
--- a/ravenwood/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/ravenwood-annotation-allowed-classes.txt
@@ -1,5 +1,7 @@
 # Only classes listed here can use the Ravenwood annotations.
 
+com.android.internal.ravenwood.*
+
 com.android.internal.util.ArrayUtils
 com.android.internal.os.BatteryStatsHistory
 com.android.internal.os.BatteryStatsHistory$TraceDelegate
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index a4b2896..96ae790 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -5084,7 +5084,9 @@
                         // so we tear it down in anticipation of it (possibly) being
                         // reconstructed due to the restore
                         host.widgets.remove(widget);
-                        provider.widgets.remove(widget);
+                        if (provider != null) {
+                            provider.widgets.remove(widget);
+                        }
                         // Check if we need to destroy any services (if no other app widgets are
                         // referencing the same service)
                         decrementAppWidgetServiceRefCount(widget);
diff --git a/services/core/java/com/android/server/BootReceiver.java b/services/core/java/com/android/server/BootReceiver.java
index 9f279b1..f69a521 100644
--- a/services/core/java/com/android/server/BootReceiver.java
+++ b/services/core/java/com/android/server/BootReceiver.java
@@ -34,6 +34,7 @@
 import android.provider.Downloads;
 import android.system.ErrnoException;
 import android.system.Os;
+import android.system.OsConstants;
 import android.text.TextUtils;
 import android.util.AtomicFile;
 import android.util.EventLog;
@@ -230,16 +231,23 @@
     }
 
     private static String getCurrentBootHeaders() throws IOException {
-        return new StringBuilder(512)
-            .append("Build: ").append(Build.FINGERPRINT).append("\n")
-            .append("Hardware: ").append(Build.BOARD).append("\n")
-            .append("Revision: ")
-            .append(SystemProperties.get("ro.revision", "")).append("\n")
-            .append("Bootloader: ").append(Build.BOOTLOADER).append("\n")
-            .append("Radio: ").append(Build.getRadioVersion()).append("\n")
-            .append("Kernel: ")
-            .append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"))
-            .append("\n").toString();
+        StringBuilder builder =  new StringBuilder(512)
+                .append("Build: ").append(Build.FINGERPRINT).append("\n")
+                .append("Hardware: ").append(Build.BOARD).append("\n")
+                .append("Revision: ")
+                .append(SystemProperties.get("ro.revision", "")).append("\n")
+                .append("Bootloader: ").append(Build.BOOTLOADER).append("\n")
+                .append("Radio: ").append(Build.getRadioVersion()).append("\n")
+                .append("Kernel: ")
+                .append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"));
+
+        // If device is not using 4KB pages, add the PageSize
+        long pageSize = Os.sysconf(OsConstants._SC_PAGESIZE);
+        if (pageSize != 4096) {
+            builder.append("PageSize: ").append(pageSize).append("\n");
+        }
+        builder.append("\n");
+        return builder.toString();
     }
 
 
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 79620cf..1c1190f 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -1638,7 +1638,13 @@
                 String gidStr = parser.getAttributeValue(null, "gid");
                 if (gidStr != null) {
                     int gid = Process.getGidForName(gidStr);
-                    perm.gids = appendInt(perm.gids, gid);
+                    if (gid != -1) {
+                        perm.gids = appendInt(perm.gids, gid);
+                    } else {
+                        Slog.w(TAG, "<group> with unknown gid \""
+                                + gidStr + " for permission " + name + " in "
+                                + parser.getPositionDescription());
+                    }
                 } else {
                     Slog.w(TAG, "<group> without gid at "
                             + parser.getPositionDescription());
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 28d840b..11e4a03 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -369,6 +369,8 @@
 import android.provider.Settings;
 import android.server.ServerProtoEnums;
 import android.sysprop.InitProperties;
+import android.system.Os;
+import android.system.OsConstants;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.text.style.SuggestionSpan;
@@ -9618,6 +9620,13 @@
             sb.append("ErrorId: ").append(errorId.toString()).append("\n");
         }
         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
+
+        // If device is not using 4KB pages, add the PageSize
+        long pageSize = Os.sysconf(OsConstants._SC_PAGESIZE);
+        if (pageSize != 4096) {
+            sb.append("PageSize: ").append(pageSize).append("\n");
+        }
+
         if (Debug.isDebuggerConnected()) {
             sb.append("Debugger: Connected\n");
         }
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 4b0177a..f249cb0 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2643,7 +2643,7 @@
         // If a target task is specified, try to reuse that one
         if (mOptions != null && mOptions.getLaunchTaskId() != INVALID_TASK_ID) {
             Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId());
-            if (launchTask != null) {
+            if (launchTask != null && launchTask.isLeafTask()) {
                 return launchTask;
             }
             return null;
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/OWNERS b/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
index 72c0a9e..2cbc226 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
+++ b/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
@@ -1 +1,3 @@
 include /services/core/java/com/android/server/am/OWNERS
+
+per-file ApplicationStartInfoTest.java = yforta@google.com, carmenjackson@google.com, jji@google.com
diff --git a/tests/Input/src/android/hardware/input/KeyboardLayoutPreviewTests.kt b/tests/Input/src/android/hardware/input/KeyboardLayoutPreviewTests.kt
index 3a2a3be..ae32bda 100644
--- a/tests/Input/src/android/hardware/input/KeyboardLayoutPreviewTests.kt
+++ b/tests/Input/src/android/hardware/input/KeyboardLayoutPreviewTests.kt
@@ -16,6 +16,8 @@
 
 package android.hardware.input
 
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import android.content.ContextWrapper
 import android.graphics.drawable.Drawable
 import android.platform.test.annotations.Presubmit
@@ -54,16 +56,16 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_KEYBOARD_LAYOUT_PREVIEW_FLAG)
     fun testKeyboardLayoutDrawable_hasCorrectDimensions() {
-        setFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_LAYOUT_PREVIEW_FLAG)
         val drawable = createDrawable()!!
         assertEquals(WIDTH, drawable.intrinsicWidth)
         assertEquals(HEIGHT, drawable.intrinsicHeight)
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_KEYBOARD_LAYOUT_PREVIEW_FLAG)
     fun testKeyboardLayoutDrawable_isNull_ifFlagOff() {
-        setFlagsRule.disableFlags(Flags.FLAG_KEYBOARD_LAYOUT_PREVIEW_FLAG)
         assertNull(createDrawable())
     }
 }
\ No newline at end of file
diff --git a/tools/aapt/Symbol.h b/tools/aapt/Symbol.h
index de1d60c..24c3208 100644
--- a/tools/aapt/Symbol.h
+++ b/tools/aapt/Symbol.h
@@ -40,7 +40,7 @@
 };
 
 /**
- * A specific defintion of a symbol, defined with a configuration and a definition site.
+ * A specific definition of a symbol, defined with a configuration and a definition site.
  */
 struct SymbolDefinition {
     inline SymbolDefinition();
@@ -92,4 +92,3 @@
 }
 
 #endif // AAPT_SYMBOL_H
-