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

Commit 4c15b904 authored by Reema Bajwa's avatar Reema Bajwa
Browse files

Pass set allowed providers permission to UI

Test: local build & deploy + CTS tests
Bug: 274667625

Change-Id: Id152608626287269959b66666d83a157e1f2c982
parent aa8c33a1
Loading
Loading
Loading
Loading
+35 −3
Original line number Diff line number Diff line
@@ -74,13 +74,30 @@ public final class RequestInfo implements Parcelable {
    @NonNull
    private final String mAppPackageName;

    private final boolean mHasPermissionToOverrideDefault;

    /** Creates new {@code RequestInfo} for a create-credential flow. */
    @NonNull
    public static RequestInfo newCreateRequestInfo(
            @NonNull IBinder token, @NonNull CreateCredentialRequest createCredentialRequest,
            @NonNull String appPackageName) {
        return new RequestInfo(
                token, TYPE_CREATE, appPackageName, createCredentialRequest, null);
                token, TYPE_CREATE, appPackageName, createCredentialRequest, null,
                /*hasPermissionToOverrideDefault=*/ false);
    }

    /**
     * Creates new {@code RequestInfo} for a create-credential flow.
     *
     * @hide
     */
    @NonNull
    public static RequestInfo newCreateRequestInfo(
            @NonNull IBinder token, @NonNull CreateCredentialRequest createCredentialRequest,
            @NonNull String appPackageName, boolean hasPermissionToOverrideDefault) {
        return new RequestInfo(
                token, TYPE_CREATE, appPackageName, createCredentialRequest, null,
                hasPermissionToOverrideDefault);
    }

    /** Creates new {@code RequestInfo} for a get-credential flow. */
@@ -89,7 +106,18 @@ public final class RequestInfo implements Parcelable {
            @NonNull IBinder token, @NonNull GetCredentialRequest getCredentialRequest,
            @NonNull String appPackageName) {
        return new RequestInfo(
                token, TYPE_GET, appPackageName, null, getCredentialRequest);
                token, TYPE_GET, appPackageName, null, getCredentialRequest,
                /*hasPermissionToOverrideDefault=*/ false);
    }


    /**
     * Returns whether the calling package has the permission
     *
     * @hide
     */
    public boolean hasPermissionToOverrideDefault() {
        return mHasPermissionToOverrideDefault;
    }

    /** Returns the request token matching the user request. */
@@ -132,12 +160,14 @@ public final class RequestInfo implements Parcelable {
    private RequestInfo(@NonNull IBinder token, @NonNull @RequestType String type,
            @NonNull String appPackageName,
            @Nullable CreateCredentialRequest createCredentialRequest,
            @Nullable GetCredentialRequest getCredentialRequest) {
            @Nullable GetCredentialRequest getCredentialRequest,
            boolean hasPermissionToOverrideDefault) {
        mToken = token;
        mType = type;
        mAppPackageName = appPackageName;
        mCreateCredentialRequest = createCredentialRequest;
        mGetCredentialRequest = getCredentialRequest;
        mHasPermissionToOverrideDefault = hasPermissionToOverrideDefault;
    }

    private RequestInfo(@NonNull Parcel in) {
@@ -157,6 +187,7 @@ public final class RequestInfo implements Parcelable {
        AnnotationValidations.validate(NonNull.class, null, mAppPackageName);
        mCreateCredentialRequest = createCredentialRequest;
        mGetCredentialRequest = getCredentialRequest;
        mHasPermissionToOverrideDefault = in.readBoolean();
    }

    @Override
@@ -166,6 +197,7 @@ public final class RequestInfo implements Parcelable {
        dest.writeString8(mAppPackageName);
        dest.writeTypedObject(mCreateCredentialRequest, flags);
        dest.writeTypedObject(mGetCredentialRequest, flags);
        dest.writeBoolean(mHasPermissionToOverrideDefault);
    }

    @Override
+5 −21
Original line number Diff line number Diff line
@@ -163,29 +163,13 @@ public final class CredentialProviderInfoFactory {

    private static boolean isSystemProviderWithValidPermission(
            ServiceInfo serviceInfo, Context context) {
        requireNonNull(context, "context must not be null");

        final String permission = Manifest.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE;
        try {
            ApplicationInfo appInfo =
                    context.getPackageManager()
                            .getApplicationInfo(
                                    serviceInfo.packageName,
                                    PackageManager.ApplicationInfoFlags.of(
                                            PackageManager.MATCH_SYSTEM_ONLY));
            if (appInfo != null
                    && context.checkPermission(permission, /* pid= */ -1, appInfo.uid)
                            == PackageManager.PERMISSION_GRANTED) {
                Slog.i(TAG, "SYS permission granted for: " + serviceInfo.packageName);
                return true;
            } else {
                Slog.i(TAG, "SYS permission failed for: " + serviceInfo.packageName);
            }
        } catch (PackageManager.NameNotFoundException e) {
            Slog.e(TAG, "Error getting info for " + serviceInfo + ": " + e);
        }
        if (context == null) {
            Slog.w(TAG, "Context is null in isSystemProviderWithValidPermission");
            return false;
        }
        return PermissionUtils.hasPermission(context, serviceInfo.packageName,
                Manifest.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE);
    }

    private static boolean isValidSystemProvider(
            Context context,
+50 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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 android.service.credentials;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;

/**
 * Utils for checking permissions, or any other permission related function
 *
 * @hide
 */
public class PermissionUtils {
    //TODO(274838409): Move all CredentialManagerService permission checks here

    /** Checks whether the given package name hold the given permission **/
    public static boolean hasPermission(Context context, String packageName, String permission) {
        try {
            ApplicationInfo appInfo =
                    context.getPackageManager()
                            .getApplicationInfo(
                                    packageName,
                                    PackageManager.ApplicationInfoFlags.of(
                                            PackageManager.MATCH_SYSTEM_ONLY));
            if (appInfo != null
                    && context.checkPermission(permission, /* pid= */ -1, appInfo.uid)
                    == PackageManager.PERMISSION_GRANTED) {
                return true;
            }
        } catch (PackageManager.NameNotFoundException e) {
        }
        return false;
    }
}
+5 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.credentials;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
@@ -31,6 +32,7 @@ import android.credentials.ui.RequestInfo;
import android.os.CancellationSignal;
import android.os.RemoteException;
import android.service.credentials.CallingAppInfo;
import android.service.credentials.PermissionUtils;
import android.util.Log;

import com.android.server.credentials.metrics.ApiName;
@@ -88,7 +90,9 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
            mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent(
                    RequestInfo.newCreateRequestInfo(
                            mRequestId, mClientRequest,
                            mClientAppInfo.getPackageName()),
                            mClientAppInfo.getPackageName(),
                            PermissionUtils.hasPermission(mContext, mClientAppInfo.getPackageName(),
                                    Manifest.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS)),
                    providerDataList));
        } catch (RemoteException e) {
            mChosenProviderFinalPhaseMetric.setUiReturned(false);
+3 −1
Original line number Diff line number Diff line
@@ -227,7 +227,9 @@ public class PrepareGetRequestSession extends RequestSession<GetCredentialReques
                    try {
                        mPrepareGetCredentialCallback.onResponse(
                                new PrepareGetCredentialResponseInternal(
                                        false, null, false, false, getUiIntent()));
                                        false, null,
                                        false, false,
                                        getUiIntent()));
                    } catch (Exception e) {
                        Log.e(TAG, "EXCEPTION while mPendingCallback.onResponse", e);
                    }
Loading