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

Commit c283f610 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "OMS: limit shell command output via optional args" into qt-dev

parents 615618f7 a465aec8
Loading
Loading
Loading
Loading
+25 −4
Original line number Diff line number Diff line
@@ -177,6 +177,23 @@ public class InstallOverlayTests extends BaseHostJUnit4Test {
                .contains(APP_OVERLAY_PACKAGE_NAME));
    }

    @Test
    public void testAdbShellOMSInterface() throws Exception {
        installPackage("OverlayHostTests_AppOverlayV1.apk");
        assertTrue(shell("cmd overlay list " + DEVICE_TEST_PKG).contains(DEVICE_TEST_PKG));
        assertTrue(shell("cmd overlay list " + DEVICE_TEST_PKG).contains(APP_OVERLAY_PACKAGE_NAME));
        assertEquals("[ ] " + APP_OVERLAY_PACKAGE_NAME,
                shell("cmd overlay list " + APP_OVERLAY_PACKAGE_NAME).trim());
        assertEquals("STATE_DISABLED",
                shell("cmd overlay dump state " + APP_OVERLAY_PACKAGE_NAME).trim());

        setOverlayEnabled(APP_OVERLAY_PACKAGE_NAME, true);
        assertEquals("[x] " + APP_OVERLAY_PACKAGE_NAME,
                shell("cmd overlay list " + APP_OVERLAY_PACKAGE_NAME).trim());
        assertEquals("STATE_ENABLED",
                shell("cmd overlay dump state " + APP_OVERLAY_PACKAGE_NAME).trim());
    }

    private void delay() {
        try {
            Thread.sleep(1000);
@@ -195,20 +212,24 @@ public class InstallOverlayTests extends BaseHostJUnit4Test {
    }

    private void installConvertExistingInstantPackageToFull(String pkg) throws Exception {
        getDevice().executeShellCommand("cmd package install-existing --wait --full " + pkg);
        shell("cmd package install-existing --wait --full " + pkg);
    }

    private void setPackageEnabled(String pkg, boolean enabled) throws Exception {
        getDevice().executeShellCommand("cmd package " + (enabled ? "enable " : "disable ") + pkg);
        shell("cmd package " + (enabled ? "enable " : "disable ") + pkg);
        delay();
    }

    private void setOverlayEnabled(String pkg, boolean enabled) throws Exception {
        getDevice().executeShellCommand("cmd overlay " + (enabled ? "enable " : "disable ") + pkg);
        shell("cmd overlay " + (enabled ? "enable " : "disable ") + pkg);
        delay();
    }

    private boolean overlayManagerContainsPackage(String pkg) throws Exception {
        return getDevice().executeShellCommand("cmd overlay list").contains(pkg);
        return shell("cmd overlay list").contains(pkg);
    }

    private String shell(final String cmd) throws Exception {
        return getDevice().executeShellCommand(cmd);
    }
}
+63 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.
 */

package com.android.server.om;

import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.os.UserHandle;

/**
 * State for dumps performed by the OverlayManagerService.
 */
public final class DumpState {
    @UserIdInt private int mUserId = UserHandle.USER_ALL;
    @Nullable private String mPackageName;
    @Nullable private String mField;
    private boolean mVerbose;

    /** Sets the user to dump the state for */
    public void setUserId(@UserIdInt int userId) {
        mUserId = userId;
    }
    @UserIdInt public int getUserId() {
        return mUserId;
    }

    /** Sets the name of the package to dump the state for */
    public void setPackageName(String packageName) {
        mPackageName = packageName;
    }
    @Nullable public String getPackageName() {
        return mPackageName;
    }

    /** Sets the name of the field to dump the state of */
    public void setField(String field) {
        mField = field;
    }
    @Nullable public String getField() {
        return mField;
    }

    /** Enables verbose dump state */
    public void setVerbose(boolean verbose) {
        mVerbose = verbose;
    }
    public boolean isVerbose() {
        return mVerbose;
    }
}
+71 −9
Original line number Diff line number Diff line
@@ -749,15 +749,77 @@ public final class OverlayManagerService extends SystemService {
        }

        @Override
        protected void dump(@NonNull final FileDescriptor fd, @NonNull final PrintWriter pw,
                @NonNull final String[] argv) {
            enforceDumpPermission("dump");
        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            final DumpState dumpState = new DumpState();
            dumpState.setUserId(UserHandle.getUserId(Binder.getCallingUid()));

            int opti = 0;
            while (opti < args.length) {
                final String opt = args[opti];
                if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
                    break;
                }
                opti++;

            final boolean verbose = argv.length > 0 && "--verbose".equals(argv[0]);
                if ("-h".equals(opt)) {
                    pw.println("dump [-h] [--verbose] [--user USER_ID] [[FIELD] PACKAGE]");
                    pw.println("  Print debugging information about the overlay manager.");
                    pw.println("  With optional parameter PACKAGE, limit output to the specified");
                    pw.println("  package. With optional parameter FIELD, limit output to");
                    pw.println("  the value of that SettingsItem field. Field names are");
                    pw.println("  case insensitive and out.println the m prefix can be omitted,");
                    pw.println("  so the following are equivalent: mState, mstate, State, state.");
                    return;
                } else if ("--user".equals(opt)) {
                    opti++;
                    if (opti >= args.length) {
                        pw.println("Error: user missing argument");
                        return;
                    }
                    try {
                        dumpState.setUserId(Integer.parseInt(args[opti]));
                    } catch (NumberFormatException e) {
                        pw.println("Error: user argument is not a number: " + args[opti]);
                        return;
                    }
                } else if ("--verbose".equals(opt)) {
                    dumpState.setVerbose(true);
                } else {
                    pw.println("Unknown argument: " + opt + "; use -h for help");
                }
            }
            if (opti < args.length) {
                final String arg = args[opti];
                opti++;
                switch (arg) {
                    case "packagename":
                    case "userid":
                    case "targetpackagename":
                    case "targetoverlayablename":
                    case "basecodepath":
                    case "state":
                    case "isenabled":
                    case "isstatic":
                    case "priority":
                    case "category":
                        dumpState.setField(arg);
                        break;
                    default:
                        dumpState.setPackageName(arg);
                        break;
                }
            }
            if (dumpState.getPackageName() == null && opti < args.length) {
                dumpState.setPackageName(args[opti]);
                opti++;
            }

            enforceDumpPermission("dump");
            synchronized (mLock) {
                mImpl.onDump(pw);
                mPackageManager.dump(pw, verbose);
                mImpl.dump(pw, dumpState);
                if (dumpState.getPackageName() == null) {
                    mPackageManager.dump(pw, dumpState);
                }
            }
        }

