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

Commit 5429dfc3 authored by Winson's avatar Winson
Browse files

Add DomainVerificationProxyV2 for new APIs

Implements the request broadcast to the new domain verification agent.

The DomainVerificationService delegates through the
PackageManagerService Handler, to mirror what happened with v1. A
message code is reserved for the domain verification feature and all
feature specific messages are wrapped in that code to isolate them
from other PackageManagerService messages.

Prepares interface for backporting the broadcast to the v1 broadcast,
but that will be done in a future change.

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

Bug: 163565712

Test: TBD in later change when proxies are combined

Change-Id: If77f0c7facebedadfd00b82120949ed4720e9b58
parent 96694aa7
Loading
Loading
Loading
Loading
+80 −3
Original line number Diff line number Diff line
@@ -379,6 +379,8 @@ import com.android.server.pm.dex.PackageDexUsage;
import com.android.server.pm.dex.ViewCompiler;
import com.android.server.pm.domain.verify.DomainVerificationManagerInternal;
import com.android.server.pm.domain.verify.DomainVerificationService;
import com.android.server.pm.domain.verify.proxy.DomainVerificationProxy;
import com.android.server.pm.domain.verify.proxy.DomainVerificationProxyV2;
import com.android.server.pm.intent.verify.legacy.IntentFilterVerificationManager;
import com.android.server.pm.intent.verify.legacy.IntentFilterVerificationParams;
import com.android.server.pm.intent.verify.legacy.IntentVerifierProxy;
@@ -1606,6 +1608,7 @@ public class PackageManagerService extends IPackageManager.Stub
    static final int DEFERRED_NO_KILL_INSTALL_OBSERVER = 24;
    static final int INTEGRITY_VERIFICATION_COMPLETE = 25;
    static final int CHECK_PENDING_INTEGRITY_VERIFICATION = 26;
    static final int DOMAIN_VERIFICATION = 27;
    static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
    static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
@@ -1821,7 +1824,7 @@ public class PackageManagerService extends IPackageManager.Stub
            new DomainVerificationConnection();
    private class DomainVerificationConnection implements
            DomainVerificationService.Connection {
            DomainVerificationService.Connection, DomainVerificationProxy.Connection {
        @Override
        public void scheduleWriteSettings() {
@@ -1829,6 +1832,30 @@ public class PackageManagerService extends IPackageManager.Stub
                PackageManagerService.this.scheduleWriteSettingsLocked();
            }
        }
        @Override
        public void schedule(int code, @Nullable Object object) {
            Message message = mHandler.obtainMessage(DOMAIN_VERIFICATION);
            message.arg1 = code;
            message.obj = object;
            mHandler.sendMessage(message);
        }
        @Override
        public long getPowerSaveTempWhitelistAppDuration() {
            return PackageManagerService.this.getVerificationTimeout();
        }
        @Override
        public DeviceIdleInternal getDeviceIdleInternal() {
            return mInjector.getLocalService(DeviceIdleInternal.class);
        }
        @Override
        public boolean isCallerPackage(int callingUid, @NonNull String packageName) {
            final int callingUserId = UserHandle.getUserId(callingUid);
            return callingUid == getPackageUid(packageName, 0, callingUserId);
        }
    }
    /**
@@ -5301,6 +5328,12 @@ public class PackageManagerService extends IPackageManager.Stub
                    }
                    break;
                }
                case DOMAIN_VERIFICATION: {
                    int messageCode = msg.arg1;
                    Object object = msg.obj;
                    mDomainVerificationManager.runMessage(messageCode, object);
                    break;
                }
            }
        }
    }
@@ -6946,8 +6979,18 @@ public class PackageManagerService extends IPackageManager.Stub
                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
                mRequiredInstallerPackage = getRequiredInstallerLPr();
                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
                ComponentName domainVerificationAgent =
                        getDomainVerificationAgentComponentNameLPr();
                if (domainVerificationAgent != null) {
                    mDomainVerificationManager.setProxy(
                            new DomainVerificationProxyV2(mContext, mDomainVerificationConnection,
                                    domainVerificationAgent));
                } else {
                    // TODO(b/159952358): DomainVerificationProxyV1
                    mIntentFilterVerificationManager.setVerifierComponent(
                            getIntentFilterVerifierComponentNameLPr());
                }
                mServicesExtensionPackageName = getRequiredServicesExtensionPackageLPr();
                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
@@ -7490,6 +7533,40 @@ public class PackageManagerService extends IPackageManager.Stub
        return null;
    }
    @Nullable
    private ComponentName getDomainVerificationAgentComponentNameLPr() {
        Intent intent = new Intent(Intent.ACTION_DOMAINS_NEED_VERIFICATION);
        List<ResolveInfo> matches = queryIntentReceiversInternal(intent, null,
                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
        ResolveInfo best = null;
        final int N = matches.size();
        for (int i = 0; i < N; i++) {
            final ResolveInfo cur = matches.get(i);
            final String packageName = cur.getComponentInfo().packageName;
            if (checkPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT,
                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
                Slog.w(TAG, "Domain verification agent found but does not hold permission: "
                        + packageName);
                continue;
            }
            if (best == null || cur.priority > best.priority) {
                if (cur.getComponentInfo().enabled) {
                    best = cur;
                } else {
                    Slog.w(TAG, "Domain verification agent found but not enabled");
                }
            }
        }
        if (best != null) {
            return best.getComponentInfo().getComponentName();
        }
        Slog.w(TAG, "Domain verification agent not found");
        return null;
    }
    @Override
    public @Nullable ComponentName getInstantAppResolverComponent() {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+13 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.util.TypedXmlSerializer;

import com.android.server.pm.PackageSetting;
import com.android.server.pm.domain.verify.models.DomainVerificationPkgState;
import com.android.server.pm.domain.verify.proxy.DomainVerificationProxy;

import org.xmlpull.v1.XmlPullParserException;

@@ -41,6 +42,18 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan
    @NonNull
    UUID generateNewId();

    /**
     * Update the proxy implementation that talks to the domain verification agent on device. The
     * default proxy is a stub that does nothing, and broadcast functionality will only work once a
     * real implementation is attached.
     */
    void setProxy(@NonNull DomainVerificationProxy proxy);

    /**
     * @see DomainVerificationProxy.Connection#runMessage(int, Object)
     */
    boolean runMessage(int messageCode, Object object);

    /**
     * Restores or creates internal state for the new package. This can either be from scanning a
     * package at boot, or a truly new installation on the device. It is expected that the {@link
+34 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.pm.domain.verify;

import android.os.Handler;

import com.android.server.pm.PackageManagerService;
import com.android.server.pm.domain.verify.proxy.DomainVerificationProxy;

/**
 * Codes that are sent through the {@link PackageManagerService} {@link Handler} and eventually
 * delegated to {@link DomainVerificationService} and {@link DomainVerificationProxy}.
 *
 * These codes are wrapped and thus exclusive to the domain verification APIs. They do not have be
 * distinct from any of the codes inside {@link PackageManagerService}.
 */
