summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/content/om/OverlayManagerImpl.java54
-rw-r--r--core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java36
2 files changed, 87 insertions, 3 deletions
diff --git a/core/java/com/android/internal/content/om/OverlayManagerImpl.java b/core/java/com/android/internal/content/om/OverlayManagerImpl.java
index e56c06e318a8..6ceccd1b544b 100644
--- a/core/java/com/android/internal/content/om/OverlayManagerImpl.java
+++ b/core/java/com/android/internal/content/om/OverlayManagerImpl.java
@@ -17,14 +17,20 @@
package com.android.internal.content.om;
import static android.content.Context.MODE_PRIVATE;
+import static android.content.om.OverlayManagerTransaction.Request.BUNDLE_FABRICATED_OVERLAY;
+import static android.content.om.OverlayManagerTransaction.Request.TYPE_REGISTER_FABRICATED;
+import static android.content.om.OverlayManagerTransaction.Request.TYPE_UNREGISTER_FABRICATED;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
import static com.android.internal.content.om.OverlayConfig.DEFAULT_PRIORITY;
import android.annotation.NonNull;
+import android.annotation.NonUiContext;
import android.content.Context;
+import android.content.om.OverlayIdentifier;
import android.content.om.OverlayInfo;
+import android.content.om.OverlayManagerTransaction;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.parsing.FrameworkParsingPackageUtils;
@@ -48,6 +54,7 @@ import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Objects;
@@ -129,10 +136,9 @@ public class OverlayManagerImpl {
}
}
- /**
- * Ensure the base dir for self-targeting is valid.
- */
+ /** Ensure the base dir for self-targeting is valid. */
@VisibleForTesting
+ @NonUiContext
public void ensureBaseDir() {
final String baseApkPath = mContext.getApplicationInfo().getBaseCodePath();
final Path baseApkFolderName = Path.of(baseApkPath).getParent().getFileName();
@@ -217,6 +223,7 @@ public class OverlayManagerImpl {
*
* @param overlayInternal the FabricatedOverlayInternal to be saved.
*/
+ @NonUiContext
public void registerFabricatedOverlay(@NonNull FabricatedOverlayInternal overlayInternal)
throws IOException, PackageManager.NameNotFoundException {
ensureBaseDir();
@@ -263,6 +270,7 @@ public class OverlayManagerImpl {
*
* @param overlayName the specific name
*/
+ @NonUiContext
public void unregisterFabricatedOverlay(@NonNull String overlayName) {
ensureBaseDir();
checkOverlayNameValid(overlayName);
@@ -278,6 +286,46 @@ public class OverlayManagerImpl {
}
/**
+ * Commit the overlay manager transaction
+ *
+ * @param transaction the overlay manager transaction
+ */
+ @NonUiContext
+ public void commit(@NonNull OverlayManagerTransaction transaction)
+ throws PackageManager.NameNotFoundException, IOException {
+ Objects.requireNonNull(transaction);
+
+ for (Iterator<OverlayManagerTransaction.Request> it = transaction.iterator();
+ it.hasNext(); ) {
+ final OverlayManagerTransaction.Request request = it.next();
+ if (request.type == TYPE_REGISTER_FABRICATED) {
+ final FabricatedOverlayInternal fabricatedOverlayInternal =
+ Objects.requireNonNull(
+ request.extras.getParcelable(
+ BUNDLE_FABRICATED_OVERLAY,
+ FabricatedOverlayInternal.class));
+
+ // populate the mandatory data
+ if (TextUtils.isEmpty(fabricatedOverlayInternal.packageName)) {
+ fabricatedOverlayInternal.packageName = mContext.getPackageName();
+ } else {
+ if (!TextUtils.equals(
+ fabricatedOverlayInternal.packageName, mContext.getPackageName())) {
+ throw new IllegalArgumentException("Unknown package name in transaction");
+ }
+ }
+
+ registerFabricatedOverlay(fabricatedOverlayInternal);
+ } else if (request.type == TYPE_UNREGISTER_FABRICATED) {
+ final OverlayIdentifier overlayIdentifier = Objects.requireNonNull(request.overlay);
+ unregisterFabricatedOverlay(overlayIdentifier.getOverlayName());
+ } else {
+ throw new IllegalArgumentException("Unknown request in transaction " + request);
+ }
+ }
+ }
+
+ /**
* Get the list of overlays information for the target package name.
*
* @param targetPackage the target package name
diff --git a/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
index 8a9ab5b7a902..40d0bef2fb0f 100644
--- a/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
+++ b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
@@ -31,7 +31,9 @@ import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.om.FabricatedOverlay;
import android.content.om.OverlayInfo;
+import android.content.om.OverlayManagerTransaction;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
@@ -451,6 +453,40 @@ public class OverlayManagerImplTest {
}
@Test
+ public void commit_withNullTransaction_shouldFail() {
+ assertThrows(NullPointerException.class, () -> mOverlayManagerImpl.commit(null));
+ }
+
+ @Test
+ public void commitRegisterOverlay_fromOtherBuilder_shouldWork()
+ throws PackageManager.NameNotFoundException, IOException {
+ FabricatedOverlay overlay =
+ new FabricatedOverlay.Builder(
+ mContext.getPackageName(), mOverlayName, mContext.getPackageName())
+ .setTargetOverlayable(SIGNATURE_OVERLAYABLE)
+ .setResourceValue(
+ TARGET_COLOR_RES, TypedValue.TYPE_INT_COLOR_ARGB8, Color.WHITE)
+ .build();
+ OverlayManagerTransaction transaction =
+ new OverlayManagerTransaction.Builder().registerFabricatedOverlay(overlay).build();
+
+ mOverlayManagerImpl.commit(transaction);
+
+ final List<OverlayInfo> overlayInfos =
+ mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName());
+ final int firstNumberOfOverlays = overlayInfos.size();
+ expect.that(firstNumberOfOverlays).isEqualTo(1);
+ final OverlayInfo overlayInfo = overlayInfos.get(0);
+ expect.that(overlayInfo).isNotNull();
+ Truth.assertThat(expect.hasFailures()).isFalse();
+ expect.that(overlayInfo.isFabricated()).isTrue();
+ expect.that(overlayInfo.getOverlayName()).isEqualTo(mOverlayName);
+ expect.that(overlayInfo.getPackageName()).isEqualTo(mContext.getPackageName());
+ expect.that(overlayInfo.getTargetPackageName()).isEqualTo(mContext.getPackageName());
+ expect.that(overlayInfo.getUserId()).isEqualTo(mContext.getUserId());
+ }
+
+ @Test
public void newOverlayManagerImpl_forOtherUser_shouldFail() {
Context fakeContext =
new ContextWrapper(mContext) {