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

Commit 768289ae authored by Reema Bajwa's avatar Reema Bajwa Committed by Android (Google) Code Review
Browse files

Merge "Valiate credential provider setup on package" into main

parents e9fca341 cfb47297
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ public final class CredentialProviderInfoFactory {
            int userId,
            boolean isSystemProvider,
            boolean isPrimary)
            throws PackageManager.NameNotFoundException {
            throws PackageManager.NameNotFoundException, SecurityException, NullPointerException {
        return create(
                context,
                getServiceInfoOrThrow(serviceComponent, userId),
@@ -117,7 +117,7 @@ public final class CredentialProviderInfoFactory {
            boolean disableSystemAppVerificationForTests,
            boolean isEnabled,
            boolean isPrimary)
            throws SecurityException {
            throws SecurityException, NullPointerException {
        verifyProviderPermission(serviceInfo);
        if (isSystemProvider) {
            if (!isValidSystemProvider(
@@ -199,7 +199,7 @@ public final class CredentialProviderInfoFactory {
    }

    private static CredentialProviderInfo.Builder populateMetadata(
            @NonNull Context context, ServiceInfo serviceInfo) {
            @NonNull Context context, ServiceInfo serviceInfo) throws NullPointerException {
        requireNonNull(context, "context must not be null");
        final PackageManager pm = context.getPackageManager();
        CredentialProviderInfo.Builder builder = new CredentialProviderInfo.Builder(serviceInfo);
+62 −7
Original line number Diff line number Diff line
@@ -21,11 +21,16 @@ import static com.android.server.credentials.CredentialManagerService.getPrimary
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.credentials.CredentialManager;
import android.credentials.CredentialProviderInfo;
import android.credentials.flags.Flags;
import android.service.credentials.CredentialProviderInfoFactory;
import android.service.credentials.CredentialProviderService;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
@@ -78,14 +83,16 @@ public final class CredentialManagerServiceImpl extends
        mInfo = providerInfo;
    }

    @Override // from PerUserSystemService when a new setting based service is to be created
    @Override // from PerUserSystemService when a new service is to be created
    @GuardedBy("mLock")
    protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent)
            throws PackageManager.NameNotFoundException {
            throws PackageManager.NameNotFoundException, SecurityException, NullPointerException {
        boolean isSystemProvider = false;
        if (mInfo != null) {
            Slog.i(TAG, "newServiceInfoLocked, mInfo not null : "
                    + mInfo.getServiceInfo().getComponentName().flattenToString() + " , "
                    + serviceComponent.flattenToString());
            isSystemProvider = mInfo.isSystemProvider();
        } else {
            Slog.i(TAG, "newServiceInfoLocked, mInfo null, "
                    + serviceComponent.flattenToString());
@@ -94,7 +101,7 @@ public final class CredentialManagerServiceImpl extends
                getPrimaryProvidersForUserId(mMaster.getContext(), mUserId);
        mInfo = CredentialProviderInfoFactory.create(
                getContext(), serviceComponent,
                mUserId, /*isSystemProvider=*/false,
                mUserId, isSystemProvider,
                primaryProviders.contains(serviceComponent));
        return mInfo.getServiceInfo();
    }
@@ -148,10 +155,22 @@ public final class CredentialManagerServiceImpl extends
     * @param packageName package of the app being updated.
     */
    @GuardedBy("mLock")
    @SuppressWarnings("GuardedBy") // ErrorProne requires this.mMaster.mLock which is the case
    // because this method is called by this.mMaster anyway
    protected void handlePackageUpdateLocked(@NonNull String packageName) {
        if (mInfo != null && mInfo.getServiceInfo() != null
                && mInfo.getServiceInfo().getComponentName()
                .getPackageName().equals(packageName)) {
            if (Flags.packageUpdateFixEnabled()) {
                try {
                    updateCredentialProviderInfo(mInfo.getServiceInfo().getComponentName(),
                            mInfo.isSystemProvider());
                } catch (SecurityException | PackageManager.NameNotFoundException
                         | NullPointerException e) {
                    Slog.w(TAG, "Unable to update provider, must be removed: " + e.getMessage());
                    mMaster.handleServiceRemovedMultiModeLocked(mInfo.getComponentName(), mUserId);
                }
            } else {
                try {
                    newServiceInfoLocked(mInfo.getServiceInfo().getComponentName());
                } catch (PackageManager.NameNotFoundException e) {
@@ -160,3 +179,39 @@ public final class CredentialManagerServiceImpl extends
            }
        }
    }

    @GuardedBy("mLock")
    private void updateCredentialProviderInfo(ComponentName componentName, boolean isSystemProvider)
            throws SecurityException, PackageManager.NameNotFoundException {
        Slog.d(TAG, "Updating credential provider: " + componentName.flattenToString());
        if (!isValidCredentialProviderInfo(componentName, mUserId, isSystemProvider)) {
            throw new SecurityException("Service has not been set up correctly");
        }
        newServiceInfoLocked(componentName);
    }

    private boolean isValidCredentialProviderInfo(ComponentName componentName, int userId,
            boolean isSystemProvider) {
        Context context = getContext();
        if (context == null) {
            return false;
        }
        String serviceInterface = CredentialProviderService.SERVICE_INTERFACE;
        if (isSystemProvider) {
            serviceInterface = CredentialProviderService.SYSTEM_SERVICE_INTERFACE;
        }
        final List<ResolveInfo> resolveInfos =
                context.getPackageManager()
                        .queryIntentServicesAsUser(
                                new Intent(serviceInterface),
                                PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA),
                                userId);
        for (ResolveInfo resolveInfo : resolveInfos) {
            final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
            if (serviceInfo.getComponentName().equals(componentName)) {
                return true;
            }
        }
        return false;
    }
}