public final class DomainVerificationMessageCodes {

    public static final int SEND_REQUEST = 1;
}
+24 −1
Original line number Diff line number Diff line
@@ -45,11 +45,14 @@ import com.android.server.pm.PackageSetting;
import com.android.server.pm.domain.verify.models.DomainVerificationPkgState;
import com.android.server.pm.domain.verify.models.DomainVerificationStateMap;
import com.android.server.pm.domain.verify.models.DomainVerificationUserState;
import com.android.server.pm.domain.verify.proxy.DomainVerificationProxy;
import com.android.server.pm.domain.verify.proxy.DomainVerificationProxyUnavailable;
import com.android.server.pm.parsing.pkg.AndroidPackage;

import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.UUID;
@@ -89,6 +92,9 @@ public class DomainVerificationService extends SystemService
    @NonNull
    private final IDomainVerificationManager.Stub mStub = new DomainVerificationManagerStub(this);

    @NonNull
    private DomainVerificationProxy mProxy = new DomainVerificationProxyUnavailable();

    public DomainVerificationService(@NonNull Context context, @NonNull SystemConfig systemConfig,
            @NonNull PlatformCompat platformCompat, @NonNull Singleton<Connection> connection) {
        super(context);
@@ -103,6 +109,11 @@ public class DomainVerificationService extends SystemService
        publishBinderService(Context.DOMAIN_VERIFICATION_SERVICE, mStub);
    }

    @Override
    public void setProxy(@NonNull DomainVerificationProxy proxy) {
        mProxy = proxy;
    }

    @NonNull
    @Override
    public List<String> getValidVerificationPackageNames() {
@@ -417,8 +428,17 @@ public class DomainVerificationService extends SystemService
        mConnection.get().scheduleWriteSettings();
    }

    @Override
    public boolean runMessage(int messageCode, Object object) {
        return mProxy.runMessage(messageCode, object);
    }

    private void sendBroadcastForPackage(@NonNull String packageName) {
        // TODO(b/159952358): Implement proxy
        mProxy.sendBroadcastForPackages(Collections.singleton(packageName));
    }

    private boolean hasRealVerifier() {
        return !(mProxy instanceof DomainVerificationProxyUnavailable);
    }

    public interface Connection {
@@ -428,5 +448,8 @@ public class DomainVerificationService extends SystemService
         * {@link #writeSettings(TypedXmlSerializer)} should be invoked by the parent.
         */
        void scheduleWriteSettings();

        /** @see DomainVerificationProxy.Connection#schedule(int, java.lang.Object) */
        void schedule(int code, @Nullable Object object);
    }
}
+66 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.pm.domain.verify.proxy;

import android.annotation.NonNull;
import android.annotation.Nullable;

import com.android.server.DeviceIdleInternal;
import com.android.server.pm.domain.verify.DomainVerificationMessageCodes;

import java.util.Set;

public interface DomainVerificationProxy {

    default void sendBroadcastForPackages(@NonNull Set<String> packageNames) {
    }

    /**
     * Runs a message on the caller's Handler as a result of {@link Connection#schedule(int,
     * Object)}. Abstracts the actual scheduling/running from the manager class. This is also
     * necessary so that different what codes can be used depending on the verifier proxy on device,
     * to allow backporting v1. The backport proxy may schedule more or less messages than the v2
     * proxy.
     *
     * @param messageCode One of the values in {@link DomainVerificationMessageCodes}.
     * @param object      Arbitrary object that was originally included.
     */
    default boolean runMessage(int messageCode, Object object) {
        return false;
    }

    default boolean isCallerVerifier(int callingUid) {
        return false;
    }

    interface Connection {

        /**
         * Schedule something to be run later. The implementation is left up to the caller.
         *
         * @param code   One of the values in {@link DomainVerificationMessageCodes}.
         * @param object Arbitrary object to include with the message.
         */
        void schedule(int code, @Nullable Object object);

        long getPowerSaveTempWhitelistAppDuration();

        DeviceIdleInternal getDeviceIdleInternal();

        boolean isCallerPackage(int callingUid, @NonNull String packageName);
    }
}
Loading