Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fbde6988 authored by Adam Lesinski's avatar Adam Lesinski Committed by Android (Google) Code Review
Browse files

Merge "OMS: handle overlay package upgrades, uninstalls"

parents f7a84a6c db0e34ed
Loading
Loading
Loading
Loading
+41 −15
Original line number Diff line number Diff line
@@ -16,10 +16,14 @@

package android.content.om;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Immutable overlay information about a package. All PackageInfos that
 * represent an overlay package will have a corresponding OverlayInfo.
@@ -27,6 +31,19 @@ import android.os.Parcelable;
 * @hide
 */
public final class OverlayInfo implements Parcelable {

    @IntDef(prefix = "STATE_", value = {
            STATE_UNKNOWN,
            STATE_MISSING_TARGET,
            STATE_NO_IDMAP,
            STATE_DISABLED,
            STATE_ENABLED,
            STATE_TARGET_UPGRADING,
            STATE_OVERLAY_UPGRADING,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface State {}

    /**
     * An internal state used as the initial state of an overlay. OverlayInfo
     * objects exposed outside the {@link
@@ -60,6 +77,18 @@ public final class OverlayInfo implements Parcelable {
     */
    public static final int STATE_ENABLED = 3;

    /**
     * The target package is currently being upgraded; the state will change
     * once the package installation has finished.
     */
    public static final int STATE_TARGET_UPGRADING = 4;

    /**
     * The overlay package is currently being upgraded; the state will change
     * once the package installation has finished.
     */
    public static final int STATE_OVERLAY_UPGRADING = 5;

    /**
     * Package name of the overlay package
     */
@@ -77,13 +106,8 @@ public final class OverlayInfo implements Parcelable {

    /**
     * The state of this OverlayInfo as defined by the STATE_* constants in this class.
     *
     * @see #STATE_MISSING_TARGET
     * @see #STATE_NO_IDMAP
     * @see #STATE_DISABLED
     * @see #STATE_ENABLED
     */
    public final int state;
    public final @State int state;

    /**
     * User handle for which this overlay applies
@@ -96,13 +120,13 @@ public final class OverlayInfo implements Parcelable {
     * @param source the source OverlayInfo to base the new instance on
     * @param state the new state for the source OverlayInfo
     */
    public OverlayInfo(@NonNull OverlayInfo source, int state) {
    public OverlayInfo(@NonNull OverlayInfo source, @State int state) {
        this(source.packageName, source.targetPackageName, source.baseCodePath, state,
                source.userId);
    }

    public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName,
            @NonNull String baseCodePath, int state, int userId) {
            @NonNull String baseCodePath, @State int state, int userId) {
        this.packageName = packageName;
        this.targetPackageName = targetPackageName;
        this.baseCodePath = baseCodePath;
@@ -136,6 +160,8 @@ public final class OverlayInfo implements Parcelable {
            case STATE_NO_IDMAP:
            case STATE_DISABLED:
            case STATE_ENABLED:
            case STATE_TARGET_UPGRADING:
            case STATE_OVERLAY_UPGRADING:
                break;
            default:
                throw new IllegalArgumentException("State " + state + " is not a valid state");
@@ -156,7 +182,8 @@ public final class OverlayInfo implements Parcelable {
        dest.writeInt(userId);
    }

    public static final Parcelable.Creator<OverlayInfo> CREATOR = new Parcelable.Creator<OverlayInfo>() {
    public static final Parcelable.Creator<OverlayInfo> CREATOR =
            new Parcelable.Creator<OverlayInfo>() {
        @Override
        public OverlayInfo createFromParcel(Parcel source) {
            return new OverlayInfo(source);
@@ -189,14 +216,9 @@ public final class OverlayInfo implements Parcelable {
     * Translate a state to a human readable string. Only intended for
     * debugging purposes.
     *
     * @see #STATE_MISSING_TARGET
     * @see #STATE_NO_IDMAP
     * @see #STATE_DISABLED
     * @see #STATE_ENABLED
     *
     * @return a human readable String representing the state.
     */
    public static String stateToString(int state) {
    public static String stateToString(@State int state) {
        switch (state) {
            case STATE_UNKNOWN:
                return "STATE_UNKNOWN";
@@ -208,6 +230,10 @@ public final class OverlayInfo implements Parcelable {
                return "STATE_DISABLED";
            case STATE_ENABLED:
                return "STATE_ENABLED";
            case STATE_TARGET_UPGRADING:
                return "STATE_TARGET_UPGRADING";
            case STATE_OVERLAY_UPGRADING:
                return "STATE_OVERLAY_UPGRADING";
            default:
                return "<unknown state>";
        }
+5 −1
Original line number Diff line number Diff line
@@ -24,7 +24,11 @@ LOCAL_TARGET_REQUIRED_MODULES := \
    OverlayHostTests_BadSignatureOverlay \
    OverlayHostTests_PlatformSignatureStaticOverlay \
    OverlayHostTests_PlatformSignatureOverlay \
    OverlayHostTests_PlatformSignatureOverlayV2
    OverlayHostTests_UpdateOverlay \
    OverlayHostTests_FrameworkOverlayV1 \
    OverlayHostTests_FrameworkOverlayV2 \
    OverlayHostTests_AppOverlayV1 \
    OverlayHostTests_AppOverlayV2
include $(BUILD_HOST_JAVA_LIBRARY)

# Include to build test-apps.
+5 −0
Original line number Diff line number Diff line
@@ -18,6 +18,11 @@
    <option name="test-tag" value="OverlayHostTests" />
    <option name="test-suite-tag" value="apct" />

    <!-- Install the device tests that will be used to verify things on device. -->
    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
        <option name="test-file-name" value="OverlayHostTests_UpdateOverlay.apk" />
    </target_preparer>

    <test class="com.android.tradefed.testtype.HostTest">
        <option name="class" value="com.android.server.om.hosttest.InstallOverlayTests" />
    </test>
+86 −16
Original line number Diff line number Diff line
@@ -23,14 +23,48 @@ import static org.junit.Assert.fail;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(DeviceJUnit4ClassRunner.class)
public class InstallOverlayTests extends BaseHostJUnit4Test {

    private static final String OVERLAY_PACKAGE_NAME =
    private static final String SIG_OVERLAY_PACKAGE_NAME =
            "com.android.server.om.hosttest.signature_overlay";
    private static final String APP_OVERLAY_PACKAGE_NAME =
            "com.android.server.om.hosttest.app_overlay";
    private static final String FRAMEWORK_OVERLAY_PACKAGE_NAME =
            "com.android.server.om.hosttest.framework_overlay";
    private static final String[] ALL_PACKAGES = new String[] {
            SIG_OVERLAY_PACKAGE_NAME, APP_OVERLAY_PACKAGE_NAME, FRAMEWORK_OVERLAY_PACKAGE_NAME
    };

    private static final String DEVICE_TEST_PKG =
            "com.android.server.om.hosttest.update_overlay_test";
    private static final String DEVICE_TEST_CLS = DEVICE_TEST_PKG + ".UpdateOverlayTest";

    @Before
    public void ensureNoOverlays() throws Exception {
        // Make sure we're starting with a clean slate.
        for (String pkg : ALL_PACKAGES) {
            assertFalse(pkg + " should not be installed", isPackageInstalled(pkg));
            assertFalse(pkg + " should not be registered with overlay manager service",
                    overlayManagerContainsPackage(pkg));
        }
    }

    /*
    For some reason, SuiteApkInstaller is *not* uninstalling overlays, even though #installPackage()
    claims it will auto-clean.
    TODO(b/72877546): Remove when auto-clean is fixed.
     */
    @After
    public void uninstallOverlays() throws Exception {
        for (String pkg : ALL_PACKAGES) {
            uninstallPackage(pkg);
        }
    }

    @Test
    public void failToInstallNonPlatformSignedOverlay() throws Exception {
@@ -40,7 +74,7 @@ public class InstallOverlayTests extends BaseHostJUnit4Test {
        } catch (Exception e) {
            // Expected.
        }
        assertFalse(overlayManagerContainsPackage());
        assertFalse(overlayManagerContainsPackage(SIG_OVERLAY_PACKAGE_NAME));
    }

    @Test
@@ -51,28 +85,64 @@ public class InstallOverlayTests extends BaseHostJUnit4Test {
        } catch (Exception e) {
            // Expected.
        }
        assertFalse(overlayManagerContainsPackage());
        assertFalse(overlayManagerContainsPackage(SIG_OVERLAY_PACKAGE_NAME));
    }

    @Test
    public void succeedToInstallPlatformSignedOverlay() throws Exception {
    public void installPlatformSignedOverlay() throws Exception {
        installPackage("OverlayHostTests_PlatformSignatureOverlay.apk");
        assertTrue(overlayManagerContainsPackage());
        assertTrue(overlayManagerContainsPackage(SIG_OVERLAY_PACKAGE_NAME));
    }

    @Test
    public void succeedToInstallPlatformSignedOverlayAndUpdate() throws Exception {
        installPackage("OverlayHostTests_PlatformSignatureOverlay.apk");
        assertTrue(overlayManagerContainsPackage());
        assertEquals("v1", getDevice().getAppPackageInfo(OVERLAY_PACKAGE_NAME).getVersionName());
    public void installPlatformSignedAppOverlayAndUpdate() throws Exception {
        assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS, "expectAppResource"));

        installPackage("OverlayHostTests_AppOverlayV1.apk");
        setOverlayEnabled(APP_OVERLAY_PACKAGE_NAME, true);
        assertTrue(overlayManagerContainsPackage(APP_OVERLAY_PACKAGE_NAME));
        assertEquals("v1", getDevice()
                .getAppPackageInfo(APP_OVERLAY_PACKAGE_NAME)
                .getVersionName());
        assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS,
                "expectAppOverlayV1Resource"));

        installPackage("OverlayHostTests_AppOverlayV2.apk");
        assertTrue(overlayManagerContainsPackage(APP_OVERLAY_PACKAGE_NAME));
        assertEquals("v2", getDevice()
                .getAppPackageInfo(APP_OVERLAY_PACKAGE_NAME)
                .getVersionName());
        assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS,
                "expectAppOverlayV2Resource"));
    }

    @Test
    public void installPlatformSignedFrameworkOverlayAndUpdate() throws Exception {
        assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS, "expectAppResource"));

        installPackage("OverlayHostTests_FrameworkOverlayV1.apk");
        setOverlayEnabled(FRAMEWORK_OVERLAY_PACKAGE_NAME, true);
        assertTrue(overlayManagerContainsPackage(FRAMEWORK_OVERLAY_PACKAGE_NAME));
        assertEquals("v1", getDevice()
                .getAppPackageInfo(FRAMEWORK_OVERLAY_PACKAGE_NAME)
                .getVersionName());
        assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS,
                "expectFrameworkOverlayV1Resource"));

        installPackage("OverlayHostTests_FrameworkOverlayV2.apk");
        assertTrue(overlayManagerContainsPackage(FRAMEWORK_OVERLAY_PACKAGE_NAME));
        assertEquals("v2", getDevice()
                .getAppPackageInfo(FRAMEWORK_OVERLAY_PACKAGE_NAME)
                .getVersionName());
        assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS,
                "expectFrameworkOverlayV2Resource"));
    }

        installPackage("OverlayHostTests_PlatformSignatureOverlayV2.apk");
        assertTrue(overlayManagerContainsPackage());
        assertEquals("v2", getDevice().getAppPackageInfo(OVERLAY_PACKAGE_NAME).getVersionName());
    private void setOverlayEnabled(String pkg, boolean enabled) throws Exception {
        getDevice().executeShellCommand("cmd overlay " + (enabled ? "enable " : "disable ") + pkg);
    }

    private boolean overlayManagerContainsPackage() throws Exception {
        return getDevice().executeShellCommand("cmd overlay list")
                .contains(OVERLAY_PACKAGE_NAME);
    private boolean overlayManagerContainsPackage(String pkg) throws Exception {
        return getDevice().executeShellCommand("cmd overlay list").contains(pkg);
    }
}
+0 −9
Original line number Diff line number Diff line
@@ -40,13 +40,4 @@ LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v1
LOCAL_AAPT_FLAGS += --version-code 1 --version-name v1
include $(BUILD_PACKAGE)

include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_PACKAGE_NAME := OverlayHostTests_PlatformSignatureOverlayV2
LOCAL_COMPATIBILITY_SUITE := general-tests
LOCAL_CERTIFICATE := platform
LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v2
LOCAL_AAPT_FLAGS += --version-code 2 --version-name v2
include $(BUILD_PACKAGE)

my_package_prefix :=
Loading