@@ -1046,10 +1108,10 @@ public final class OverlayManagerService extends SystemService {
        private static final String TAB1 = "    ";
        private static final String TAB2 = TAB1 + TAB1;

        public void dump(@NonNull final PrintWriter pw, final boolean verbose) {
        public void dump(@NonNull final PrintWriter pw, @NonNull DumpState dumpState) {
            pw.println("PackageInfo cache");

            if (!verbose) {
            if (!dumpState.isVerbose()) {
                int count = 0;
                final int n = mCache.size();
                for (int i = 0; i < n; i++) {
+5 −3
Original line number Diff line number Diff line
@@ -636,10 +636,12 @@ final class OverlayManagerServiceImpl {
        return true;
    }

    void onDump(@NonNull final PrintWriter pw) {
        mSettings.dump(pw);
    void dump(@NonNull final PrintWriter pw, @NonNull DumpState dumpState) {
        mSettings.dump(pw, dumpState);
        if (dumpState.getPackageName() == null) {
            pw.println("Default overlays: " + TextUtils.join(";", mDefaultOverlays));
        }
    }

    @NonNull String[] getDefaultOverlayPackages() {
        return mDefaultOverlays;
+69 −25
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static com.android.server.om.OverlayManagerService.TAG;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.om.OverlayInfo;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Slog;
import android.util.Xml;
@@ -288,19 +289,27 @@ final class OverlayManagerSettings {
        return true;
    }

    void dump(@NonNull final PrintWriter p) {
        final IndentingPrintWriter pw = new IndentingPrintWriter(p, "  ");
        pw.println("Settings");
        pw.increaseIndent();
    void dump(@NonNull final PrintWriter p, @NonNull DumpState dumpState) {
        // select items to display
        Stream<SettingsItem> items = mItems.stream();
        if (dumpState.getUserId() != UserHandle.USER_ALL) {
            items = items.filter(item -> item.mUserId == dumpState.getUserId());
        }
        if (dumpState.getPackageName() != null) {
            items = items.filter(item -> item.mPackageName.equals(dumpState.getPackageName()));
        }

        if (mItems.isEmpty()) {
            pw.println("<none>");
            return;
        // display items
        final IndentingPrintWriter pw = new IndentingPrintWriter(p, "  ");
        if (dumpState.getField() != null) {
            items.forEach(item -> dumpSettingsItemField(pw, item, dumpState.getField()));
        } else {
            items.forEach(item -> dumpSettingsItem(pw, item));
        }
    }

        final int n = mItems.size();
        for (int i = 0; i < n; i++) {
            final SettingsItem item = mItems.get(i);
    private void dumpSettingsItem(@NonNull final IndentingPrintWriter pw,
            @NonNull final SettingsItem item) {
        pw.println(item.mPackageName + ":" + item.getUserId() + " {");
        pw.increaseIndent();

@@ -318,6 +327,41 @@ final class OverlayManagerSettings {
        pw.decreaseIndent();
        pw.println("}");
    }

    private void dumpSettingsItemField(@NonNull final IndentingPrintWriter pw,
            @NonNull final SettingsItem item, @NonNull final String field) {
        switch (field) {
            case "packagename":
                pw.println(item.mPackageName);
                break;
            case "userid":
                pw.println(item.mUserId);
                break;
            case "targetpackagename":
                pw.println(item.mTargetPackageName);
                break;
            case "targetoverlayablename":
                pw.println(item.mTargetOverlayableName);
                break;
            case "basecodepath":
                pw.println(item.mBaseCodePath);
                break;
            case "state":
                pw.println(OverlayInfo.stateToString(item.mState));
                break;
            case "isenabled":
                pw.println(item.mIsEnabled);
                break;
            case "isstatic":
                pw.println(item.mIsStatic);
                break;
            case "priority":
                pw.println(item.mPriority);
                break;
            case "category":
                pw.println(item.mCategory);
                break;
        }
    }

    void restore(@NonNull final InputStream is) throws IOException, XmlPullParserException {
Loading