summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/idmap2/TEST_MAPPING5
-rw-r--r--cmds/idmap2/idmap2d/Idmap2Service.cpp6
-rw-r--r--core/java/android/app/ResourcesManager.java4
-rw-r--r--core/tests/overlaytests/host/Android.bp2
-rw-r--r--core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java15
-rw-r--r--core/tests/overlaytests/host/test-apps/SignatureOverlay/Android.mk7
-rw-r--r--core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk10
-rw-r--r--core/tests/overlaytests/remount/Android.bp (renamed from core/tests/overlaytests/remount/host/Android.bp)2
-rw-r--r--core/tests/overlaytests/remount/AndroidTest.xml (renamed from core/tests/overlaytests/remount/host/AndroidTest.xml)0
-rw-r--r--core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/OverlayRemountedTestBase.java84
-rw-r--r--core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/OverlaySharedLibraryTest.java (renamed from core/tests/overlaytests/remount/host/src/com/android/overlaytest/remounted/OverlaySharedLibraryTest.java)51
-rw-r--r--core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/PackagedUpgradedTest.java65
-rw-r--r--core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/SystemPreparer.java (renamed from core/tests/overlaytests/remount/host/src/com/android/overlaytest/remounted/SystemPreparer.java)54
-rw-r--r--core/tests/overlaytests/remount/test-apps/Overlay/Android.bp18
-rw-r--r--core/tests/overlaytests/remount/test-apps/Overlay/AndroidManifest.xml23
-rw-r--r--core/tests/overlaytests/remount/test-apps/Overlay/res/values/values.xml20
-rw-r--r--core/tests/overlaytests/remount/test-apps/SharedLibrary/Android.bp (renamed from core/tests/overlaytests/remount/host/test-apps/SharedLibrary/Android.bp)0
-rw-r--r--core/tests/overlaytests/remount/test-apps/SharedLibrary/AndroidManifest.xml (renamed from core/tests/overlaytests/remount/host/test-apps/SharedLibrary/AndroidManifest.xml)0
-rw-r--r--core/tests/overlaytests/remount/test-apps/SharedLibrary/res/values/overlayable.xml (renamed from core/tests/overlaytests/remount/host/test-apps/SharedLibrary/res/values/overlayable.xml)0
-rw-r--r--core/tests/overlaytests/remount/test-apps/SharedLibrary/res/values/public.xml (renamed from core/tests/overlaytests/remount/host/test-apps/SharedLibrary/res/values/public.xml)0
-rw-r--r--core/tests/overlaytests/remount/test-apps/SharedLibrary/res/values/values.xml (renamed from core/tests/overlaytests/remount/host/test-apps/SharedLibrary/res/values/values.xml)0
-rw-r--r--core/tests/overlaytests/remount/test-apps/SharedLibraryOverlay/Android.bp (renamed from core/tests/overlaytests/remount/host/test-apps/SharedLibraryOverlay/Android.bp)0
-rw-r--r--core/tests/overlaytests/remount/test-apps/SharedLibraryOverlay/AndroidManifest.xml (renamed from core/tests/overlaytests/remount/host/test-apps/SharedLibraryOverlay/AndroidManifest.xml)0
-rw-r--r--core/tests/overlaytests/remount/test-apps/SharedLibraryOverlay/res/values/values.xml (renamed from core/tests/overlaytests/remount/host/test-apps/SharedLibraryOverlay/res/values/values.xml)0
-rw-r--r--core/tests/overlaytests/remount/test-apps/Target/Android.bp (renamed from core/tests/overlaytests/remount/target/Android.bp)9
-rw-r--r--core/tests/overlaytests/remount/test-apps/Target/AndroidManifest.xml (renamed from core/tests/overlaytests/remount/target/AndroidManifest.xml)3
-rw-r--r--core/tests/overlaytests/remount/test-apps/Target/res/values/overlayable.xml24
-rw-r--r--core/tests/overlaytests/remount/test-apps/Target/res/values/values.xml (renamed from core/tests/overlaytests/remount/target/res/values/values.xml)6
-rw-r--r--core/tests/overlaytests/remount/test-apps/Target/res_upgrade/values/overlayable.xml24
-rw-r--r--core/tests/overlaytests/remount/test-apps/Target/res_upgrade/values/values.xml23
-rw-r--r--libs/androidfw/ApkAssets.cpp5
-rw-r--r--libs/androidfw/Idmap.cpp20
-rw-r--r--libs/androidfw/include/androidfw/Idmap.h18
-rw-r--r--libs/androidfw/tests/Idmap_test.cpp30
-rw-r--r--services/core/java/com/android/server/om/IdmapManager.java7
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerServiceImpl.java7
-rw-r--r--services/core/java/com/android/server/om/TEST_MAPPING3
-rw-r--r--services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java3
38 files changed, 429 insertions, 119 deletions
diff --git a/cmds/idmap2/TEST_MAPPING b/cmds/idmap2/TEST_MAPPING
index 26ccf038cba2..9e0fb84c7949 100644
--- a/cmds/idmap2/TEST_MAPPING
+++ b/cmds/idmap2/TEST_MAPPING
@@ -3,5 +3,10 @@
{
"name" : "idmap2_tests"
}
+ ],
+ "imports": [
+ {
+ "path": "frameworks/base/services/core/java/com/android/server/om"
+ }
]
}
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp
index e55ea6c00545..75fc7f714ce3 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.cpp
+++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp
@@ -149,15 +149,21 @@ Status Idmap2Service::createIdmap(const std::string& target_apk_path,
return error(idmap.GetErrorMessage());
}
+ // idmap files are mapped with mmap in libandroidfw. Deleting and recreating the idmap guarantees
+ // that existing memory maps will continue to be valid and unaffected.
+ unlink(idmap_path.c_str());
+
umask(kIdmapFilePermissionMask);
std::ofstream fout(idmap_path);
if (fout.fail()) {
return error("failed to open idmap path " + idmap_path);
}
+
BinaryStreamVisitor visitor(fout);
(*idmap)->accept(&visitor);
fout.close();
if (fout.fail()) {
+ unlink(idmap_path.c_str());
return error("failed to write to idmap path " + idmap_path);
}
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index d2e848b9562a..47ccc2f0badb 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -344,7 +344,7 @@ public class ResourcesManager {
ApkAssets apkAssets = null;
if (mLoadedApkAssets != null) {
apkAssets = mLoadedApkAssets.get(newKey);
- if (apkAssets != null) {
+ if (apkAssets != null && apkAssets.isUpToDate()) {
return apkAssets;
}
}
@@ -353,7 +353,7 @@ public class ResourcesManager {
final WeakReference<ApkAssets> apkAssetsRef = mCachedApkAssets.get(newKey);
if (apkAssetsRef != null) {
apkAssets = apkAssetsRef.get();
- if (apkAssets != null) {
+ if (apkAssets != null && apkAssets.isUpToDate()) {
if (mLoadedApkAssets != null) {
mLoadedApkAssets.put(newKey, apkAssets);
}
diff --git a/core/tests/overlaytests/host/Android.bp b/core/tests/overlaytests/host/Android.bp
index a2fcef56b780..2b38cca2db36 100644
--- a/core/tests/overlaytests/host/Android.bp
+++ b/core/tests/overlaytests/host/Android.bp
@@ -16,7 +16,7 @@ java_test_host {
name: "OverlayHostTests",
srcs: ["src/**/*.java"],
libs: ["tradefed"],
- test_suites: ["general-tests"],
+ test_suites: ["device-tests"],
target_required: [
"OverlayHostTests_NonPlatformSignatureOverlay",
"OverlayHostTests_PlatformSignatureStaticOverlay",
diff --git a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
index eec7be22c78b..d898d222b8de 100644
--- a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
+++ b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
@@ -78,14 +78,9 @@ public class InstallOverlayTests extends BaseHostJUnit4Test {
}
@Test
- public void failToInstallPlatformSignedStaticOverlay() throws Exception {
- try {
- installPackage("OverlayHostTests_PlatformSignatureStaticOverlay.apk");
- fail("installed a static overlay");
- } catch (Exception e) {
- // Expected.
- }
- assertFalse(overlayManagerContainsPackage(SIG_OVERLAY_PACKAGE_NAME));
+ public void installedIsStaticOverlayIsMutable() throws Exception {
+ installPackage("OverlayHostTests_PlatformSignatureStaticOverlay.apk");
+ assertTrue(isOverlayMutable(SIG_OVERLAY_PACKAGE_NAME));
}
@Test
@@ -229,6 +224,10 @@ public class InstallOverlayTests extends BaseHostJUnit4Test {
return shell("cmd overlay list").contains(pkg);
}
+ private boolean isOverlayMutable(String pkg) throws Exception {
+ return shell("cmd overlay dump ismutable " + pkg).contains("true");
+ }
+
private String shell(final String cmd) throws Exception {
return getDevice().executeShellCommand(cmd);
}
diff --git a/core/tests/overlaytests/host/test-apps/SignatureOverlay/Android.mk b/core/tests/overlaytests/host/test-apps/SignatureOverlay/Android.mk
index cc7704b0ce98..f3c0abd8293f 100644
--- a/core/tests/overlaytests/host/test-apps/SignatureOverlay/Android.mk
+++ b/core/tests/overlaytests/host/test-apps/SignatureOverlay/Android.mk
@@ -20,7 +20,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_PACKAGE_NAME := OverlayHostTests_NonPlatformSignatureOverlay
LOCAL_SDK_VERSION := current
-LOCAL_COMPATIBILITY_SUITE := general-tests
+LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_bad
include $(BUILD_PACKAGE)
@@ -28,7 +28,8 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_PACKAGE_NAME := OverlayHostTests_PlatformSignatureStaticOverlay
LOCAL_SDK_VERSION := current
-LOCAL_COMPATIBILITY_SUITE := general-tests
+LOCAL_COMPATIBILITY_SUITE := device-tests
+LOCAL_CERTIFICATE := platform
LOCAL_MANIFEST_FILE := static/AndroidManifest.xml
LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_static
include $(BUILD_PACKAGE)
@@ -37,7 +38,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_PACKAGE_NAME := OverlayHostTests_PlatformSignatureOverlay
LOCAL_SDK_VERSION := current
-LOCAL_COMPATIBILITY_SUITE := general-tests
+LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_CERTIFICATE := platform
LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v1
LOCAL_AAPT_FLAGS += --version-code 1 --version-name v1
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
index f8607f44bda6..878f05d57662 100644
--- a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
+++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
@@ -19,7 +19,7 @@ LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_PACKAGE_NAME := OverlayHostTests_UpdateOverlay
LOCAL_SDK_VERSION := current
-LOCAL_COMPATIBILITY_SUITE := general-tests
+LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules
LOCAL_USE_AAPT2 := true
LOCAL_AAPT_FLAGS := --no-resource-removal
@@ -31,7 +31,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_PACKAGE_NAME := OverlayHostTests_FrameworkOverlayV1
LOCAL_SDK_VERSION := current
-LOCAL_COMPATIBILITY_SUITE := general-tests
+LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_CERTIFICATE := platform
LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v1
LOCAL_AAPT_FLAGS += --version-code 1 --version-name v1
@@ -43,7 +43,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_PACKAGE_NAME := OverlayHostTests_FrameworkOverlayV2
LOCAL_SDK_VERSION := current
-LOCAL_COMPATIBILITY_SUITE := general-tests
+LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_CERTIFICATE := platform
LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v2
LOCAL_AAPT_FLAGS += --version-code 2 --version-name v2
@@ -57,7 +57,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_PACKAGE_NAME := OverlayHostTests_AppOverlayV1
LOCAL_SDK_VERSION := current
-LOCAL_COMPATIBILITY_SUITE := general-tests
+LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v1
LOCAL_AAPT_FLAGS += --version-code 1 --version-name v1
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/app/v1/res
@@ -68,7 +68,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_PACKAGE_NAME := OverlayHostTests_AppOverlayV2
LOCAL_SDK_VERSION := current
-LOCAL_COMPATIBILITY_SUITE := general-tests
+LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v2
LOCAL_AAPT_FLAGS += --version-code 2 --version-name v2
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/app/v2/res
diff --git a/core/tests/overlaytests/remount/host/Android.bp b/core/tests/overlaytests/remount/Android.bp
index 3825c55f3b4b..9baedf81d6e0 100644
--- a/core/tests/overlaytests/remount/host/Android.bp
+++ b/core/tests/overlaytests/remount/Android.bp
@@ -24,5 +24,7 @@ java_test_host {
":OverlayRemountedTest_SharedLibrary",
":OverlayRemountedTest_SharedLibraryOverlay",
":OverlayRemountedTest_Target",
+ ":OverlayRemountedTest_TargetUpgrade",
+ ":OverlayRemountedTest_Overlay",
],
}
diff --git a/core/tests/overlaytests/remount/host/AndroidTest.xml b/core/tests/overlaytests/remount/AndroidTest.xml
index 087b7313693d..087b7313693d 100644
--- a/core/tests/overlaytests/remount/host/AndroidTest.xml
+++ b/core/tests/overlaytests/remount/AndroidTest.xml
diff --git a/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/OverlayRemountedTestBase.java b/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/OverlayRemountedTestBase.java
new file mode 100644
index 000000000000..00a53c45d797
--- /dev/null
+++ b/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/OverlayRemountedTestBase.java
@@ -0,0 +1,84 @@
+/*
+ * 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.overlaytest.remounted;
+
+import static org.junit.Assert.fail;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TemporaryFolder;
+
+public class OverlayRemountedTestBase extends BaseHostJUnit4Test {
+ static final long ASSERT_RESOURCE_TIMEOUT_MS = 30000;
+
+ static final String TARGET_APK = "OverlayRemountedTest_Target.apk";
+ static final String TARGET_PACKAGE = "com.android.overlaytest.remounted.target";
+ static final String TARGET_UPGRADE_APK = "OverlayRemountedTest_TargetUpgrade.apk";
+ static final String OVERLAY_APK = "OverlayRemountedTest_Overlay.apk";
+ static final String OVERLAY_PACKAGE = "com.android.overlaytest.remounted.target.overlay";
+ static final String SHARED_LIBRARY_APK =
+ "OverlayRemountedTest_SharedLibrary.apk";
+ static final String SHARED_LIBRARY_PACKAGE =
+ "com.android.overlaytest.remounted.shared_library";
+ static final String SHARED_LIBRARY_OVERLAY_APK =
+ "OverlayRemountedTest_SharedLibraryOverlay.apk";
+ static final String SHARED_LIBRARY_OVERLAY_PACKAGE =
+ "com.android.overlaytest.remounted.shared_library.overlay";
+
+ private final TemporaryFolder mTemporaryFolder = new TemporaryFolder();
+ protected final SystemPreparer mPreparer = new SystemPreparer(mTemporaryFolder,
+ this::getDevice);
+
+ @Rule
+ public final RuleChain ruleChain = RuleChain.outerRule(mTemporaryFolder).around(mPreparer);
+
+ @Before
+ public void startBefore() throws DeviceNotAvailableException {
+ getDevice().waitForDeviceAvailable();
+ }
+
+ /** Builds the full name of a resource in the form package:type/entry. */
+ String resourceName(String pkg, String type, String entry) {
+ return String.format("%s:%s/%s", pkg, type, entry);
+ }
+
+ void assertResource(String resourceName, String expectedValue)
+ throws DeviceNotAvailableException {
+ String result = null;
+
+ final long endMillis = System.currentTimeMillis() + ASSERT_RESOURCE_TIMEOUT_MS;
+ while (System.currentTimeMillis() <= endMillis) {
+ result = getDevice().executeShellCommand(
+ String.format("cmd overlay lookup %s %s", TARGET_PACKAGE, resourceName));
+ if (result.equals(expectedValue + "\n") ||
+ result.endsWith("-> " + expectedValue + "\n")) {
+ return;
+ }
+
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException ignore) {
+ }
+ }
+
+ fail(String.format("expected: <[%s]> in: <[%s]>", expectedValue, result));
+ }
+}
diff --git a/core/tests/overlaytests/remount/host/src/com/android/overlaytest/remounted/OverlaySharedLibraryTest.java b/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/OverlaySharedLibraryTest.java
index 06b2ac8f9e22..49d1894c9bae 100644
--- a/core/tests/overlaytests/remount/host/src/com/android/overlaytest/remounted/OverlaySharedLibraryTest.java
+++ b/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/OverlaySharedLibraryTest.java
@@ -16,42 +16,13 @@
package com.android.overlaytest.remounted;
-import static org.junit.Assert.assertTrue;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.RuleChain;
-import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class OverlaySharedLibraryTest extends BaseHostJUnit4Test {
- private static final String TARGET_APK = "OverlayRemountedTest_Target.apk";
- private static final String TARGET_PACKAGE = "com.android.overlaytest.remounted.target";
- private static final String SHARED_LIBRARY_APK =
- "OverlayRemountedTest_SharedLibrary.apk";
- private static final String SHARED_LIBRARY_PACKAGE =
- "com.android.overlaytest.remounted.shared_library";
- private static final String SHARED_LIBRARY_OVERLAY_APK =
- "OverlayRemountedTest_SharedLibraryOverlay.apk";
- private static final String SHARED_LIBRARY_OVERLAY_PACKAGE =
- "com.android.overlaytest.remounted.shared_library.overlay";
-
- public final TemporaryFolder temporaryFolder = new TemporaryFolder();
- public final SystemPreparer preparer = new SystemPreparer(temporaryFolder, this::getDevice);
-
- @Rule
- public final RuleChain ruleChain = RuleChain.outerRule(temporaryFolder).around(preparer);
-
- @Before
- public void startBefore() throws DeviceNotAvailableException {
- getDevice().waitForDeviceAvailable();
- }
+public class OverlaySharedLibraryTest extends OverlayRemountedTestBase {
@Test
public void testSharedLibrary() throws Exception {
@@ -60,7 +31,7 @@ public class OverlaySharedLibraryTest extends BaseHostJUnit4Test {
final String libraryResource = resourceName(SHARED_LIBRARY_PACKAGE, "bool",
"shared_library_overlaid");
- preparer.pushResourceFile(SHARED_LIBRARY_APK, "/product/app/SharedLibrary.apk")
+ mPreparer.pushResourceFile(SHARED_LIBRARY_APK, "/product/app/SharedLibrary.apk")
.installResourceApk(SHARED_LIBRARY_OVERLAY_APK, SHARED_LIBRARY_OVERLAY_PACKAGE)
.reboot()
.setOverlayEnabled(SHARED_LIBRARY_OVERLAY_PACKAGE, false)
@@ -71,7 +42,7 @@ public class OverlaySharedLibraryTest extends BaseHostJUnit4Test {
assertResource(libraryResource, "false");
// Overlay the shared library resource.
- preparer.setOverlayEnabled(SHARED_LIBRARY_OVERLAY_PACKAGE, true);
+ mPreparer.setOverlayEnabled(SHARED_LIBRARY_OVERLAY_PACKAGE, true);
assertResource(targetResource, "true");
assertResource(libraryResource, "true");
}
@@ -83,7 +54,7 @@ public class OverlaySharedLibraryTest extends BaseHostJUnit4Test {
final String libraryResource = resourceName(SHARED_LIBRARY_PACKAGE, "bool",
"shared_library_overlaid");
- preparer.pushResourceFile(SHARED_LIBRARY_APK, "/product/app/SharedLibrary.apk")
+ mPreparer.pushResourceFile(SHARED_LIBRARY_APK, "/product/app/SharedLibrary.apk")
.installResourceApk(SHARED_LIBRARY_OVERLAY_APK, SHARED_LIBRARY_OVERLAY_PACKAGE)
.setOverlayEnabled(SHARED_LIBRARY_OVERLAY_PACKAGE, true)
.reboot()
@@ -92,18 +63,4 @@ public class OverlaySharedLibraryTest extends BaseHostJUnit4Test {
assertResource(targetResource, "true");
assertResource(libraryResource, "true");
}
-
- /** Builds the full name of a resource in the form package:type/entry. */
- String resourceName(String pkg, String type, String entry) {
- return String.format("%s:%s/%s", pkg, type, entry);
- }
-
- void assertResource(String resourceName, String expectedValue)
- throws DeviceNotAvailableException {
- final String result = getDevice().executeShellCommand(
- String.format("cmd overlay lookup %s %s", TARGET_PACKAGE, resourceName));
- assertTrue(String.format("expected: <[%s]> in: <[%s]>", expectedValue, result),
- result.equals(expectedValue + "\n") ||
- result.endsWith("-> " + expectedValue + "\n"));
- }
}
diff --git a/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/PackagedUpgradedTest.java b/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/PackagedUpgradedTest.java
new file mode 100644
index 000000000000..f685ec1580ad
--- /dev/null
+++ b/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/PackagedUpgradedTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.overlaytest.remounted;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class PackagedUpgradedTest extends OverlayRemountedTestBase {
+
+ @Test
+ public void testTargetUpgrade() throws Exception {
+ final String targetOverlaid = resourceName(TARGET_PACKAGE, "bool", "target_overlaid");
+ final String targetReference = resourceName(TARGET_PACKAGE, "bool", "target_reference");
+
+ mPreparer.pushResourceFile(TARGET_APK, "/product/app/OverlayTarget.apk")
+ .reboot()
+ .installResourceApk(OVERLAY_APK, OVERLAY_PACKAGE)
+ .setOverlayEnabled(OVERLAY_PACKAGE, true);
+
+ assertResource(targetReference, "@" + 0x7f010000 + " -> true");
+ assertResource(targetOverlaid, "true");
+
+ mPreparer.installResourceApk(TARGET_UPGRADE_APK, TARGET_PACKAGE);
+
+ assertResource(targetReference, "@" + 0x7f0100ff + " -> true");
+ assertResource(targetOverlaid, "true");
+ }
+
+ @Test
+ public void testTargetRelocated() throws Exception {
+ final String targetOverlaid = resourceName(TARGET_PACKAGE, "bool", "target_overlaid");
+ final String originalPath = "/product/app/OverlayTarget.apk";
+
+ mPreparer.pushResourceFile(TARGET_APK, originalPath)
+ .reboot()
+ .installResourceApk(OVERLAY_APK, OVERLAY_PACKAGE)
+ .setOverlayEnabled(OVERLAY_PACKAGE, true);
+
+ assertResource(targetOverlaid, "true");
+
+ mPreparer.remount();
+ getDevice().deleteFile(originalPath);
+ mPreparer.pushResourceFile(TARGET_UPGRADE_APK, "/product/app/OverlayTarget2.apk")
+ .reboot();
+
+ assertResource(targetOverlaid, "true");
+ }
+}
diff --git a/core/tests/overlaytests/remount/host/src/com/android/overlaytest/remounted/SystemPreparer.java b/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/SystemPreparer.java
index 8696091239c2..b45b8eabf7c0 100644
--- a/core/tests/overlaytests/remount/host/src/com/android/overlaytest/remounted/SystemPreparer.java
+++ b/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/SystemPreparer.java
@@ -18,8 +18,6 @@ package com.android.overlaytest.remounted;
import static org.junit.Assert.assertTrue;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
@@ -32,10 +30,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeoutException;
class SystemPreparer extends ExternalResource {
private static final long OVERLAY_ENABLE_TIMEOUT_MS = 30000;
@@ -58,7 +52,7 @@ class SystemPreparer extends ExternalResource {
SystemPreparer pushResourceFile(String resourcePath,
String outputPath) throws DeviceNotAvailableException, IOException {
final ITestDevice device = mDeviceProvider.getDevice();
- device.executeAdbCommand("remount");
+ remount();
assertTrue(device.pushFile(copyResourceToTemp(resourcePath), outputPath));
mPushedFiles.add(outputPath);
return this;
@@ -69,7 +63,7 @@ class SystemPreparer extends ExternalResource {
throws DeviceNotAvailableException, IOException {
final ITestDevice device = mDeviceProvider.getDevice();
final File tmpFile = copyResourceToTemp(resourcePath);
- final String result = device.installPackage(tmpFile, true);
+ final String result = device.installPackage(tmpFile, true /* reinstall */);
Assert.assertNull(result);
mInstalledPackages.add(packageName);
return this;
@@ -77,34 +71,29 @@ class SystemPreparer extends ExternalResource {
/** Sets the enable state of an overlay pacakage. */
SystemPreparer setOverlayEnabled(String packageName, boolean enabled)
- throws ExecutionException, DeviceNotAvailableException {
+ throws DeviceNotAvailableException {
final ITestDevice device = mDeviceProvider.getDevice();
+ final String enable = enabled ? "enable" : "disable";
// Wait for the overlay to change its enabled state.
- final FutureTask<Boolean> enabledListener = new FutureTask<>(() -> {
- while (true) {
- device.executeShellCommand(String.format("cmd overlay %s %s",
- enabled ? "enable" : "disable", packageName));
-
- final String result = device.executeShellCommand("cmd overlay dump " + packageName);
- final int startIndex = result.indexOf("mIsEnabled");
- final int endIndex = result.indexOf('\n', startIndex);
- if (result.substring(startIndex, endIndex).contains((enabled) ? "true" : "false")) {
- return true;
- }
+ final long endMillis = System.currentTimeMillis() + OVERLAY_ENABLE_TIMEOUT_MS;
+ String result;
+ while (System.currentTimeMillis() <= endMillis) {
+ device.executeShellCommand(String.format("cmd overlay %s %s", enable, packageName));
+ result = device.executeShellCommand("cmd overlay dump isenabled "
+ + packageName);
+ if (((enabled) ? "true\n" : "false\n").equals(result)) {
+ return this;
}
- });
- final Executor executor = (cmd) -> new Thread(cmd).start();
- executor.execute(enabledListener);
- try {
- enabledListener.get(OVERLAY_ENABLE_TIMEOUT_MS, MILLISECONDS);
- } catch (InterruptedException ignored) {
- } catch (TimeoutException e) {
- throw new IllegalStateException(device.executeShellCommand("cmd overlay list"));
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException ignore) {
+ }
}
- return this;
+ throw new IllegalStateException(String.format("Failed to %s overlay %s:\n%s", enable,
+ packageName, device.executeShellCommand("cmd overlay list")));
}
/** Restarts the device and waits until after boot is completed. */
@@ -114,6 +103,11 @@ class SystemPreparer extends ExternalResource {
return this;
}
+ SystemPreparer remount() throws DeviceNotAvailableException {
+ mDeviceProvider.getDevice().executeAdbCommand("remount");
+ return this;
+ }
+
/** Copies a file within the host test jar to a temporary file on the host machine. */
private File copyResourceToTemp(String resourcePath) throws IOException {
final File tempFile = mHostTempFolder.newFile(resourcePath);
@@ -138,7 +132,7 @@ class SystemPreparer extends ExternalResource {
protected void after() {
final ITestDevice device = mDeviceProvider.getDevice();
try {
- device.executeAdbCommand("remount");
+ remount();
for (final String file : mPushedFiles) {
device.deleteFile(file);
}
diff --git a/core/tests/overlaytests/remount/test-apps/Overlay/Android.bp b/core/tests/overlaytests/remount/test-apps/Overlay/Android.bp
new file mode 100644
index 000000000000..447601972f78
--- /dev/null
+++ b/core/tests/overlaytests/remount/test-apps/Overlay/Android.bp
@@ -0,0 +1,18 @@
+// Copyright (C) 2019 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.
+
+android_test_helper_app {
+ name: "OverlayRemountedTest_Overlay",
+ sdk_version: "current",
+}
diff --git a/core/tests/overlaytests/remount/test-apps/Overlay/AndroidManifest.xml b/core/tests/overlaytests/remount/test-apps/Overlay/AndroidManifest.xml
new file mode 100644
index 000000000000..d6d706c2da62
--- /dev/null
+++ b/core/tests/overlaytests/remount/test-apps/Overlay/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.overlaytest.remounted.target.overlay">
+ <application android:hasCode="false" />
+ <overlay android:targetPackage="com.android.overlaytest.remounted.target"
+ android:targetName="TestResources" />
+</manifest> \ No newline at end of file
diff --git a/core/tests/overlaytests/remount/test-apps/Overlay/res/values/values.xml b/core/tests/overlaytests/remount/test-apps/Overlay/res/values/values.xml
new file mode 100644
index 000000000000..675e44f19f95
--- /dev/null
+++ b/core/tests/overlaytests/remount/test-apps/Overlay/res/values/values.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<resources>
+ <bool name="target_overlaid">true</bool>
+</resources>
diff --git a/core/tests/overlaytests/remount/host/test-apps/SharedLibrary/Android.bp b/core/tests/overlaytests/remount/test-apps/SharedLibrary/Android.bp
index ffb0572c3fd0..ffb0572c3fd0 100644
--- a/core/tests/overlaytests/remount/host/test-apps/SharedLibrary/Android.bp
+++ b/core/tests/overlaytests/remount/test-apps/SharedLibrary/Android.bp
diff --git a/core/tests/overlaytests/remount/host/test-apps/SharedLibrary/AndroidManifest.xml b/core/tests/overlaytests/remount/test-apps/SharedLibrary/AndroidManifest.xml
index 06e3f6a99410..06e3f6a99410 100644
--- a/core/tests/overlaytests/remount/host/test-apps/SharedLibrary/AndroidManifest.xml
+++ b/core/tests/overlaytests/remount/test-apps/SharedLibrary/AndroidManifest.xml
diff --git a/core/tests/overlaytests/remount/host/test-apps/SharedLibrary/res/values/overlayable.xml b/core/tests/overlaytests/remount/test-apps/SharedLibrary/res/values/overlayable.xml
index 1b06f6d7530b..1b06f6d7530b 100644
--- a/core/tests/overlaytests/remount/host/test-apps/SharedLibrary/res/values/overlayable.xml
+++ b/core/tests/overlaytests/remount/test-apps/SharedLibrary/res/values/overlayable.xml
diff --git a/core/tests/overlaytests/remount/host/test-apps/SharedLibrary/res/values/public.xml b/core/tests/overlaytests/remount/test-apps/SharedLibrary/res/values/public.xml
index 5b9db163a274..5b9db163a274 100644
--- a/core/tests/overlaytests/remount/host/test-apps/SharedLibrary/res/values/public.xml
+++ b/core/tests/overlaytests/remount/test-apps/SharedLibrary/res/values/public.xml
diff --git a/core/tests/overlaytests/remount/host/test-apps/SharedLibrary/res/values/values.xml b/core/tests/overlaytests/remount/test-apps/SharedLibrary/res/values/values.xml
index 2dc47a7ecf61..2dc47a7ecf61 100644
--- a/core/tests/overlaytests/remount/host/test-apps/SharedLibrary/res/values/values.xml
+++ b/core/tests/overlaytests/remount/test-apps/SharedLibrary/res/values/values.xml
diff --git a/core/tests/overlaytests/remount/host/test-apps/SharedLibraryOverlay/Android.bp b/core/tests/overlaytests/remount/test-apps/SharedLibraryOverlay/Android.bp
index 0d29aec909d5..0d29aec909d5 100644
--- a/core/tests/overlaytests/remount/host/test-apps/SharedLibraryOverlay/Android.bp
+++ b/core/tests/overlaytests/remount/test-apps/SharedLibraryOverlay/Android.bp
diff --git a/core/tests/overlaytests/remount/host/test-apps/SharedLibraryOverlay/AndroidManifest.xml b/core/tests/overlaytests/remount/test-apps/SharedLibraryOverlay/AndroidManifest.xml
index 53a4e61949da..53a4e61949da 100644
--- a/core/tests/overlaytests/remount/host/test-apps/SharedLibraryOverlay/AndroidManifest.xml
+++ b/core/tests/overlaytests/remount/test-apps/SharedLibraryOverlay/AndroidManifest.xml
diff --git a/core/tests/overlaytests/remount/host/test-apps/SharedLibraryOverlay/res/values/values.xml b/core/tests/overlaytests/remount/test-apps/SharedLibraryOverlay/res/values/values.xml
index f66448a8d991..f66448a8d991 100644
--- a/core/tests/overlaytests/remount/host/test-apps/SharedLibraryOverlay/res/values/values.xml
+++ b/core/tests/overlaytests/remount/test-apps/SharedLibraryOverlay/res/values/values.xml
diff --git a/core/tests/overlaytests/remount/target/Android.bp b/core/tests/overlaytests/remount/test-apps/Target/Android.bp
index 83f9f28b3f48..a8910eb8dae2 100644
--- a/core/tests/overlaytests/remount/target/Android.bp
+++ b/core/tests/overlaytests/remount/test-apps/Target/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 The Android Open Source Project
+// Copyright (C) 2019 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.
@@ -14,7 +14,12 @@
android_test_helper_app {
name: "OverlayRemountedTest_Target",
- srcs: ["src/**/*.java"],
sdk_version: "test_current",
libs: ["OverlayRemountedTest_SharedLibrary"],
}
+
+android_test_helper_app {
+ name: "OverlayRemountedTest_TargetUpgrade",
+ resource_dirs: ["res_upgrade"],
+ sdk_version: "test_current",
+}
diff --git a/core/tests/overlaytests/remount/target/AndroidManifest.xml b/core/tests/overlaytests/remount/test-apps/Target/AndroidManifest.xml
index dc07dca16718..d1c7b7e8bb9d 100644
--- a/core/tests/overlaytests/remount/target/AndroidManifest.xml
+++ b/core/tests/overlaytests/remount/test-apps/Target/AndroidManifest.xml
@@ -19,8 +19,7 @@
package="com.android.overlaytest.remounted.target">
<application>
- <uses-library android:name="android.test.runner" />
<uses-library android:name="com.android.overlaytest.remounted.shared_library"
- android:required="true" />
+ android:required="false" />
</application>
</manifest>
diff --git a/core/tests/overlaytests/remount/test-apps/Target/res/values/overlayable.xml b/core/tests/overlaytests/remount/test-apps/Target/res/values/overlayable.xml
new file mode 100644
index 000000000000..4aa5bcee8f3d
--- /dev/null
+++ b/core/tests/overlaytests/remount/test-apps/Target/res/values/overlayable.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<resources>
+ <overlayable name="TestResources">
+ <policy type="public">
+ <item type="bool" name="target_overlaid" />
+ </policy>
+ </overlayable>
+</resources>
diff --git a/core/tests/overlaytests/remount/target/res/values/values.xml b/core/tests/overlaytests/remount/test-apps/Target/res/values/values.xml
index b5f444a5eb72..76253a95b766 100644
--- a/core/tests/overlaytests/remount/target/res/values/values.xml
+++ b/core/tests/overlaytests/remount/test-apps/Target/res/values/values.xml
@@ -17,4 +17,10 @@
<resources xmlns:sharedlib="http://schemas.android.com/apk/res/com.android.overlaytest.remounted.shared_library">
<bool name="uses_shared_library_overlaid">@sharedlib:bool/shared_library_overlaid</bool>
+
+ <!-- This resource has a different id in the updated version of this target app to test that the
+ idmap is regenerated when the target is updated. -->
+ <bool name="target_overlaid">false</bool>
+ <public type="bool" name="target_overlaid" id="0x7f010000" />
+ <bool name="target_reference">@bool/target_overlaid</bool>
</resources>
diff --git a/core/tests/overlaytests/remount/test-apps/Target/res_upgrade/values/overlayable.xml b/core/tests/overlaytests/remount/test-apps/Target/res_upgrade/values/overlayable.xml
new file mode 100644
index 000000000000..4aa5bcee8f3d
--- /dev/null
+++ b/core/tests/overlaytests/remount/test-apps/Target/res_upgrade/values/overlayable.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<resources>
+ <overlayable name="TestResources">
+ <policy type="public">
+ <item type="bool" name="target_overlaid" />
+ </policy>
+ </overlayable>
+</resources>
diff --git a/core/tests/overlaytests/remount/test-apps/Target/res_upgrade/values/values.xml b/core/tests/overlaytests/remount/test-apps/Target/res_upgrade/values/values.xml
new file mode 100644
index 000000000000..f552cb0776ab
--- /dev/null
+++ b/core/tests/overlaytests/remount/test-apps/Target/res_upgrade/values/values.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+<resources>
+ <!-- This resource has a different id in the updated target app than the base target app to test
+ that the idmap is regenerated when the target is updated. -->
+ <bool name="target_overlaid">false</bool>
+ <public type="bool" name="target_overlaid" id="0x7f0100ff" />
+ <bool name="target_reference">@bool/target_overlaid</bool>
+</resources> \ No newline at end of file
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 918e7af12d31..05f4d6b63a4c 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -385,7 +385,7 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadOverlay(const std::string& idmap
const StringPiece idmap_data(
reinterpret_cast<const char*>(idmap_asset->getBuffer(true /*wordAligned*/)),
static_cast<size_t>(idmap_asset->getLength()));
- std::unique_ptr<const LoadedIdmap> loaded_idmap = LoadedIdmap::Load(idmap_data);
+ std::unique_ptr<const LoadedIdmap> loaded_idmap = LoadedIdmap::Load(idmap_path, idmap_data);
if (loaded_idmap == nullptr) {
LOG(ERROR) << "failed to load IDMAP " << idmap_path;
return {};
@@ -538,8 +538,9 @@ bool ApkAssets::IsUpToDate() const {
// Loaders are invalidated by the app, not the system, so assume they are up to date.
return true;
}
+ return (!loaded_idmap_ || loaded_idmap_->IsUpToDate()) &&
+ last_mod_time_ == getFileModDate(path_.c_str());
- return last_mod_time_ == getFileModDate(path_.c_str());
}
} // namespace android
diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp
index 0b2fd9ec982d..eb6ee9525bb9 100644
--- a/libs/androidfw/Idmap.cpp
+++ b/libs/androidfw/Idmap.cpp
@@ -20,6 +20,7 @@
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
+#include "androidfw/misc.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/Util.h"
#include "utils/ByteOrder.h"
@@ -192,7 +193,9 @@ static bool IsValidIdmapHeader(const StringPiece& data) {
return true;
}
-LoadedIdmap::LoadedIdmap(const Idmap_header* header,
+LoadedIdmap::LoadedIdmap(std::string&& idmap_path,
+ const time_t last_mod_time,
+ const Idmap_header* header,
const Idmap_data_header* data_header,
const Idmap_target_entry* target_entries,
const Idmap_overlay_entry* overlay_entries,
@@ -201,7 +204,9 @@ LoadedIdmap::LoadedIdmap(const Idmap_header* header,
data_header_(data_header),
target_entries_(target_entries),
overlay_entries_(overlay_entries),
- string_pool_(string_pool) {
+ string_pool_(string_pool),
+ idmap_path_(std::move(idmap_path)),
+ idmap_last_mod_time_(last_mod_time) {
size_t length = strnlen(reinterpret_cast<const char*>(header_->overlay_path),
arraysize(header_->overlay_path));
@@ -212,7 +217,8 @@ LoadedIdmap::LoadedIdmap(const Idmap_header* header,
target_apk_path_.assign(reinterpret_cast<const char*>(header_->target_path), length);
}
-std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_data) {
+std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_path,
+ const StringPiece& idmap_data) {
ATRACE_CALL();
if (!IsValidIdmapHeader(idmap_data)) {
return {};
@@ -275,10 +281,14 @@ std::unique_ptr<const LoadedIdmap> LoadedIdmap::Load(const StringPiece& idmap_da
// Can't use make_unique because LoadedIdmap constructor is private.
std::unique_ptr<LoadedIdmap> loaded_idmap = std::unique_ptr<LoadedIdmap>(
- new LoadedIdmap(header, data_header, target_entries, overlay_entries,
- idmap_string_pool.release()));
+ new LoadedIdmap(idmap_path.to_string(), getFileModDate(idmap_path.data()), header,
+ data_header, target_entries, overlay_entries, idmap_string_pool.release()));
return std::move(loaded_idmap);
}
+bool LoadedIdmap::IsUpToDate() const {
+ return idmap_last_mod_time_ == getFileModDate(idmap_path_.c_str());
+}
+
} // namespace android
diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h
index ccb57f373473..ecc1ce65d124 100644
--- a/libs/androidfw/include/androidfw/Idmap.h
+++ b/libs/androidfw/include/androidfw/Idmap.h
@@ -142,7 +142,13 @@ class IdmapResMap {
class LoadedIdmap {
public:
// Loads an IDMAP from a chunk of memory. Returns nullptr if the IDMAP data was malformed.
- static std::unique_ptr<const LoadedIdmap> Load(const StringPiece& idmap_data);
+ static std::unique_ptr<const LoadedIdmap> Load(const StringPiece& idmap_path,
+ const StringPiece& idmap_data);
+
+ // Returns the path to the IDMAP.
+ inline const std::string& IdmapPath() const {
+ return idmap_path_;
+ }
// Returns the path to the RRO (Runtime Resource Overlay) APK for which this IDMAP was generated.
inline const std::string& OverlayApkPath() const {
@@ -167,6 +173,10 @@ class LoadedIdmap {
return OverlayDynamicRefTable(data_header_, overlay_entries_, target_assigned_package_id);
}
+ // Returns whether the idmap file on disk has not been modified since the construction of this
+ // LoadedIdmap.
+ bool IsUpToDate() const;
+
protected:
// Exposed as protected so that tests can subclass and mock this class out.
LoadedIdmap() = default;
@@ -177,13 +187,17 @@ class LoadedIdmap {
const Idmap_overlay_entry* overlay_entries_;
const std::unique_ptr<ResStringPool> string_pool_;
+ const std::string idmap_path_;
std::string overlay_apk_path_;
std::string target_apk_path_;
+ const time_t idmap_last_mod_time_;
private:
DISALLOW_COPY_AND_ASSIGN(LoadedIdmap);
- explicit LoadedIdmap(const Idmap_header* header,
+ explicit LoadedIdmap(std::string&& idmap_path,
+ time_t last_mod_time,
+ const Idmap_header* header,
const Idmap_data_header* data_header,
const Idmap_target_entry* target_entries,
const Idmap_overlay_entry* overlay_entries,
diff --git a/libs/androidfw/tests/Idmap_test.cpp b/libs/androidfw/tests/Idmap_test.cpp
index 41ba637da5d7..7aa0dbbafab3 100644
--- a/libs/androidfw/tests/Idmap_test.cpp
+++ b/libs/androidfw/tests/Idmap_test.cpp
@@ -38,7 +38,7 @@ class IdmapTest : public ::testing::Test {
protected:
void SetUp() override {
// Move to the test data directory so the idmap can locate the overlay APK.
- std::string original_path = base::GetExecutableDirectory();
+ original_path = base::GetExecutableDirectory();
chdir(GetTestDataPath().c_str());
system_assets_ = ApkAssets::Load("system/system.apk");
@@ -49,10 +49,14 @@ class IdmapTest : public ::testing::Test {
overlayable_assets_ = ApkAssets::Load("overlayable/overlayable.apk");
ASSERT_NE(nullptr, overlayable_assets_);
+ }
+
+ void TearDown() override {
chdir(original_path.c_str());
}
protected:
+ std::string original_path;
std::unique_ptr<const ApkAssets> system_assets_;
std::unique_ptr<const ApkAssets> overlay_assets_;
std::unique_ptr<const ApkAssets> overlayable_assets_;
@@ -221,8 +225,7 @@ TEST_F(IdmapTest, OverlaidResourceHasSameName) {
TEST_F(IdmapTest, OverlayLoaderInterop) {
std::string contents;
- auto loader_assets = ApkAssets::LoadTable(GetTestDataPath() + "/loader/resources.arsc",
- PROPERTY_LOADER);
+ auto loader_assets = ApkAssets::LoadTable("loader/resources.arsc", PROPERTY_LOADER);
AssetManager2 asset_manager;
asset_manager.SetApkAssets({overlayable_assets_.get(), loader_assets.get(),
@@ -241,4 +244,25 @@ TEST_F(IdmapTest, OverlayLoaderInterop) {
ASSERT_EQ(GetStringFromApkAssets(asset_manager, val, cookie), "loader");
}
+TEST_F(IdmapTest, OverlayAssetsIsUpToDate) {
+ std::string idmap_contents;
+ ASSERT_TRUE(base::ReadFileToString("overlay/overlay.idmap", &idmap_contents));
+
+ TemporaryFile temp_file;
+ ASSERT_TRUE(base::WriteStringToFile(idmap_contents, temp_file.path));
+
+ auto apk_assets = ApkAssets::LoadOverlay(temp_file.path);
+ ASSERT_NE(nullptr, apk_assets);
+ ASSERT_TRUE(apk_assets->IsUpToDate());
+
+ unlink(temp_file.path);
+ ASSERT_FALSE(apk_assets->IsUpToDate());
+ sleep(2);
+
+ base::WriteStringToFile("hello", temp_file.path);
+ sleep(2);
+
+ ASSERT_FALSE(apk_assets->IsUpToDate());
+}
+
} // namespace
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index 43fc7ed0e39d..90c85ada9def 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -63,20 +63,23 @@ class IdmapManager {
mIdmapDaemon = IdmapDaemon.getInstance();
}
+ /**
+ * Creates the idmap for the target/overlay combination and returns whether the idmap file was
+ * modified.
+ */
boolean createIdmap(@NonNull final PackageInfo targetPackage,
@NonNull final PackageInfo overlayPackage, int userId) {
if (DEBUG) {
Slog.d(TAG, "create idmap for " + targetPackage.packageName + " and "
+ overlayPackage.packageName);
}
- final int sharedGid = UserHandle.getSharedAppGid(targetPackage.applicationInfo.uid);
final String targetPath = targetPackage.applicationInfo.getBaseCodePath();
final String overlayPath = overlayPackage.applicationInfo.getBaseCodePath();
try {
int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId);
boolean enforce = enforceOverlayable(overlayPackage);
if (mIdmapDaemon.verifyIdmap(targetPath, overlayPath, policies, enforce, userId)) {
- return true;
+ return false;
}
return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies,
enforce, userId) != null;
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index d108e76e37df..05a4a38feef1 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -700,14 +700,15 @@ final class OverlayManagerServiceImpl {
final PackageInfo overlayPackage = mPackageManager.getPackageInfo(overlayPackageName,
userId);
- // Immutable RROs targeting to "android", ie framework-res.apk, are handled by native layers.
+ // Immutable RROs targeting to "android", ie framework-res.apk, are handled by native
+ // layers.
+ boolean modified = false;
if (targetPackage != null && overlayPackage != null
&& !("android".equals(targetPackageName)
&& !isPackageConfiguredMutable(overlayPackageName))) {
- mIdmapManager.createIdmap(targetPackage, overlayPackage, userId);
+ modified |= mIdmapManager.createIdmap(targetPackage, overlayPackage, userId);
}
- boolean modified = false;
if (overlayPackage != null) {
modified |= mSettings.setBaseCodePath(overlayPackageName, userId,
overlayPackage.applicationInfo.getBaseCodePath());
diff --git a/services/core/java/com/android/server/om/TEST_MAPPING b/services/core/java/com/android/server/om/TEST_MAPPING
index 75229a1adccc..6edd76f1810a 100644
--- a/services/core/java/com/android/server/om/TEST_MAPPING
+++ b/services/core/java/com/android/server/om/TEST_MAPPING
@@ -15,6 +15,9 @@
"name": "OverlayHostTests"
},
{
+ "name": "OverlayRemountedTest"
+ },
+ {
"name": "CtsAppSecurityHostTestCases",
"options": [
{
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
index 820e61cb0a08..9eda718ed922 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
@@ -377,8 +377,7 @@ class OverlayManagerServiceImplTestsBase {
return false;
}
final String key = createKey(overlayPackage.packageName, userId);
- mIdmapFiles.add(key);
- return true;
+ return mIdmapFiles.add(key);
}
@Override