Merge "Enforce the overlayable mechanism for self-targeting"

This commit is contained in:
TreeHugger Robot
2022-11-29 08:40:11 +00:00
committed by Android (Google) Code Review
7 changed files with 425 additions and 19 deletions

View File

@@ -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);
@@ -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
@@ -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());

View File

@@ -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.
*
@@ -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)
@@ -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(
@@ -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);
@@ -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(

View File

@@ -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,
@@ -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,
@@ -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");
@@ -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;
}
@@ -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)},

View File

@@ -29,6 +29,7 @@ android_test {
"androidx.test.rules",
"androidx.test.runner",
"androidx.test.ext.junit",
"mockito-target-minus-junit4",
"truth-prebuilt",
],

View File

@@ -0,0 +1,84 @@
<?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>

View File

@@ -17,4 +17,14 @@
<resources>
<color name="mycolor">#ff112233</color>
<string name="mystring">hello</string>
<color name="public_overlayable_color">#000</color>
<color name="signature_overlayable_color">#000</color>
<color name="system_app_overlayable_color">#000</color>
<color name="odm_overlayable_color">#000</color>
<color name="oem_overlayable_color">#000</color>
<color name="vendor_overlayable_color">#000</color>
<color name="product_overlayable_color">#000</color>
<color name="actor_overlayable_color">#000</color>
<color name="config_overlayable_color">#000</color>
</resources>

View File

