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

Commit fa302df9 authored by Winson's avatar Winson
Browse files

Add DomainVerificationShell and boot broadcast

Support for mutating internal state using pm shell commands.

Also wires up the boot broadcast now that the ability to verify all
unverified packages has been added.

Exempt-From-Owner-Approval: Already approved by owners on main branch

Bug: 163565712

Test: TODO

Change-Id: I809436c6b8ff04cdc68430303859d2d7f40d9557
parent e94d0cfd
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.UserHandle;
import android.util.AndroidException;
import android.util.ArrayMap;

import com.android.server.pm.domain.verify.models.DomainVerificationPkgState;

import java.util.List;
import java.util.Set;
+2 −2
Original line number Diff line number Diff line
@@ -23765,8 +23765,8 @@ public class PackageManagerService extends IPackageManager.Stub
    public void onShellCommand(FileDescriptor in, FileDescriptor out,
            FileDescriptor err, String[] args, ShellCallback callback,
            ResultReceiver resultReceiver) {
        (new PackageManagerShellCommand(this, mContext)).exec(
                this, in, out, err, args, callback, resultReceiver);
        (new PackageManagerShellCommand(this, mContext,mDomainVerificationManager.getShell()))
                .exec(this, in, out, err, args, callback, resultReceiver);
    }
    @SuppressWarnings("resource")
+14 −138
Original line number Diff line number Diff line
@@ -17,13 +17,9 @@
package com.android.server.pm;

import static android.content.pm.PackageInstaller.LOCATION_DATA_APP;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;

import android.accounts.IAccountManager;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
@@ -108,6 +104,7 @@ import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.pm.PackageManagerShellCommandDataLoader.Metadata;
import com.android.server.pm.domain.verify.DomainVerificationShell;
import com.android.server.pm.permission.LegacyPermissionManagerInternal;

