Loading cmds/idmap2/self_targeting/SelfTargeting.cpp +45 −10 Original line number Diff line number Diff line Loading @@ -38,9 +38,10 @@ namespace android::self_targeting { constexpr const mode_t kIdmapFilePermission = S_IRUSR | S_IWUSR; // u=rw-, g=---, o=--- extern "C" bool CreateFrroFile(std::string& out_err_result, std::string& packageName, std::string& overlayName, std::string& targetPackageName, std::optional<std::string>& targetOverlayable, std::vector<FabricatedOverlayEntryParameters>& entries_params, CreateFrroFile(std::string& out_err_result, const std::string& packageName, const std::string& overlayName, const std::string& targetPackageName, const std::optional<std::string>& targetOverlayable, const std::vector<FabricatedOverlayEntryParameters>& entries_params, const std::string& frro_file_path) { android::idmap2::FabricatedOverlay::Builder builder(packageName, overlayName, targetPackageName); Loading Loading @@ -90,9 +91,46 @@ CreateFrroFile(std::string& out_err_result, std::string& packageName, std::strin return true; } static PolicyBitmask GetFulfilledPolicy(const bool isSystem, const bool isVendor, const bool isProduct, const bool isTargetSignature, const bool isOdm, const bool isOem) { auto fulfilled_policy = static_cast<PolicyBitmask>(PolicyFlags::PUBLIC); if (isSystem) { fulfilled_policy |= PolicyFlags::SYSTEM_PARTITION; } if (isVendor) { fulfilled_policy |= PolicyFlags::VENDOR_PARTITION; } if (isProduct) { fulfilled_policy |= PolicyFlags::PRODUCT_PARTITION; } if (isOdm) { fulfilled_policy |= PolicyFlags::ODM_PARTITION; } if (isOem) { fulfilled_policy |= PolicyFlags::OEM_PARTITION; } if (isTargetSignature) { fulfilled_policy |= PolicyFlags::SIGNATURE; } // Not support actor_signature and config_overlay_signature fulfilled_policy &= ~(PolicyFlags::ACTOR_SIGNATURE | PolicyFlags::CONFIG_SIGNATURE); ALOGV( "fulfilled_policy = 0x%08x, isSystem = %d, isVendor = %d, isProduct = %d," " isTargetSignature = %d, isOdm = %d, isOem = %d,", fulfilled_policy, isSystem, isVendor, isProduct, isTargetSignature, isOdm, isOem); return fulfilled_policy; } extern "C" bool CreateIdmapFile(std::string& out_err, const std::string& targetPath, const std::string& overlayPath, const std::string& idmapPath, const std::string& overlayName) { const std::string& idmapPath, const std::string& overlayName, const bool isSystem, const bool isVendor, const bool isProduct, const bool isTargetSignature, const bool isOdm, const bool isOem) { // 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. The file must // be deleted before attempting to create the idmap, so that if idmap creation fails, the Loading @@ -114,14 +152,11 @@ CreateIdmapFile(std::string& out_err, const std::string& targetPath, const std:: } // Overlay self target process. Only allow self-targeting types. const auto fulfilled_policies = static_cast<PolicyBitmask>( PolicyFlags::PUBLIC | PolicyFlags::SYSTEM_PARTITION | PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE | PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | PolicyFlags::ACTOR_SIGNATURE | PolicyFlags::CONFIG_SIGNATURE); const auto fulfilled_policies = GetFulfilledPolicy(isSystem, isVendor, isProduct, isTargetSignature, isOdm, isOem); const auto idmap = Idmap::FromContainers(**target, **overlay, overlayName, fulfilled_policies, false /* enforce_overlayable */); fulfilled_policies, true /* enforce_overlayable */); if (!idmap) { out_err = base::StringPrintf("Failed to create idmap because of %s", idmap.GetErrorMessage().c_str()); Loading core/java/com/android/internal/content/om/OverlayManagerImpl.java +34 −2 Original line number Diff line number Diff line Loading @@ -170,6 +170,16 @@ public class OverlayManagerImpl { mBasePath = baseFile.toPath(); } private boolean isSameWithTargetSignature(final String targetPackage) { final PackageManager packageManager = mContext.getPackageManager(); final String packageName = mContext.getPackageName(); if (TextUtils.equals(packageName, targetPackage)) { return true; } return packageManager.checkSignatures(packageName, targetPackage) == PackageManager.SIGNATURE_MATCH; } /** * Check if the overlay name is valid or not. * Loading Loading @@ -202,6 +212,9 @@ public class OverlayManagerImpl { /** * Save FabricatedOverlay instance as frro and idmap files. * * <p>In order to fill the overlayable policy, it's necessary to collect the information from * app. And then, the information is passed to native layer to fill the overlayable policy * * @param overlayInternal the FabricatedOverlayInternal to be saved. */ public void registerFabricatedOverlay(@NonNull FabricatedOverlayInternal overlayInternal) Loading @@ -214,6 +227,9 @@ public class OverlayManagerImpl { final String overlayName = checkOverlayNameValid(overlayInternal.overlayName); checkPackageName(overlayInternal.packageName); checkPackageName(overlayInternal.targetPackageName); Preconditions.checkStringNotEmpty( overlayInternal.targetOverlayable, "Target overlayable should be neither null nor empty string."); final ApplicationInfo applicationInfo = mContext.getApplicationInfo(); final String targetPackage = Preconditions.checkStringNotEmpty( Loading @@ -223,7 +239,17 @@ public class OverlayManagerImpl { createFrroFile(frroPath.toString(), overlayInternal); try { createIdmapFile(targetPackage, frroPath.toString(), idmapPath.toString(), overlayName); createIdmapFile( targetPackage, frroPath.toString(), idmapPath.toString(), overlayName, applicationInfo.isSystemApp() || applicationInfo.isSystemExt() /* isSystem */, applicationInfo.isVendor(), applicationInfo.isProduct(), isSameWithTargetSignature(overlayInternal.targetPackageName), applicationInfo.isOdm(), applicationInfo.isOem()); } catch (IOException e) { if (!frroPath.toFile().delete()) { Log.w(TAG, "Failed to delete file " + frroPath); Loading Loading @@ -315,7 +341,13 @@ public class OverlayManagerImpl { @NonNull String targetPath, @NonNull String overlayPath, @NonNull String idmapPath, @NonNull String overlayName) @NonNull String overlayName, boolean isSystem, boolean isVendor, boolean isProduct, boolean isSameWithTargetSignature, boolean isOdm, boolean isOem) throws IOException; private static native FabricatedOverlayInfo getFabricatedOverlayInfo( Loading core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp +18 −6 Original line number Diff line number Diff line Loading @@ -123,8 +123,12 @@ public: bool callCreateIdmapFile(std::string& out_error, const std::string& targetPath, const std::string& overlayPath, const std::string& idmapPath, const std::string& overlayName) { return createIdmapFileFuncPtr_(out_error, targetPath, overlayPath, idmapPath, overlayName); const std::string& overlayName, const bool isSystem, const bool isVendor, const bool isProduct, const bool isTargetSignature, const bool isOdm, const bool isOem) { return createIdmapFileFuncPtr_(out_error, targetPath, overlayPath, idmapPath, overlayName, isSystem, isVendor, isProduct, isTargetSignature, isOdm, isOem); } bool callGetFabricatedOverlayInfo(std::string& out_error, const std::string& overlay_path, Loading Loading @@ -158,7 +162,10 @@ private: typedef bool (*CreateIdmapFileFunc)(std::string& out_error, const std::string& targetPath, const std::string& overlayPath, const std::string& idmapPath, const std::string& overlayName); const std::string& overlayName, const jboolean isSystem, const jboolean isVendor, const jboolean isProduct, const jboolean isSameWithTargetSignature, const jboolean isOdm, const jboolean isOem); typedef bool (*GetFabricatedOverlayInfoFunc)(std::string& out_error, const std::string& overlay_path, Loading Loading @@ -295,7 +302,9 @@ static void CreateFrroFile(JNIEnv* env, jclass /*clazz*/, jstring jsFrroFilePath } static void CreateIdmapFile(JNIEnv* env, jclass /* clazz */, jstring jsTargetPath, jstring jsOverlayPath, jstring jsIdmapPath, jstring jsOverlayName) { jstring jsOverlayPath, jstring jsIdmapPath, jstring jsOverlayName, jboolean isSystem, jboolean isVendor, jboolean isProduct, jboolean isTargetSignature, jboolean isOdm, jboolean isOem) { DynamicLibraryLoader& dlLoader = EnsureDynamicLibraryLoader(env); if (!dlLoader) { jniThrowNullPointerException(env, "libidmap2 is not loaded"); Loading Loading @@ -327,7 +336,10 @@ static void CreateIdmapFile(JNIEnv* env, jclass /* clazz */, jstring jsTargetPat std::string err_result; if (!dlLoader.callCreateIdmapFile(err_result, targetPath.c_str(), overlayPath.c_str(), idmapPath.c_str(), overlayName.c_str())) { idmapPath.c_str(), overlayName.c_str(), (isSystem == JNI_TRUE), (isVendor == JNI_TRUE), (isProduct == JNI_TRUE), (isTargetSignature == JNI_TRUE), (isOdm == JNI_TRUE), (isOem == JNI_TRUE))) { jniThrowException(env, kIOException, err_result.c_str()); return; } Loading Loading @@ -374,7 +386,7 @@ static const JNINativeMethod gOverlayManagerMethods[] = { {"createFrroFile", "(Ljava/lang/String;Landroid/os/FabricatedOverlayInternal;)V", reinterpret_cast<void*>(self_targeting::CreateFrroFile)}, {"createIdmapFile", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZZZZ)V", reinterpret_cast<void*>(self_targeting::CreateIdmapFile)}, {"getFabricatedOverlayInfo", "(Ljava/lang/String;)Landroid/os/FabricatedOverlayInfo;", reinterpret_cast<void*>(self_targeting::GetFabricatedOverlayInfo)}, Loading core/tests/overlaytests/device_self_targeting/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ android_test { "androidx.test.rules", "androidx.test.runner", "androidx.test.ext.junit", "mockito-target-minus-junit4", "truth-prebuilt", ], Loading core/tests/overlaytests/device_self_targeting/res/values/overlayable.xml 0 → 100644 +84 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2022 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="PublicOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="public"> <item type="color" name="public_overlayable_color" /> </policy> </overlayable> <overlayable name="SignatureOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="signature"> <item type="color" name="mycolor" /> <item type="color" name="signature_overlayable_color" /> <item type="string" name="mystring" /> <item type="drawable" name="mydrawable" /> </policy> </overlayable> <overlayable name="SystemAppOverlayable" actor="overlay://theme"> <!-- The app in system partition can overlay the below resources --> <policy type="system"> <item type="color" name="system_app_overlayable_color" /> </policy> </overlayable> <overlayable name="OdmOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="odm"> <item type="color" name="odm_overlayable_color" /> </policy> </overlayable> <overlayable name="OemOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="oem"> <item type="color" name="oem_overlayable_color" /> </policy> </overlayable> <overlayable name="VendorOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="vendor"> <item type="color" name="vendor_overlayable_color" /> </policy> </overlayable> <overlayable name="ProductOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="product"> <item type="color" name="product_overlayable_color" /> </policy> </overlayable> <overlayable name="ActorOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="actor"> <item type="color" name="actor_overlayable_color" /> </policy> </overlayable> <overlayable name="ConfigOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="config_signature"> <item type="color" name="config_overlayable_color" /> </policy> </overlayable> </resources> Loading
cmds/idmap2/self_targeting/SelfTargeting.cpp +45 −10 Original line number Diff line number Diff line Loading @@ -38,9 +38,10 @@ namespace android::self_targeting { constexpr const mode_t kIdmapFilePermission = S_IRUSR | S_IWUSR; // u=rw-, g=---, o=--- extern "C" bool CreateFrroFile(std::string& out_err_result, std::string& packageName, std::string& overlayName, std::string& targetPackageName, std::optional<std::string>& targetOverlayable, std::vector<FabricatedOverlayEntryParameters>& entries_params, CreateFrroFile(std::string& out_err_result, const std::string& packageName, const std::string& overlayName, const std::string& targetPackageName, const std::optional<std::string>& targetOverlayable, const std::vector<FabricatedOverlayEntryParameters>& entries_params, const std::string& frro_file_path) { android::idmap2::FabricatedOverlay::Builder builder(packageName, overlayName, targetPackageName); Loading Loading @@ -90,9 +91,46 @@ CreateFrroFile(std::string& out_err_result, std::string& packageName, std::strin return true; } static PolicyBitmask GetFulfilledPolicy(const bool isSystem, const bool isVendor, const bool isProduct, const bool isTargetSignature, const bool isOdm, const bool isOem) { auto fulfilled_policy = static_cast<PolicyBitmask>(PolicyFlags::PUBLIC); if (isSystem) { fulfilled_policy |= PolicyFlags::SYSTEM_PARTITION; } if (isVendor) { fulfilled_policy |= PolicyFlags::VENDOR_PARTITION; } if (isProduct) { fulfilled_policy |= PolicyFlags::PRODUCT_PARTITION; } if (isOdm) { fulfilled_policy |= PolicyFlags::ODM_PARTITION; } if (isOem) { fulfilled_policy |= PolicyFlags::OEM_PARTITION; } if (isTargetSignature) { fulfilled_policy |= PolicyFlags::SIGNATURE; } // Not support actor_signature and config_overlay_signature fulfilled_policy &= ~(PolicyFlags::ACTOR_SIGNATURE | PolicyFlags::CONFIG_SIGNATURE); ALOGV( "fulfilled_policy = 0x%08x, isSystem = %d, isVendor = %d, isProduct = %d," " isTargetSignature = %d, isOdm = %d, isOem = %d,", fulfilled_policy, isSystem, isVendor, isProduct, isTargetSignature, isOdm, isOem); return fulfilled_policy; } extern "C" bool CreateIdmapFile(std::string& out_err, const std::string& targetPath, const std::string& overlayPath, const std::string& idmapPath, const std::string& overlayName) { const std::string& idmapPath, const std::string& overlayName, const bool isSystem, const bool isVendor, const bool isProduct, const bool isTargetSignature, const bool isOdm, const bool isOem) { // 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. The file must // be deleted before attempting to create the idmap, so that if idmap creation fails, the Loading @@ -114,14 +152,11 @@ CreateIdmapFile(std::string& out_err, const std::string& targetPath, const std:: } // Overlay self target process. Only allow self-targeting types. const auto fulfilled_policies = static_cast<PolicyBitmask>( PolicyFlags::PUBLIC | PolicyFlags::SYSTEM_PARTITION | PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE | PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | PolicyFlags::ACTOR_SIGNATURE | PolicyFlags::CONFIG_SIGNATURE); const auto fulfilled_policies = GetFulfilledPolicy(isSystem, isVendor, isProduct, isTargetSignature, isOdm, isOem); const auto idmap = Idmap::FromContainers(**target, **overlay, overlayName, fulfilled_policies, false /* enforce_overlayable */); fulfilled_policies, true /* enforce_overlayable */); if (!idmap) { out_err = base::StringPrintf("Failed to create idmap because of %s", idmap.GetErrorMessage().c_str()); Loading
core/java/com/android/internal/content/om/OverlayManagerImpl.java +34 −2 Original line number Diff line number Diff line Loading @@ -170,6 +170,16 @@ public class OverlayManagerImpl { mBasePath = baseFile.toPath(); } private boolean isSameWithTargetSignature(final String targetPackage) { final PackageManager packageManager = mContext.getPackageManager(); final String packageName = mContext.getPackageName(); if (TextUtils.equals(packageName, targetPackage)) { return true; } return packageManager.checkSignatures(packageName, targetPackage) == PackageManager.SIGNATURE_MATCH; } /** * Check if the overlay name is valid or not. * Loading Loading @@ -202,6 +212,9 @@ public class OverlayManagerImpl { /** * Save FabricatedOverlay instance as frro and idmap files. * * <p>In order to fill the overlayable policy, it's necessary to collect the information from * app. And then, the information is passed to native layer to fill the overlayable policy * * @param overlayInternal the FabricatedOverlayInternal to be saved. */ public void registerFabricatedOverlay(@NonNull FabricatedOverlayInternal overlayInternal) Loading @@ -214,6 +227,9 @@ public class OverlayManagerImpl { final String overlayName = checkOverlayNameValid(overlayInternal.overlayName); checkPackageName(overlayInternal.packageName); checkPackageName(overlayInternal.targetPackageName); Preconditions.checkStringNotEmpty( overlayInternal.targetOverlayable, "Target overlayable should be neither null nor empty string."); final ApplicationInfo applicationInfo = mContext.getApplicationInfo(); final String targetPackage = Preconditions.checkStringNotEmpty( Loading @@ -223,7 +239,17 @@ public class OverlayManagerImpl { createFrroFile(frroPath.toString(), overlayInternal); try { createIdmapFile(targetPackage, frroPath.toString(), idmapPath.toString(), overlayName); createIdmapFile( targetPackage, frroPath.toString(), idmapPath.toString(), overlayName, applicationInfo.isSystemApp() || applicationInfo.isSystemExt() /* isSystem */, applicationInfo.isVendor(), applicationInfo.isProduct(), isSameWithTargetSignature(overlayInternal.targetPackageName), applicationInfo.isOdm(), applicationInfo.isOem()); } catch (IOException e) { if (!frroPath.toFile().delete()) { Log.w(TAG, "Failed to delete file " + frroPath); Loading Loading @@ -315,7 +341,13 @@ public class OverlayManagerImpl { @NonNull String targetPath, @NonNull String overlayPath, @NonNull String idmapPath, @NonNull String overlayName) @NonNull String overlayName, boolean isSystem, boolean isVendor, boolean isProduct, boolean isSameWithTargetSignature, boolean isOdm, boolean isOem) throws IOException; private static native FabricatedOverlayInfo getFabricatedOverlayInfo( Loading
core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp +18 −6 Original line number Diff line number Diff line Loading @@ -123,8 +123,12 @@ public: bool callCreateIdmapFile(std::string& out_error, const std::string& targetPath, const std::string& overlayPath, const std::string& idmapPath, const std::string& overlayName) { return createIdmapFileFuncPtr_(out_error, targetPath, overlayPath, idmapPath, overlayName); const std::string& overlayName, const bool isSystem, const bool isVendor, const bool isProduct, const bool isTargetSignature, const bool isOdm, const bool isOem) { return createIdmapFileFuncPtr_(out_error, targetPath, overlayPath, idmapPath, overlayName, isSystem, isVendor, isProduct, isTargetSignature, isOdm, isOem); } bool callGetFabricatedOverlayInfo(std::string& out_error, const std::string& overlay_path, Loading Loading @@ -158,7 +162,10 @@ private: typedef bool (*CreateIdmapFileFunc)(std::string& out_error, const std::string& targetPath, const std::string& overlayPath, const std::string& idmapPath, const std::string& overlayName); const std::string& overlayName, const jboolean isSystem, const jboolean isVendor, const jboolean isProduct, const jboolean isSameWithTargetSignature, const jboolean isOdm, const jboolean isOem); typedef bool (*GetFabricatedOverlayInfoFunc)(std::string& out_error, const std::string& overlay_path, Loading Loading @@ -295,7 +302,9 @@ static void CreateFrroFile(JNIEnv* env, jclass /*clazz*/, jstring jsFrroFilePath } static void CreateIdmapFile(JNIEnv* env, jclass /* clazz */, jstring jsTargetPath, jstring jsOverlayPath, jstring jsIdmapPath, jstring jsOverlayName) { jstring jsOverlayPath, jstring jsIdmapPath, jstring jsOverlayName, jboolean isSystem, jboolean isVendor, jboolean isProduct, jboolean isTargetSignature, jboolean isOdm, jboolean isOem) { DynamicLibraryLoader& dlLoader = EnsureDynamicLibraryLoader(env); if (!dlLoader) { jniThrowNullPointerException(env, "libidmap2 is not loaded"); Loading Loading @@ -327,7 +336,10 @@ static void CreateIdmapFile(JNIEnv* env, jclass /* clazz */, jstring jsTargetPat std::string err_result; if (!dlLoader.callCreateIdmapFile(err_result, targetPath.c_str(), overlayPath.c_str(), idmapPath.c_str(), overlayName.c_str())) { idmapPath.c_str(), overlayName.c_str(), (isSystem == JNI_TRUE), (isVendor == JNI_TRUE), (isProduct == JNI_TRUE), (isTargetSignature == JNI_TRUE), (isOdm == JNI_TRUE), (isOem == JNI_TRUE))) { jniThrowException(env, kIOException, err_result.c_str()); return; } Loading Loading @@ -374,7 +386,7 @@ static const JNINativeMethod gOverlayManagerMethods[] = { {"createFrroFile", "(Ljava/lang/String;Landroid/os/FabricatedOverlayInternal;)V", reinterpret_cast<void*>(self_targeting::CreateFrroFile)}, {"createIdmapFile", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZZZZ)V", reinterpret_cast<void*>(self_targeting::CreateIdmapFile)}, {"getFabricatedOverlayInfo", "(Ljava/lang/String;)Landroid/os/FabricatedOverlayInfo;", reinterpret_cast<void*>(self_targeting::GetFabricatedOverlayInfo)}, Loading
core/tests/overlaytests/device_self_targeting/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ android_test { "androidx.test.rules", "androidx.test.runner", "androidx.test.ext.junit", "mockito-target-minus-junit4", "truth-prebuilt", ], Loading
core/tests/overlaytests/device_self_targeting/res/values/overlayable.xml 0 → 100644 +84 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright (C) 2022 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="PublicOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="public"> <item type="color" name="public_overlayable_color" /> </policy> </overlayable> <overlayable name="SignatureOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="signature"> <item type="color" name="mycolor" /> <item type="color" name="signature_overlayable_color" /> <item type="string" name="mystring" /> <item type="drawable" name="mydrawable" /> </policy> </overlayable> <overlayable name="SystemAppOverlayable" actor="overlay://theme"> <!-- The app in system partition can overlay the below resources --> <policy type="system"> <item type="color" name="system_app_overlayable_color" /> </policy> </overlayable> <overlayable name="OdmOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="odm"> <item type="color" name="odm_overlayable_color" /> </policy> </overlayable> <overlayable name="OemOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="oem"> <item type="color" name="oem_overlayable_color" /> </policy> </overlayable> <overlayable name="VendorOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="vendor"> <item type="color" name="vendor_overlayable_color" /> </policy> </overlayable> <overlayable name="ProductOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="product"> <item type="color" name="product_overlayable_color" /> </policy> </overlayable> <overlayable name="ActorOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="actor"> <item type="color" name="actor_overlayable_color" /> </policy> </overlayable> <overlayable name="ConfigOverlayable" actor="overlay://theme"> <!-- The app with the same signature can overlay the below resources --> <policy type="config_signature"> <item type="color" name="config_overlayable_color" /> </policy> </overlayable> </resources>