@@ -17,15 +17,22 @@
package com.android.overlaytest;
import static android.content.Context.MODE_PRIVATE;
import static android.content.pm.PackageManager.SIGNATURE_NO_MATCH;
import static com.android.internal.content.om.OverlayManagerImpl.SELF_TARGET;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.om.OverlayInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.FabricatedOverlayInternal;
@@ -72,11 +79,23 @@ public class OverlayManagerImplTest {
private static final String TARGET_COLOR_RES = "color/mycolor";
private static final String TARGET_STRING_RES = "string/mystring";
private static final String TARGET_DRAWABLE_RES = "drawable/mydrawable";
private static final String PUBLIC_OVERLAYABLE = "PublicOverlayable";
private static final String SIGNATURE_OVERLAYABLE = "SignatureOverlayable";
private static final String SYSTEM_APP_OVERLAYABLE = "SystemAppOverlayable";
private static final String ODM_OVERLAYABLE = "OdmOverlayable";
private static final String OEM_OVERLAYABLE = "OemOverlayable";
private static final String VENDOR_OVERLAYABLE = "VendorOverlayable";
private static final String PRODUCT_OVERLAYABLE = "ProductOverlayable";
private static final String ACTOR_OVERLAYABLE = "ActorOverlayable";
private static final String CONFIG_OVERLAYABLE = "ConfigOverlayable";
private Context mContext;
private OverlayManagerImpl mOverlayManagerImpl;
private String mOverlayName;
private PackageManager mMockPackageManager;
private ApplicationInfo mMockApplicationInfo;
@Rule public TestName mTestName = new TestName();
@Rule public Expect expect = Expect.create();
@@ -111,7 +130,36 @@ public class OverlayManagerImplTest {
public void setUp() throws IOException {
clearDir();
mOverlayName = mTestName.getMethodName();
mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
mMockApplicationInfo = mock(ApplicationInfo.class);
when(mMockApplicationInfo.isSystemApp()).thenReturn(false);
when(mMockApplicationInfo.isSystemExt()).thenReturn(false);
when(mMockApplicationInfo.isOdm()).thenReturn(false);
when(mMockApplicationInfo.isOem()).thenReturn(false);
when(mMockApplicationInfo.isVendor()).thenReturn(false);
when(mMockApplicationInfo.isProduct()).thenReturn(false);
when(mMockApplicationInfo.getBaseCodePath()).thenReturn(
context.getApplicationInfo().getBaseCodePath());
mMockApplicationInfo.sourceDir = context.getApplicationInfo().sourceDir;
mMockPackageManager = mock(PackageManager.class);
when(mMockPackageManager.checkSignatures(anyString(), anyString()))
.thenReturn(SIGNATURE_NO_MATCH);
mContext =
new ContextWrapper(context) {
@Override
public ApplicationInfo getApplicationInfo() {
return mMockApplicationInfo;
}
@Override
public PackageManager getPackageManager() {
return mMockPackageManager;
}
};
mOverlayManagerImpl = new OverlayManagerImpl(mContext);
}
@@ -144,12 +192,14 @@ public class OverlayManagerImplTest {
private <T> FabricatedOverlayInternal createOverlayWithName(
@NonNull String overlayName,
@NonNull String targetOverlayable,
@NonNull String targetPackageName,
@NonNull List<Pair<String, Pair<String, T>>> entryDefinitions) {
final String packageName = mContext.getPackageName();
FabricatedOverlayInternal overlayInternal = new FabricatedOverlayInternal();
overlayInternal.overlayName = overlayName;
overlayInternal.targetPackageName = targetPackageName;
overlayInternal.targetOverlayable = targetOverlayable;
overlayInternal.packageName = packageName;
addOverlayEntry(overlayInternal, entryDefinitions);
@@ -162,6 +212,7 @@ public class OverlayManagerImplTest {
FabricatedOverlayInternal overlayInternal =
createOverlayWithName(
mOverlayName,
SYSTEM_APP_OVERLAYABLE,
"android",
List.of(Pair.create("color/white", Pair.create(null, Color.BLACK))));
@@ -190,6 +241,7 @@ public class OverlayManagerImplTest {
FabricatedOverlayInternal overlayInternal =
createOverlayWithName(
mOverlayName,
SIGNATURE_OVERLAYABLE,
mContext.getPackageName(),
List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE))));
@@ -215,6 +267,7 @@ public class OverlayManagerImplTest {
FabricatedOverlayInternal overlayInternal =
createOverlayWithName(
mOverlayName,
SIGNATURE_OVERLAYABLE,
mContext.getPackageName(),
List.of(Pair.create(TARGET_STRING_RES, Pair.create(null, "HELLO"))));
@@ -242,6 +295,7 @@ public class OverlayManagerImplTest {
FabricatedOverlayInternal overlayInternal =
createOverlayWithName(
mOverlayName,
SIGNATURE_OVERLAYABLE,
mContext.getPackageName(),
List.of(Pair.create(TARGET_DRAWABLE_RES,
Pair.create(null, parcelFileDescriptor))));
@@ -268,6 +322,7 @@ public class OverlayManagerImplTest {
FabricatedOverlayInternal overlayInternal =
createOverlayWithName(
mOverlayName,
SIGNATURE_OVERLAYABLE,
mContext.getPackageName(),
List.of(Pair.create("color/not_existed", Pair.create(null, "HELLO"))));
@@ -301,6 +356,7 @@ public class OverlayManagerImplTest {
FabricatedOverlayInternal overlayInternal =
createOverlayWithName(
mOverlayName,
SIGNATURE_OVERLAYABLE,
mContext.getPackageName(),
List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE))));
mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
@@ -309,6 +365,7 @@ public class OverlayManagerImplTest {
overlayInternal =
createOverlayWithName(
secondOverlayName,
SIGNATURE_OVERLAYABLE,
mContext.getPackageName(),
List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE))));
mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
@@ -341,6 +398,7 @@ public class OverlayManagerImplTest {
FabricatedOverlayInternal overlayInternal =
createOverlayWithName(
mOverlayName,
SIGNATURE_OVERLAYABLE,
mContext.getPackageName(),
List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE))));
mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
@@ -349,6 +407,7 @@ public class OverlayManagerImplTest {
overlayInternal =
createOverlayWithName(
mOverlayName,
SIGNATURE_OVERLAYABLE,
mContext.getPackageName(),
List.of(Pair.create(TARGET_COLOR_RES, Pair.create(null, Color.WHITE))));
mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
@@ -408,4 +467,177 @@ public class OverlayManagerImplTest {
assertThrows(SecurityException.class, () -> new OverlayManagerImpl(fakeContext));
}
FabricatedOverlayInternal prepareFabricatedOverlayInternal(
String targetOverlayableName, String targetEntryName) {
return createOverlayWithName(
mOverlayName,
targetOverlayableName,
mContext.getPackageName(),
List.of(
Pair.create(
targetEntryName,
Pair.create(null, Color.WHITE))));
}
@Test
public void registerOverlayOnSystemOverlayable_selfIsNotSystemApp_shouldFail() {
final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
SYSTEM_APP_OVERLAYABLE,
"color/system_app_overlayable_color");
assertThrows(
IOException.class,
() -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
}
@Test
public void registerOverlayOnOdmOverlayable_selfIsNotOdm_shouldFail() {
final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
ODM_OVERLAYABLE,
"color/odm_overlayable_color");
assertThrows(
IOException.class,
() -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
}
@Test
public void registerOverlayOnOemOverlayable_selfIsNotOem_shouldFail() {
final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
OEM_OVERLAYABLE,
"color/oem_overlayable_color");
assertThrows(
IOException.class,
() -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
}
@Test
public void registerOverlayOnVendorOverlayable_selfIsNotVendor_shouldFail() {
final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
VENDOR_OVERLAYABLE,
"color/vendor_overlayable_color");
assertThrows(
IOException.class,
() -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
}
@Test
public void registerOverlayOnProductOverlayable_selfIsNotProduct_shouldFail() {
final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
PRODUCT_OVERLAYABLE,
"color/product_overlayable_color");
assertThrows(
IOException.class,
() -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
}
@Test
public void registerOverlayOnActorOverlayable_notSupport_shouldFail() {
final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
ACTOR_OVERLAYABLE,
"color/actor_overlayable_color");
assertThrows(
IOException.class,
() -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
}
@Test
public void registerOverlayOnConfigOverlayable_notSupport_shouldFail() {
final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
CONFIG_OVERLAYABLE,
"color/config_overlayable_color");
assertThrows(
IOException.class,
() -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
}
@Test
public void registerOverlayOnPublicOverlayable_shouldAlwaysSucceed()
throws PackageManager.NameNotFoundException, IOException {
final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
PUBLIC_OVERLAYABLE,
"color/public_overlayable_color");
mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
assertThat(mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size())
.isEqualTo(1);
}
@Test
public void registerOverlayOnSystemOverlayable_selfIsSystemApp_shouldSucceed()
throws PackageManager.NameNotFoundException, IOException {
final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
SYSTEM_APP_OVERLAYABLE,
"color/system_app_overlayable_color");
when(mMockApplicationInfo.isSystemApp()).thenReturn(true);
when(mMockApplicationInfo.isSystemExt()).thenReturn(true);
mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
assertThat(mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size())
.isEqualTo(1);
}
@Test
public void registerOverlayOnOdmOverlayable_selfIsOdm_shouldSucceed()
throws PackageManager.NameNotFoundException, IOException {
final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
ODM_OVERLAYABLE,
"color/odm_overlayable_color");
when(mMockApplicationInfo.isOdm()).thenReturn(true);
mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
assertThat(mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size())
.isEqualTo(1);
}
@Test
public void registerOverlayOnOemOverlayable_selfIsOem_shouldSucceed()
throws PackageManager.NameNotFoundException, IOException {
final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
OEM_OVERLAYABLE,
"color/oem_overlayable_color");
when(mMockApplicationInfo.isOem()).thenReturn(true);
mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
assertThat(mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size())
.isEqualTo(1);
}
@Test
public void registerOverlayOnVendorOverlayable_selfIsVendor_shouldSucceed()
throws PackageManager.NameNotFoundException, IOException {
final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
VENDOR_OVERLAYABLE,
"color/vendor_overlayable_color");
when(mMockApplicationInfo.isVendor()).thenReturn(true);
mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
assertThat(mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size())
.isEqualTo(1);
}
@Test
public void registerOverlayOnProductOverlayable_selfIsProduct_shouldSucceed()
throws PackageManager.NameNotFoundException, IOException {
final FabricatedOverlayInternal overlayInternal = prepareFabricatedOverlayInternal(
PRODUCT_OVERLAYABLE,
"color/product_overlayable_color");
when(mMockApplicationInfo.isProduct()).thenReturn(true);
mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal);
assertThat(mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName()).size())
.isEqualTo(1);
}
}