Merge "Ignore null action in PackageManagerService." into main
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 371e3d2..b0c280b 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -935,6 +935,11 @@
         return static_cast<jint>(PublicFormat::PRIVATE);
     } else {
         BufferItem* buffer = Image_getBufferItem(env, thiz);
+        if (buffer == nullptr) {
+            jniThrowException(env, "java/lang/IllegalStateException",
+                    "Image is not initialized");
+            return -1;
+        }
         int readerHalFormat = mapPublicFormatToHalFormat(static_cast<PublicFormat>(readerFormat));
         int32_t fmt = applyFormatOverrides(
                 buffer->mGraphicBuffer->getPixelFormat(), readerHalFormat);
@@ -953,6 +958,11 @@
 
 static jobject Image_getHardwareBuffer(JNIEnv* env, jobject thiz) {
     BufferItem* buffer = Image_getBufferItem(env, thiz);
+    if (buffer == nullptr) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Image is not initialized");
+        return NULL;
+    }
     AHardwareBuffer* b = AHardwareBuffer_from_GraphicBuffer(buffer->mGraphicBuffer.get());
     // don't user the public AHardwareBuffer_toHardwareBuffer() because this would force us
     // to link against libandroid.so
diff --git a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java
index 121f549..3696000 100644
--- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java
+++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java
@@ -41,6 +41,7 @@
             "/system_ext/etc/NOTICE.xml.gz",
             "/vendor_dlkm/etc/NOTICE.xml.gz",
             "/odm_dlkm/etc/NOTICE.xml.gz",
+            "/system_dlkm/etc/NOTICE.xml.gz",
     };
     static final String NOTICE_HTML_FILE_NAME = "NOTICE.html";
 
diff --git a/packages/SystemUI/animation/lib/OWNERS b/packages/SystemUI/animation/lib/OWNERS
new file mode 100644
index 0000000..7569419
--- /dev/null
+++ b/packages/SystemUI/animation/lib/OWNERS
@@ -0,0 +1,3 @@
+#inherits OWNERS from SystemUI in addition to WEAR framework owners below
+file:platform/frameworks/base:/WEAR_OWNERS
+
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java
index b4b8715..016de8e 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java
@@ -90,9 +90,7 @@
         // Create the "latest" symlink.
         Path symlink = Paths.get(tmpdir, basename + "latest.csv");
         try {
-            if (Files.exists(symlink)) {
-                Files.delete(symlink);
-            }
+            Files.deleteIfExists(symlink);
             Files.createSymbolicLink(symlink, Paths.get(mOutputFile.getName()));
 
         } catch (IOException e) {
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 8b619a4..9b987e9 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -670,6 +670,17 @@
     }
 
     private void readAllPermissions() {
+        readAllPermissionsFromXml();
+        readAllPermissionsFromEnvironment();
+
+        // Apply global feature removal last, after all features have been read.
+        // This only needs to happen once.
+        for (String featureName : mUnavailableFeatures) {
+            removeFeature(featureName);
+        }
+    }
+
+    private void readAllPermissionsFromXml() {
         final XmlPullParser parser = Xml.newPullParser();
 
         // Read configuration from system
@@ -1732,7 +1743,13 @@
         } finally {
             IoUtils.closeQuietly(permReader);
         }
+    }
 
+    // Add features or permission dependent on global system properties (as
+    // opposed to XML permission files).
+    // This only needs to be called once after all features have been parsed
+    // from various partition/apex sources.
+    private void readAllPermissionsFromEnvironment() {
         // Some devices can be field-converted to FBE, so offer to splice in
         // those features if not already defined by the static config
         if (StorageManager.isFileEncrypted()) {
@@ -1773,10 +1790,6 @@
                 addFeature(PackageManager.FEATURE_EROFS_LEGACY, 0);
             }
         }
