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

Commit 8025f910 authored by Reema Bajwa's avatar Reema Bajwa
Browse files

Listen to live cancellation signal

Main sessions per user in CredentialManagerService that is
ended when the session ends.

Test: Built & deployed locally, CTS tests
Bug: 270439131

Change-Id: Ib5936008f69997a05ed35e59b602f72ee10a261d
parent be257d0e
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 * 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
 *      http://www.apache.org/licenses/LICENSE-2.0N
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
@@ -74,7 +74,6 @@ class CredentialSelectorActivity : ComponentActivity() {
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        Log.d(Constants.LOG_TAG, "Existing activity received new intent")
        try {
            val viewModel: CredentialSelectorViewModel by viewModels()
            val (isCancellationRequest, shouldShowCancellationUi, appDisplayName) =
@@ -111,7 +110,7 @@ class CredentialSelectorActivity : ComponentActivity() {
            ?: return Triple(false, false, null)
        if (viewModel != null && !viewModel.shouldCancelCurrentUi(cancelUiRequest.token)) {
            // Cancellation was for a different request, don't cancel the current UI.
            return Triple(false, false, null)
            return Triple(true, false, null)
        }
        val shouldShowCancellationUi = cancelUiRequest.shouldShowCancellationUi()
        Log.d(
+4 −2
Original line number Diff line number Diff line
@@ -40,11 +40,13 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta
        implements ProviderSession.ProviderInternalCallback<Void> {
    private static final String TAG = "GetRequestSession";

    public ClearRequestSession(Context context, int userId, int callingUid,
    public ClearRequestSession(Context context, RequestSession.SessionLifetime sessionCallback,
            Object lock, int userId, int callingUid,
            IClearCredentialStateCallback callback, ClearCredentialStateRequest request,
            CallingAppInfo callingAppInfo, CancellationSignal cancellationSignal,
            long startedTimestamp) {
        super(context, userId, callingUid, request, callback, RequestInfo.TYPE_UNDEFINED,
        super(context, sessionCallback, lock, userId, callingUid, request, callback,
                RequestInfo.TYPE_UNDEFINED,
                callingAppInfo, cancellationSignal, startedTimestamp);
    }

+6 −2
Original line number Diff line number Diff line
@@ -49,13 +49,15 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
        implements ProviderSession.ProviderInternalCallback<CreateCredentialResponse> {
    private static final String TAG = "CreateRequestSession";

    CreateRequestSession(@NonNull Context context, int userId, int callingUid,
    CreateRequestSession(@NonNull Context context, RequestSession.SessionLifetime sessionCallback,
            Object lock, int userId, int callingUid,
            CreateCredentialRequest request,
            ICreateCredentialCallback callback,
            CallingAppInfo callingAppInfo,
            CancellationSignal cancellationSignal,
            long startedTimestamp) {
        super(context, userId, callingUid, request, callback, RequestInfo.TYPE_CREATE,
        super(context, sessionCallback, lock, userId, callingUid, request, callback,
                RequestInfo.TYPE_CREATE,
                callingAppInfo, cancellationSignal, startedTimestamp);
    }

@@ -83,6 +85,7 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
    @Override
    protected void launchUiWithProviderData(ArrayList<ProviderData> providerDataList) {
        mRequestSessionMetric.collectUiCallStartTime(System.nanoTime());
        mCredentialManagerUi.setStatus(CredentialManagerUi.UiStatus.USER_INTERACTION);
        try {
            mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent(
                    RequestInfo.newCreateRequestInfo(
@@ -93,6 +96,7 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
                    providerDataList));
        } catch (RemoteException e) {
            mRequestSessionMetric.collectUiReturnedFinalPhase(/*uiReturned=*/ false);
            mCredentialManagerUi.setStatus(CredentialManagerUi.UiStatus.TERMINATED);
            respondToClientWithErrorAndFinish(
                    CreateCredentialException.TYPE_UNKNOWN,
                    "Unable to invoke selector");
+54 −16
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import android.content.pm.PackageManager;
import android.credentials.ClearCredentialStateRequest;
import android.credentials.CreateCredentialException;
import android.credentials.CreateCredentialRequest;
import android.credentials.CredentialManager;
import android.credentials.CredentialOption;
import android.credentials.CredentialProviderInfo;
import android.credentials.GetCredentialException;
@@ -50,6 +49,7 @@ import android.credentials.UnregisterCredentialDescriptionRequest;
import android.credentials.ui.IntentFactory;
import android.os.Binder;
import android.os.CancellationSignal;
import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -70,9 +70,11 @@ import com.android.server.infra.AbstractMasterSystemService;
import com.android.server.infra.SecureSettingsServiceNameResolver;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@@ -102,6 +104,13 @@ public final class CredentialManagerService
    private final SparseArray<List<CredentialManagerServiceImpl>> mSystemServicesCacheList =
            new SparseArray<>();

    /** Cache of all ongoing request sessions per user id. */
    @GuardedBy("mLock")
    private final SparseArray<Map<IBinder, RequestSession>> mRequestSessions =
            new SparseArray<>();

    private final SessionManager mSessionManager = new SessionManager();

    public CredentialManagerService(@NonNull Context context) {
        super(
                context,
@@ -389,14 +398,6 @@ public final class CredentialManagerService
        return providerSessions;
    }

    private List<CredentialProviderInfo> getServicesForCredentialDescription(int userId) {
        return CredentialProviderInfoFactory.getCredentialProviderServices(
                mContext,
                userId,
                CredentialManager.PROVIDER_FILTER_ALL_PROVIDERS,
                new HashSet<>());
    }

    @Override
    @GuardedBy("CredentialDescriptionRegistry.sLock")
    public void onUserStopped(@NonNull TargetUser user) {
@@ -448,6 +449,8 @@ public final class CredentialManagerService
            final GetRequestSession session =
                    new GetRequestSession(
                            getContext(),
                            mSessionManager,
                            mLock,
                            userId,
                            callingUid,
                            callback,
@@ -455,6 +458,7 @@ public final class CredentialManagerService
                            constructCallingAppInfo(callingPackage, userId, request.getOrigin()),
                            CancellationSignal.fromTransport(cancelTransport),
                            timestampBegan);
            addSessionLocked(userId, session);

            List<ProviderSession> providerSessions =
                    prepareProviderSessions(request, session);
@@ -499,6 +503,8 @@ public final class CredentialManagerService
            final PrepareGetRequestSession session =
                    new PrepareGetRequestSession(
                            getContext(),
                            mSessionManager,
                            mLock,
                            userId,
                            callingUid,
                            getCredentialCallback,
@@ -614,6 +620,8 @@ public final class CredentialManagerService
            final CreateRequestSession session =
                    new CreateRequestSession(
                            getContext(),
                            mSessionManager,
                            mLock,
                            userId,
                            callingUid,
                            request,
@@ -621,6 +629,7 @@ public final class CredentialManagerService
                            constructCallingAppInfo(callingPackage, userId, request.getOrigin()),
                            CancellationSignal.fromTransport(cancelTransport),
                            timestampBegan);
            addSessionLocked(userId, session);

            processCreateCredential(request, callback, session);
            return cancelTransport;
@@ -815,6 +824,8 @@ public final class CredentialManagerService
            final ClearRequestSession session =
                    new ClearRequestSession(
                            getContext(),
                            mSessionManager,
                            mLock,
                            userId,
                            callingUid,
                            callback,
@@ -822,6 +833,7 @@ public final class CredentialManagerService
                            constructCallingAppInfo(callingPackage, userId, null),
                            CancellationSignal.fromTransport(cancelTransport),
                            timestampBegan);
            addSessionLocked(userId, session);

            // Initiate all provider sessions
            // TODO: Determine if provider needs to have clear capability in their manifest
@@ -905,6 +917,13 @@ public final class CredentialManagerService
        }
    }

    private void addSessionLocked(@UserIdInt int userId,
            RequestSession requestSession) {
        synchronized (mLock) {
            mSessionManager.addSession(userId, requestSession.mRequestId, requestSession);
        }
    }

    private void enforceCallingPackage(String callingPackage, int callingUid) {
        int packageUid;
        PackageManager pm = mContext.createContextAsUser(
@@ -919,4 +938,23 @@ public final class CredentialManagerService
            throw new SecurityException(callingPackage + " does not belong to uid " + callingUid);
        }
    }

    private class SessionManager implements RequestSession.SessionLifetime {
        @Override
        @GuardedBy("mLock")
        public void onFinishRequestSession(@UserIdInt int userId, IBinder token) {
            Log.i(TAG, "In onFinishRequestSession");
            if (mRequestSessions.get(userId) != null) {
                mRequestSessions.get(userId).remove(token);
            }
        }

        @GuardedBy("mLock")
        public void addSession(int userId, IBinder token, RequestSession requestSession) {
            if (mRequestSessions.get(userId) == null) {
                mRequestSessions.put(userId, new HashMap<>());
            }
            mRequestSessions.get(userId).put(token, requestSession);
        }
    }
}
+31 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.credentials.ui.RequestInfo;
import android.credentials.ui.UserSelectionDialogResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.ResultReceiver;
import android.service.credentials.CredentialProviderInfoFactory;
@@ -50,6 +51,20 @@ public class CredentialManagerUi {
    @NonNull private final Context mContext;
    // TODO : Use for starting the activity for this user
    private final int mUserId;

    private UiStatus mStatus;

    /** Creates intent that is ot be invoked to cancel an in-progress UI session. */
    public Intent createCancelIntent(IBinder requestId, String packageName) {
        return IntentFactory.createCancelUiIntent(requestId, /*shouldShowCancellationUi=*/ true,
                packageName);
    }

    enum UiStatus {
        IN_PROGRESS,
        USER_INTERACTION,
        NOT_STARTED, TERMINATED
    }
    @NonNull private final ResultReceiver mResultReceiver = new ResultReceiver(
            new Handler(Looper.getMainLooper())) {
        @Override
@@ -61,6 +76,7 @@ public class CredentialManagerUi {
    private void handleUiResult(int resultCode, Bundle resultData) {
        switch (resultCode) {
            case UserSelectionDialogResult.RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION:
                mStatus = UiStatus.IN_PROGRESS;
                UserSelectionDialogResult selection = UserSelectionDialogResult
                        .fromResultData(resultData);
                if (selection != null) {
@@ -70,16 +86,20 @@ public class CredentialManagerUi {
                }
                break;
            case UserSelectionDialogResult.RESULT_CODE_DIALOG_USER_CANCELED:
                mStatus = UiStatus.TERMINATED;
                mCallbacks.onUiCancellation(/* isUserCancellation= */ true);
                break;
            case UserSelectionDialogResult.RESULT_CODE_CANCELED_AND_LAUNCHED_SETTINGS:
                mStatus = UiStatus.TERMINATED;
                mCallbacks.onUiCancellation(/* isUserCancellation= */ false);
                break;
            case UserSelectionDialogResult.RESULT_CODE_DATA_PARSING_FAILURE:
                mStatus = UiStatus.TERMINATED;
                mCallbacks.onUiSelectorInvocationFailure();
                break;
            default:
                Slog.i(TAG, "Unknown error code returned from the UI");
                mStatus = UiStatus.IN_PROGRESS;
                mCallbacks.onUiSelectorInvocationFailure();
                break;
        }
@@ -103,6 +123,17 @@ public class CredentialManagerUi {
        mContext = context;
        mUserId = userId;
        mCallbacks = callbacks;
        mStatus = UiStatus.IN_PROGRESS;
    }

    /** Set status for credential manager UI */
    public void setStatus(UiStatus status) {
        mStatus = status;
    }

    /** Returns status for credential manager UI */
    public UiStatus getStatus() {
        return mStatus;
    }

    /**
Loading