import dalvik.system.DexFile;
@@ -149,6 +146,7 @@ class PackageManagerShellCommand extends ShellCommand {
    final LegacyPermissionManagerInternal mLegacyPermissionManager;
    final PermissionManager mPermissionManager;
    final Context mContext;
    final DomainVerificationShell mDomainVerificationShell;
    final private WeakHashMap<String, Resources> mResourceCache =
            new WeakHashMap<String, Resources>();
    int mTargetUser;
@@ -158,11 +156,13 @@ class PackageManagerShellCommand extends ShellCommand {

    private static final SecureRandom RANDOM = new SecureRandom();

    PackageManagerShellCommand(PackageManagerService service, Context context) {
    PackageManagerShellCommand(@NonNull PackageManagerService service,
            @NonNull Context context, @NonNull DomainVerificationShell domainVerificationShell) {
        mInterface = service;
        mLegacyPermissionManager = LocalServices.getService(LegacyPermissionManagerInternal.class);
        mPermissionManager = context.getSystemService(PermissionManager.class);
        mContext = context;
        mDomainVerificationShell = domainVerificationShell;
    }

    @Override
@@ -267,10 +267,6 @@ class PackageManagerShellCommand extends ShellCommand {
                    return runGetPrivappDenyPermissions();
                case "get-oem-permissions":
                    return runGetOemPermissions();
                case "set-app-link":
                    return runSetAppLink();
                case "get-app-link":
                    return runGetAppLink();
                case "trim-caches":
                    return runTrimCaches();
                case "create-user":
@@ -309,6 +305,12 @@ class PackageManagerShellCommand extends ShellCommand {
                case "bypass-staged-installer-check":
                    return runBypassStagedInstallerCheck();
                default: {
                    Boolean domainVerificationResult =
                            mDomainVerificationShell.runCommand(this, cmd);
                    if (domainVerificationResult != null) {
                        return domainVerificationResult ? 0 : 1;
                    }

                    String nextArg = getNextArg();
                    if (nextArg == null) {
                        if (cmd.equalsIgnoreCase("-l")) {
@@ -2427,134 +2429,6 @@ class PackageManagerShellCommand extends ShellCommand {
        return 0;
    }

    private String linkStateToString(int state) {
        switch (state) {
            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined";
            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask";
            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always";
            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never";
            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask";
        }
        return "Unknown link state: " + state;
    }

    // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined}
    private int runSetAppLink() throws RemoteException {
        int userId = UserHandle.USER_SYSTEM;

        String opt;
        while ((opt = getNextOption()) != null) {
            if (opt.equals("--user")) {
                userId = UserHandle.parseUserArg(getNextArgRequired());
            } else {
                getErrPrintWriter().println("Error: unknown option: " + opt);
                return 1;
            }
        }

        // Package name to act on; required
        final String pkg = getNextArg();
        if (pkg == null) {
            getErrPrintWriter().println("Error: no package specified.");
            return 1;
        }

        // State to apply; {always|ask|never|undefined}, required
        final String modeString = getNextArg();
        if (modeString == null) {
            getErrPrintWriter().println("Error: no app link state specified.");
            return 1;
        }

        final int newMode;
        switch (modeString.toLowerCase()) {
            case "undefined":
                newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
                break;

            case "always":
                newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
                break;

            case "ask":
                newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
                break;

            case "always-ask":
                newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
                break;

            case "never":
                newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
                break;

            default:
                getErrPrintWriter().println("Error: unknown app link state '" + modeString + "'");
                return 1;
        }

        final int translatedUserId =
                translateUserId(userId, UserHandle.USER_NULL, "runSetAppLink");
        final PackageInfo info = mInterface.getPackageInfo(pkg, 0, translatedUserId);
        if (info == null) {
            getErrPrintWriter().println("Error: package " + pkg + " not found.");
            return 1;
        }

        if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
            getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
            return 1;
        }

        if (!mInterface.updateIntentVerificationStatus(pkg, newMode, translatedUserId)) {
            getErrPrintWriter().println("Error: unable to update app link status for " + pkg);
            return 1;
        }

        return 0;
    }

    // pm get-app-link [--user USER_ID] PACKAGE
    private int runGetAppLink() throws RemoteException {
        int userId = UserHandle.USER_SYSTEM;

        String opt;
        while ((opt = getNextOption()) != null) {
            if (opt.equals("--user")) {
                userId = UserHandle.parseUserArg(getNextArgRequired());
            } else {
                getErrPrintWriter().println("Error: unknown option: " + opt);
                return 1;
            }
        }

        // Package name to act on; required
        final String pkg = getNextArg();
        if (pkg == null) {
            getErrPrintWriter().println("Error: no package specified.");
            return 1;
        }

        final int translatedUserId =
                translateUserId(userId, UserHandle.USER_NULL, "runGetAppLink");
        final PackageInfo info = mInterface.getPackageInfo(pkg, 0, translatedUserId);
        if (info == null) {
            getErrPrintWriter().println("Error: package " + pkg + " not found.");
            return 1;
        }

        if ((info.applicationInfo.privateFlags
                & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
            getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
            return 1;
        }

        getOutPrintWriter().println(linkStateToString(
                mInterface.getIntentVerificationStatus(pkg, translatedUserId)));

        return 0;
    }

    private int runTrimCaches() throws RemoteException {
        String size = getNextArg();
        if (size == null) {
@@ -3915,6 +3789,8 @@ class PackageManagerShellCommand extends ShellCommand {
        pw.println("      --enable: turn on debug logging (default)");
        pw.println("      --disable: turn off debug logging");
        pw.println("");
        mDomainVerificationShell.printHelp(pw);
        pw.println("");
        Intent.printIntentArgsHelp(pw , "");
    }

+2 −1
Original line number Diff line number Diff line
@@ -110,8 +110,9 @@ public class DomainVerificationDebug {
                        PackageUtils.computeSignaturesSha256Digests(
                                pkg.getSigningDetails().signatures));

                writer.println(pkgState.getPackageName() + " " + pkgState.getId() + ":");
                writer.println(pkgState.getPackageName() + ":");
                writer.increaseIndent();
                writer.println("ID: " + pkgState.getId());
                writer.println("Signatures: " + signaturesDigest);
                writer.decreaseIndent();
                printedHeader = true;
+3 −0
Original line number Diff line number Diff line
@@ -154,4 +154,7 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan
     */
    void printState(@NonNull IndentingPrintWriter writer, @Nullable String packageName,
            @Nullable @UserIdInt Integer userId) throws NameNotFoundException;

    @NonNull
    DomainVerificationShell getShell();
}
Loading