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

Commit 7ec6c48c authored by Cosmin Băieș's avatar Cosmin Băieș Committed by Android (Google) Code Review
Browse files

Merge "Handle HSUM in OverlayManager shell commands" into main

parents 5d24ba07 02232b0c
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -44,8 +44,11 @@ public class InstallOverlayTests extends BaseHostJUnit4Test {
            "com.android.server.om.hosttest.update_overlay_test";
    private static final String DEVICE_TEST_CLS = DEVICE_TEST_PKG + ".UpdateOverlayTest";

    private int mCurrentUserid;

    @Before
    public void ensureNoOverlays() throws Exception {
        mCurrentUserid = getDevice().getCurrentUser();
        // Make sure we're starting with a clean slate.
        for (String pkg : ALL_PACKAGES) {
            assertFalse(pkg + " should not be installed", isPackageInstalled(pkg));
@@ -62,7 +65,7 @@ public class InstallOverlayTests extends BaseHostJUnit4Test {
    @After
    public void uninstallOverlays() throws Exception {
        for (String pkg : ALL_PACKAGES) {
            uninstallPackage(pkg);
            getDevice().uninstallPackageForUser(pkg, mCurrentUserid);
        }
    }

@@ -166,7 +169,7 @@ public class InstallOverlayTests extends BaseHostJUnit4Test {
        installPackage("OverlayHostTests_AppOverlayV1.apk");
        assertTrue(getDevice().executeShellCommand("cat /data/system/overlays.xml")
                .contains(APP_OVERLAY_PACKAGE_NAME));
        uninstallPackage(APP_OVERLAY_PACKAGE_NAME);
        getDevice().uninstallPackageForUser(APP_OVERLAY_PACKAGE_NAME, mCurrentUserid);
        delay();
        assertFalse(getDevice().executeShellCommand("cat /data/system/overlays.xml")
                .contains(APP_OVERLAY_PACKAGE_NAME));
@@ -200,12 +203,12 @@ public class InstallOverlayTests extends BaseHostJUnit4Test {
    }

    private void installPackage(String pkg) throws Exception {
        super.installPackage(pkg);
        super.installPackageAsUser(pkg, true /* grantPermission */, mCurrentUserid);
        delay();
    }

    private void installInstantPackage(String pkg) throws Exception {
        super.installPackage(pkg, "--instant");
        super.installPackageAsUser(pkg, true /* grantPermission */, mCurrentUserid, "--instant");
        delay();
    }

+19 −18
Original line number Diff line number Diff line
@@ -403,6 +403,20 @@ public final class OverlayManagerService extends SystemService {
        return userIds;
    }

    /**
     * Ensure that the caller has permission to interact with the given userId.
     * If the calling user is not the same as the provided user, the caller needs
     * to hold the INTERACT_ACROSS_USERS_FULL permission (or be system uid or
     * root).
     *
     * @param userId the user to interact with
     * @param message message for any SecurityException
     */
    static int handleIncomingUser(final int userId, @NonNull final String message) {
        return ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                Binder.getCallingUid(), userId, false, true, message, null);
    }

    private void handlePackageAdd(String packageName, Bundle extras, int userId) {
        final boolean replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false);
        if (replacing) {
@@ -1037,7 +1051,7 @@ public final class OverlayManagerService extends SystemService {
        @Override
        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            final DumpState dumpState = new DumpState();
            dumpState.setUserId(UserHandle.USER_ALL);
            int userId = UserHandle.USER_ALL;

            int opti = 0;
            while (opti < args.length) {
@@ -1064,9 +1078,7 @@ public final class OverlayManagerService extends SystemService {
                        return;
                    }
                    try {
                        final int userId = UserHandle.parseUserArg(args[opti]);
                        final int realUserId = handleIncomingUser(userId, "dump");
                        dumpState.setUserId(realUserId);
                        userId = UserHandle.parseUserArg(args[opti]);
                        opti++;
                    } catch (Exception e) {
                        pw.println("Error: " + e.getMessage());
@@ -1105,6 +1117,9 @@ public final class OverlayManagerService extends SystemService {
            }

            enforceDumpPermission("dump");
            final int realUserId = userId != UserHandle.USER_ALL
                    ? handleIncomingUser(userId, "dump") : userId;
            dumpState.setUserId(realUserId);
            synchronized (mLock) {
                mImpl.dump(pw, dumpState);
                if (dumpState.getPackageName() == null) {
@@ -1113,20 +1128,6 @@ public final class OverlayManagerService extends SystemService {
            }
        }

        /**
         * Ensure that the caller has permission to interact with the given userId.
         * If the calling user is not the same as the provided user, the caller needs
         * to hold the INTERACT_ACROSS_USERS_FULL permission (or be system uid or
         * root).
         *
         * @param userId the user to interact with
         * @param message message for any SecurityException
         */
        private int handleIncomingUser(final int userId, @NonNull final String message) {
            return ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                    Binder.getCallingUid(), userId, false, true, message, null);
        }

        /**
         * Enforce that the caller holds the DUMP permission (or is system or root).
         *
+1 −10
Original line number Diff line number Diff line
@@ -715,20 +715,11 @@ final class OverlayManagerServiceImpl {
    }

    void dump(@NonNull final PrintWriter pw, @NonNull DumpState dumpState) {
        Pair<OverlayIdentifier, String> overlayIdmap = null;
        if (dumpState.getPackageName() != null) {
            OverlayIdentifier id = new OverlayIdentifier(dumpState.getPackageName(),
                    dumpState.getOverlayName());
            OverlayInfo oi = mSettings.getNullableOverlayInfo(id, USER_SYSTEM);
            if (oi != null) {
                overlayIdmap = new Pair<>(id, oi.baseCodePath);
            }
        }

        // settings
        mSettings.dump(pw, dumpState);

        // idmap data
        final var overlayIdmap = mSettings.getIdentifierAndBaseCodePath(dumpState);
        if (dumpState.getField() == null) {
            Set<Pair<OverlayIdentifier, String>> allIdmaps = (overlayIdmap != null)
                    ? Set.of(overlayIdmap) : mSettings.getAllIdentifiersAndBaseCodePaths();
+25 −1
Original line number Diff line number Diff line
@@ -212,17 +212,41 @@ final class OverlayManagerSettings {
    }

    Set<String> getAllBaseCodePaths() {
        // Overlays installed for multiple users have the same code path, avoid duplicates with Set.
        final Set<String> paths = new ArraySet<>();
        mItems.forEach(item -> paths.add(item.mBaseCodePath));
        return paths;
    }

    Set<Pair<OverlayIdentifier, String>> getAllIdentifiersAndBaseCodePaths() {
        // Overlays installed for multiple users have the same code path, avoid duplicates with Set.
        final Set<Pair<OverlayIdentifier, String>> set = new ArraySet<>();
        mItems.forEach(item -> set.add(new Pair(item.mOverlay, item.mBaseCodePath)));
        mItems.forEach(item -> set.add(new Pair<>(item.mOverlay, item.mBaseCodePath)));
        return set;
    }

    @Nullable
    Pair<OverlayIdentifier, String> getIdentifierAndBaseCodePath(@NonNull DumpState dumpState) {
        if (dumpState.getPackageName() == null) {
            return null;
        }
        OverlayIdentifier id = new OverlayIdentifier(dumpState.getPackageName(),
                dumpState.getOverlayName());
        final int userId = dumpState.getUserId();
        for (int i = 0; i < mItems.size(); i++) {
            final var item = mItems.get(i);
            if (userId != UserHandle.USER_ALL && userId != item.mUserId) {
                continue;
            }
            if (!id.equals(item.mOverlay)) {
                continue;
            }
            // Overlays installed for multiple users have the same code path, return first found.
            return new Pair<>(id, item.mBaseCodePath);
        }
        return null;
    }

    @NonNull
    List<OverlayInfo> removeIf(@NonNull final Predicate<OverlayInfo> predicate, final int userId) {
        return removeIf(info -> (predicate.test(info) && info.userId == userId));
+10 −12
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.om;

import static com.android.internal.content.om.OverlayConfig.PARTITION_ORDER_FILE_PATH;
import static com.android.server.om.OverlayManagerService.handleIncomingUser;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -145,7 +146,7 @@ final class OverlayManagerShellCommand extends ShellCommand {
        out.println("    Load a package and print the value of a given resource");
        out.println("    applying the current configuration and enabled overlays.");
        out.println("    For a more fine-grained alternative, use 'idmap2 lookup'.");
        out.println("  fabricate [--user USER_ID] [--target-name OVERLAYABLE] --target PACKAGE");
        out.println("  fabricate [--target-name OVERLAYABLE] --target PACKAGE");
        out.println("            --name NAME [--file FILE] ");
        out.println("            PACKAGE:TYPE/NAME ENCODED-TYPE-ID|TYPE-NAME ENCODED-VALUE");
        out.println("    Create an overlay from a single resource. Caller must be root. Example:");
@@ -160,7 +161,7 @@ final class OverlayManagerShellCommand extends ShellCommand {
        final PrintWriter out = getOutPrintWriter();
        final PrintWriter err = getErrPrintWriter();

        int userId = UserHandle.USER_SYSTEM;
        int userId = UserHandle.USER_CURRENT;
        String opt;
        while ((opt = getNextOption()) != null) {
            switch (opt) {
@@ -234,7 +235,7 @@ final class OverlayManagerShellCommand extends ShellCommand {
    private int runEnableDisable(final boolean enable) throws RemoteException {
        final PrintWriter err = getErrPrintWriter();

        int userId = UserHandle.USER_SYSTEM;
        int userId = UserHandle.USER_CURRENT;
        String opt;
        while ((opt = getNextOption()) != null) {
            switch (opt) {
@@ -269,7 +270,6 @@ final class OverlayManagerShellCommand extends ShellCommand {
            return 1;
        }

        int userId = UserHandle.USER_SYSTEM;
        String targetPackage = "";
        String targetOverlayable = "";
        String name = "";
@@ -278,9 +278,6 @@ final class OverlayManagerShellCommand extends ShellCommand {
        String config = null;
        while ((opt = getNextOption()) != null) {
            switch (opt) {
                case "--user":
                    userId = UserHandle.parseUserArg(getNextArgRequired());
                    break;
                case "--target":
                    targetPackage = getNextArgRequired();
                    break;
@@ -442,7 +439,7 @@ final class OverlayManagerShellCommand extends ShellCommand {
    private int runEnableExclusive() throws RemoteException {
        final PrintWriter err = getErrPrintWriter();

        int userId = UserHandle.USER_SYSTEM;
        int userId = UserHandle.USER_CURRENT;
        boolean inCategory = false;
        String opt;
        while ((opt = getNextOption()) != null) {
@@ -469,7 +466,7 @@ final class OverlayManagerShellCommand extends ShellCommand {
    private int runSetPriority() throws RemoteException {
        final PrintWriter err = getErrPrintWriter();

        int userId = UserHandle.USER_SYSTEM;
        int userId = UserHandle.USER_CURRENT;
        String opt;
        while ((opt = getNextOption()) != null) {
            switch (opt) {
@@ -498,7 +495,7 @@ final class OverlayManagerShellCommand extends ShellCommand {
        final PrintWriter out = getOutPrintWriter();
        final PrintWriter err = getErrPrintWriter();

        int userId = UserHandle.USER_SYSTEM;
        int userId = UserHandle.USER_CURRENT;
        boolean verbose = false;
        String opt;
        while ((opt = getNextOption()) != null) {
@@ -525,15 +522,16 @@ final class OverlayManagerShellCommand extends ShellCommand {
            return 1;
        }

        final int realUserId = handleIncomingUser(userId, "runLookup");
        final Resources res;
        try {
            res = mContext
                .createContextAsUser(UserHandle.of(userId), /* flags */ 0)
                .createContextAsUser(UserHandle.of(realUserId), /* flags */ 0)
                .getPackageManager()
                .getResourcesForApplication(packageToLoad);
        } catch (PackageManager.NameNotFoundException e) {
            err.println(String.format("Error: failed to get resources for package %s for user %d",
                    packageToLoad, userId));
                    packageToLoad, realUserId));
            return 1;
        }
        final AssetManager assets = res.getAssets();