-
-        for (String featureName : mUnavailableFeatures) {
-            removeFeature(featureName);
-        }
     }
 
     private @Nullable SignedPackage parseEnhancedConfirmationTrustedPackage(XmlPullParser parser,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f549c7b..be53130 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2874,8 +2874,12 @@
             // Add common services.
             // IMPORTANT: Before adding services here, make sure ephemeral apps can access them too.
             // Enable the check in ApplicationThread.bindApplication() to make sure.
-            if (!android.server.Flags.removeJavaServiceManagerCache()) {
-                addServiceToMap(mAppBindArgs, "permissionmgr");
+
+            // Removing User Service and App Ops Service from cache breaks boot for auto.
+            // Removing permissionmgr breaks tests for Android Auto due to SELinux restrictions.
+            // TODO: fix SELinux restrictions and remove caching for Android Auto.
+            if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+                    || !android.server.Flags.removeJavaServiceManagerCache()) {
                 addServiceToMap(mAppBindArgs, Context.ALARM_SERVICE);
                 addServiceToMap(mAppBindArgs, Context.DISPLAY_SERVICE);
                 addServiceToMap(mAppBindArgs, Context.NETWORKMANAGEMENT_SERVICE);
@@ -2892,16 +2896,16 @@
                 addServiceToMap(mAppBindArgs, Context.POWER_SERVICE);
                 addServiceToMap(mAppBindArgs, "mount");
                 addServiceToMap(mAppBindArgs, Context.PLATFORM_COMPAT_SERVICE);
+                addServiceToMap(mAppBindArgs, "permissionmgr");
+                addServiceToMap(mAppBindArgs, Context.APP_OPS_SERVICE);
+                addServiceToMap(mAppBindArgs, Context.USER_SERVICE);
             }
             // See b/79378449
             // Getting the window service and package service binder from servicemanager
             // is blocked for Apps. However they are necessary for apps.
-            // Removing User Service and App Ops Service from cache breaks boot for auto.
             // TODO: remove exception
-            addServiceToMap(mAppBindArgs, Context.APP_OPS_SERVICE);
             addServiceToMap(mAppBindArgs, "package");
             addServiceToMap(mAppBindArgs, Context.WINDOW_SERVICE);
-            addServiceToMap(mAppBindArgs, Context.USER_SERVICE);
         }
         return mAppBindArgs;
     }
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index bbe7b2b..8436c80 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1975,7 +1975,6 @@
     void setAudioStatus(boolean mute, int volume) {
         if (!isTvDeviceEnabled()
                 || !tv().isSystemAudioActivated()
-                || !tv().isArcEstablished() // Don't update TV volume when SAM is on and ARC is off
                 || getHdmiCecVolumeControl()
                 == HdmiControlManager.VOLUME_CONTROL_DISABLED) {
             return;
diff --git a/services/core/java/com/android/server/integrity/parser/RuleIndexRange.java b/services/core/java/com/android/server/integrity/parser/RuleIndexRange.java
index 595a035..408df5a 100644
--- a/services/core/java/com/android/server/integrity/parser/RuleIndexRange.java
+++ b/services/core/java/com/android/server/integrity/parser/RuleIndexRange.java
@@ -19,8 +19,7 @@
 import android.annotation.Nullable;
 
 /**
- * A wrapper class to represent an indexing range that is identified by the {@link
- * RuleIndexingController}.
+ * A wrapper class to represent an indexing range.
  */
 public class RuleIndexRange {
     private int mStartIndex;
diff --git a/services/core/java/com/android/server/integrity/parser/RuleIndexingController.java b/services/core/java/com/android/server/integrity/parser/RuleIndexingController.java
deleted file mode 100644
index 348a03b..0000000
--- a/services/core/java/com/android/server/integrity/parser/RuleIndexingController.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2020 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.integrity.parser;
-
-import static com.android.server.integrity.model.IndexingFileConstants.END_INDEXING_KEY;
-import static com.android.server.integrity.model.IndexingFileConstants.START_INDEXING_KEY;
-import static com.android.server.integrity.parser.BinaryFileOperations.getIntValue;
-import static com.android.server.integrity.parser.BinaryFileOperations.getStringValue;
-
-import android.content.integrity.AppInstallMetadata;
-
-import com.android.server.integrity.model.BitInputStream;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/** Helper class to identify the necessary indexes that needs to be read. */
-public class RuleIndexingController {
-
-    private static LinkedHashMap<String, Integer> sPackageNameBasedIndexes;
-    private static LinkedHashMap<String, Integer> sAppCertificateBasedIndexes;
-    private static LinkedHashMap<String, Integer> sUnindexedRuleIndexes;
-
-    /**
-     * Provide the indexing file to read and the object will be constructed by reading and
-     * identifying the indexes.
-     */
-    public RuleIndexingController(InputStream inputStream) throws IOException {
-        BitInputStream bitInputStream = new BitInputStream(inputStream);
-        sPackageNameBasedIndexes = getNextIndexGroup(bitInputStream);
-        sAppCertificateBasedIndexes = getNextIndexGroup(bitInputStream);
-        sUnindexedRuleIndexes = getNextIndexGroup(bitInputStream);
-    }
-
-    /**
-     * Returns a list of integers with the starting and ending bytes of the rules that needs to be
-     * read and evaluated.
-     */
-    public List<RuleIndexRange> identifyRulesToEvaluate(AppInstallMetadata appInstallMetadata) {
-        List<RuleIndexRange> indexRanges = new ArrayList<>();
-
-        // Add the range for package name indexes rules.
-        indexRanges.add(
-                searchIndexingKeysRangeContainingKey(
-                        sPackageNameBasedIndexes, appInstallMetadata.getPackageName()));
-
-        // Add the range for app certificate indexes rules of all certificates.
-        for (String appCertificate : appInstallMetadata.getAppCertificates()) {
-            indexRanges.add(
-                    searchIndexingKeysRangeContainingKey(
-                            sAppCertificateBasedIndexes, appCertificate));
-        }
-
-        // Add the range for unindexed rules.
-        indexRanges.add(
-                new RuleIndexRange(
-                        sUnindexedRuleIndexes.get(START_INDEXING_KEY),
-                        sUnindexedRuleIndexes.get(END_INDEXING_KEY)));
-
-        return indexRanges;
-    }
-
-    private LinkedHashMap<String, Integer> getNextIndexGroup(BitInputStream bitInputStream)
-            throws IOException {
-        LinkedHashMap<String, Integer> keyToIndexMap = new LinkedHashMap<>();
-        while (bitInputStream.hasNext()) {
-            String key = getStringValue(bitInputStream);
-            int value = getIntValue(bitInputStream);
-
-            keyToIndexMap.put(key, value);
-
-            if (key.matches(END_INDEXING_KEY)) {
-                break;
-            }
-        }
-        if (keyToIndexMap.size() < 2) {
-            throw new IllegalStateException("Indexing file is corrupt.");
-        }
-        return keyToIndexMap;
-    }
-
-    private static RuleIndexRange searchIndexingKeysRangeContainingKey(
-            LinkedHashMap<String, Integer> indexMap, String searchedKey) {
-        List<String> keys = indexMap.keySet().stream().collect(Collectors.toList());
-        List<String> identifiedKeyRange =
-                searchKeysRangeContainingKey(keys, searchedKey, 0, keys.size() - 1);
-        return new RuleIndexRange(
-                indexMap.get(identifiedKeyRange.get(0)), indexMap.get(identifiedKeyRange.get(1)));
-    }
-
-    private static List<String> searchKeysRangeContainingKey(
-            List<String> sortedKeyList, String key, int startIndex, int endIndex) {
-        if (endIndex <= startIndex) {
-            throw new IllegalStateException("Indexing file is corrupt.");
-        }
-        if (endIndex - startIndex == 1) {
-            return Arrays.asList(sortedKeyList.get(startIndex), sortedKeyList.get(endIndex));
-        }
-
-        int midKeyIndex = startIndex + ((endIndex - startIndex) / 2);
-        String midKey = sortedKeyList.get(midKeyIndex);
-
-        if (key.compareTo(midKey) >= 0) {
-            return searchKeysRangeContainingKey(sortedKeyList, key, midKeyIndex, endIndex);
-        } else {
-            return searchKeysRangeContainingKey(sortedKeyList, key, startIndex, midKeyIndex);
-        }
-    }
-}
diff --git a/services/tests/powerstatstests/Android.bp b/services/tests/powerstatstests/Android.bp
index cedf9db..d786f3fc 100644
--- a/services/tests/powerstatstests/Android.bp
+++ b/services/tests/powerstatstests/Android.bp
@@ -69,7 +69,9 @@
         "flag-junit",
     ],
     srcs: [
-        "src/com/android/server/power/stats/*.java",
+        // b/375477626 -- somehow this test is failing in presubmit on AOSP.
+        // This module is devlopped internal-fast, so we don't need to run it on AOSP.
+        //        "src/com/android/server/power/stats/*.java",
     ],
     java_resources: [
         "res/xml/power_profile*.xml",
diff --git a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleIndexingControllerTest.java b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleIndexingControllerTest.java
deleted file mode 100644
index 370bd80..0000000
--- a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleIndexingControllerTest.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2020 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.integrity.parser;
-
-import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS;
-import static com.android.server.integrity.model.IndexingFileConstants.END_INDEXING_KEY;
-import static com.android.server.integrity.model.IndexingFileConstants.START_INDEXING_KEY;
-import static com.android.server.integrity.utils.TestUtils.getBits;
-import static com.android.server.integrity.utils.TestUtils.getBytes;
-import static com.android.server.integrity.utils.TestUtils.getValueBits;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.content.integrity.AppInstallMetadata;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-@RunWith(JUnit4.class)
-public class RuleIndexingControllerTest {
-
-    @Test
-    public void verifyIndexRangeSearchIsCorrect() throws IOException {
-        InputStream inputStream = obtainDefaultIndexingMapForTest();
-
-        RuleIndexingController indexingController = new RuleIndexingController(inputStream);
-
-        AppInstallMetadata appInstallMetadata =
-                new AppInstallMetadata.Builder()
-                        .setPackageName("ddd")
-                        .setAppCertificates(Collections.singletonList("777"))
-                        .setAppCertificateLineage(Collections.singletonList("777"))
-                        .build();
-
-        List<RuleIndexRange> resultingIndexes =
-                indexingController.identifyRulesToEvaluate(appInstallMetadata);
-
-        assertThat(resultingIndexes)
-                .containsExactly(
-                        new RuleIndexRange(200, 300),
-                        new RuleIndexRange(700, 800),
-                        new RuleIndexRange(900, 945));
-    }
-
-    @Test
-    public void verifyIndexRangeSearchIsCorrect_multipleAppCertificates() throws IOException {
-        InputStream inputStream = obtainDefaultIndexingMapForTest();
-
-        RuleIndexingController indexingController = new RuleIndexingController(inputStream);
-
-        AppInstallMetadata appInstallMetadata =
-                new AppInstallMetadata.Builder()
-                        .setPackageName("ddd")
-                        .setAppCertificates(Arrays.asList("777", "999"))
-                        .setAppCertificateLineage(Arrays.asList("777", "999"))
-                        .build();
-
-        List<RuleIndexRange> resultingIndexes =
-                indexingController.identifyRulesToEvaluate(appInstallMetadata);
-
-        assertThat(resultingIndexes)
-                .containsExactly(
-                        new RuleIndexRange(200, 300),
-                        new RuleIndexRange(700, 800),
-                        new RuleIndexRange(800, 900),
-                        new RuleIndexRange(900, 945));
-    }
-
-    @Test
-    public void verifyIndexRangeSearchIsCorrect_keysInFirstAndLastBlock() throws IOException {
-        InputStream inputStream = obtainDefaultIndexingMapForTest();
-
-        RuleIndexingController indexingController = new RuleIndexingController(inputStream);
-
-        AppInstallMetadata appInstallMetadata =
-                new AppInstallMetadata.Builder()
-                        .setPackageName("bbb")
-                        .setAppCertificates(Collections.singletonList("999"))
-                        .setAppCertificateLineage(Collections.singletonList("999"))
-                        .build();
-
-        List<RuleIndexRange> resultingIndexes =
-                indexingController.identifyRulesToEvaluate(appInstallMetadata);
-
-        assertThat(resultingIndexes)
-                .containsExactly(
-                        new RuleIndexRange(100, 200),
-                        new RuleIndexRange(800, 900),
-                        new RuleIndexRange(900, 945));
-    }
-
-    @Test
-    public void verifyIndexRangeSearchIsCorrect_keysMatchWithValues() throws IOException {
-        InputStream inputStream = obtainDefaultIndexingMapForTest();
-
-        RuleIndexingController indexingController = new RuleIndexingController(inputStream);
-
-        AppInstallMetadata appInstallMetadata =
-                new AppInstallMetadata.Builder()
-                        .setPackageName("ccc")
-                        .setAppCertificates(Collections.singletonList("444"))
-                        .setAppCertificateLineage(Collections.singletonList("444"))
-                        .build();
-
-        List<RuleIndexRange> resultingIndexes =
-                indexingController.identifyRulesToEvaluate(appInstallMetadata);
-
-        assertThat(resultingIndexes)
-                .containsExactly(
-                        new RuleIndexRange(200, 300),
-                        new RuleIndexRange(700, 800),
-                        new RuleIndexRange(900, 945));
-    }
-
-    @Test
-    public void verifyIndexRangeSearchIsCorrect_noIndexesAvailable() throws IOException {
-        byte[] stringBytes =
-                getBytes(
-                        getKeyValueString(START_INDEXING_KEY, 100)
-                                + getKeyValueString(END_INDEXING_KEY, 500)
-                                + getKeyValueString(START_INDEXING_KEY, 500)
-                                + getKeyValueString(END_INDEXING_KEY, 900)
-                                + getKeyValueString(START_INDEXING_KEY, 900)
-                                + getKeyValueString(END_INDEXING_KEY, 945));
-        ByteBuffer rule = ByteBuffer.allocate(stringBytes.length);
-        rule.put(stringBytes);
-        InputStream inputStream = new ByteArrayInputStream(rule.array());
-
-        RuleIndexingController indexingController = new RuleIndexingController(inputStream);
-
-        AppInstallMetadata appInstallMetadata =
-                new AppInstallMetadata.Builder()
-                        .setPackageName("ccc")
-                        .setAppCertificates(Collections.singletonList("444"))
-                        .setAppCertificateLineage(Collections.singletonList("444"))
-                        .build();
-
-        List<RuleIndexRange> resultingIndexes =
-                indexingController.identifyRulesToEvaluate(appInstallMetadata);
-
-        assertThat(resultingIndexes)
-                .containsExactly(
-                        new RuleIndexRange(100, 500),
-                        new RuleIndexRange(500, 900),
-                        new RuleIndexRange(900, 945));
-    }
-
-    @Test
-    public void verifyIndexingFileIsCorrupt() throws IOException {
-        byte[] stringBytes =
-                getBytes(
-                        getKeyValueString(START_INDEXING_KEY, 100)
-                                + getKeyValueString("ccc", 200)
-                                + getKeyValueString(END_INDEXING_KEY, 300)
-                                + getKeyValueString(END_INDEXING_KEY, 900));
-        ByteBuffer rule = ByteBuffer.allocate(stringBytes.length);
-        rule.put(stringBytes);
-        InputStream inputStream = new ByteArrayInputStream(rule.array());
-
-        assertThrows(IllegalStateException.class,
-                () -> new RuleIndexingController(inputStream));
-    }
-
-    private static InputStream obtainDefaultIndexingMapForTest() {
-        byte[] stringBytes =
-                getBytes(
-                        getKeyValueString(START_INDEXING_KEY, 100)
-                                + getKeyValueString("ccc", 200)
-                                + getKeyValueString("eee", 300)
-                                + getKeyValueString("hhh", 400)
-                                + getKeyValueString(END_INDEXING_KEY, 500)
-                                + getKeyValueString(START_INDEXING_KEY, 500)
-                                + getKeyValueString("111", 600)
-                                + getKeyValueString("444", 700)
-                                + getKeyValueString("888", 800)
-                                + getKeyValueString(END_INDEXING_KEY, 900)
-                                + getKeyValueString(START_INDEXING_KEY, 900)
-                                + getKeyValueString(END_INDEXING_KEY, 945));
-        ByteBuffer rule = ByteBuffer.allocate(stringBytes.length);
-        rule.put(stringBytes);
-        return new ByteArrayInputStream(rule.array());
-    }
-
-    private static String getKeyValueString(String key, int value) {
-        String isNotHashed = "0";
-        return isNotHashed
-                + getBits(key.length(), VALUE_SIZE_BITS)
-                + getValueBits(key)
-                + getBits(value, /* numOfBits= */ 32);
-    }
-}