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

Commit c89bd75a authored by Winson's avatar Winson
Browse files

Combine v1 and v2 DomainVerficationProxies

In case both v1 and v2 are on the device, have a delegate that supports
sending requests to both receivers. The verification agent will then
decide which API to use.

This allows deferred migration to the v2 APIs. Note that the old user
state API is still non-functional, even for a v1 verification agent.

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

Bug: 170321181

Test: atest DomainVerificationProxyTest

Change-Id: I951fec5690c1f0d848d86c8859c3e9a171fca887
parent 346d2769
Loading
Loading
Loading
Loading
+13 −17
Original line number Diff line number Diff line
@@ -7073,26 +7073,22 @@ 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
                ComponentName intentFilterVerifierComponent =
                        getIntentFilterVerifierComponentNameLPr();
                ComponentName domainVerificationAgent =
                        getDomainVerificationAgentComponentNameLPr();
                DomainVerificationProxy domainVerificationProxy = DomainVerificationProxy.makeProxy(
                        intentFilterVerifierComponent, domainVerificationAgent, mContext,
                        mDomainVerificationManager, mDomainVerificationManager.getCollector(),
                        mDomainVerificationConnection);
                mDomainVerificationManager.setProxy(domainVerificationProxy);
                if (intentFilterVerifierComponent != null) {
                        mDomainVerificationManager.setProxy(
                                new DomainVerificationProxyV1(mContext, mDomainVerificationManager,
                                        mDomainVerificationManager.getCollector(),
                                        mDomainVerificationConnection,
                                        intentFilterVerifierComponent));
                    mIntentFilterVerificationManager.setVerifierComponent(
                            intentFilterVerifierComponent);
                }
                }
                mServicesExtensionPackageName = getRequiredServicesExtensionPackageLPr();
                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
+3 −2
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 * 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.
@@ -31,5 +31,6 @@ import com.android.server.pm.domain.verify.proxy.DomainVerificationProxy;
public final class DomainVerificationMessageCodes {

    public static final int SEND_REQUEST = 1;
    public static final int LEGACY_ON_INTENT_FILTER_VERIFIED = 2;
    public static final int LEGACY_SEND_REQUEST = 2;
    public static final int LEGACY_ON_INTENT_FILTER_VERIFIED = 3;
}
+0 −2
Original line number Diff line number Diff line
@@ -1170,8 +1170,6 @@ public class DomainVerificationService extends SystemService
         */
        void schedule(int code, @Nullable Object object);

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

        /**
         * This can only be called when the internal {@link #mLock} is held. Otherwise it's possible
         * to deadlock with {@link PackageManagerService}.
+52 −0
Original line number Diff line number Diff line
@@ -19,15 +19,67 @@ package com.android.server.pm.domain.verify.proxy;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.util.Slog;

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

import java.util.Objects;
import java.util.Set;

// TODO(b/170321181): Combine the proxy versions for supporting v1 and v2 at once
public interface DomainVerificationProxy {

    String TAG = "DomainVerificationProxy";

    boolean DEBUG_PROXIES = false;

    static <ConnectionType extends DomainVerificationProxyV1.Connection
            & DomainVerificationProxyV2.Connection> DomainVerificationProxy makeProxy(
            @Nullable ComponentName componentV1, @Nullable ComponentName componentV2,
            @NonNull Context context, @NonNull DomainVerificationManagerInternal manager,
            @NonNull DomainVerificationCollector collector, @NonNull ConnectionType connection) {
        if (DEBUG_PROXIES) {
            Slog.d(TAG, "Intent filter verification agent: " + componentV1);
            Slog.d(TAG, "Domain verification agent: " + componentV2);
        }

        if (componentV2 != null && componentV1 != null
                && !Objects.equals(componentV2.getPackageName(), componentV1.getPackageName())) {
            // Only allow a legacy verifier if it's in the same package as the v2 verifier
            componentV1 = null;
        }

        DomainVerificationProxy proxyV1 = null;
        DomainVerificationProxy proxyV2 = null;

        if (componentV1 != null) {
            proxyV1 = new DomainVerificationProxyV1(context, manager, collector, connection,
                    componentV1);
        }

        if (componentV2 != null) {
            proxyV2 = new DomainVerificationProxyV2(context, connection, componentV2);
        }

        if (proxyV1 != null && proxyV2 != null) {
            return new DomainVerificationProxyCombined(proxyV1, proxyV2);
        }

        if (proxyV1 != null) {
            return proxyV1;
        }

        if (proxyV2 != null) {
            return proxyV2;
        }

        return new DomainVerificationProxyUnavailable();
    }

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

+54 −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.proxy;

import android.annotation.NonNull;

import java.util.Set;

class DomainVerificationProxyCombined implements DomainVerificationProxy {

    @NonNull
    private final DomainVerificationProxy mProxyV1;
    @NonNull
    private final DomainVerificationProxy mProxyV2;

    DomainVerificationProxyCombined(@NonNull DomainVerificationProxy proxyV1,
            @NonNull DomainVerificationProxy proxyV2) {
        mProxyV1 = proxyV1;
        mProxyV2 = proxyV2;
    }

    @Override
    public void sendBroadcastForPackages(@NonNull Set<String> packageNames) {
        mProxyV2.sendBroadcastForPackages(packageNames);
        mProxyV1.sendBroadcastForPackages(packageNames);
    }

    @Override
    public boolean runMessage(int messageCode, Object object) {
        // Both proxies must run, so cannot use a direct ||, which may skip the right hand side
        boolean resultV2 = mProxyV2.runMessage(messageCode, object);
        boolean resultV1 = mProxyV1.runMessage(messageCode, object);
        return resultV2 || resultV1;
    }

    @Override
    public boolean isCallerVerifier(int callingUid) {
        return mProxyV2.isCallerVerifier(callingUid) || mProxyV1.isCallerVerifier(callingUid);
    }
}
Loading