diff options
| -rw-r--r-- | core/java/com/android/internal/content/om/OverlayManagerImpl.java | 54 | ||||
| -rw-r--r-- | core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java | 36 |
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) { |