diff options
| author | 2024-02-06 00:52:47 +0000 | |
|---|---|---|
| committer | 2024-02-06 00:52:47 +0000 | |
| commit | 8ae6fefd810423c3d6d0be716be6fe0637320f7c (patch) | |
| tree | 2a851cd2326209123a3943b3001acd2e04755a2b | |
| parent | 862b59b91de0833bdf6d6ce9c08403fe183ae4e4 (diff) | |
| parent | 98d4af54d1dab99e45964887835ed08b6e5abf4e (diff) | |
Merge "Log when webview requests credential" into main
4 files changed, 48 insertions, 13 deletions
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java index 298bdb881e9f..e6a84df16c27 100644 --- a/core/java/android/service/autofill/AutofillService.java +++ b/core/java/android/service/autofill/AutofillService.java @@ -600,6 +600,14 @@ public abstract class AutofillService extends Service { */ public static final String EXTRA_ERROR = "error"; + /** + * Name of the key used to mark whether the fill response is for a webview. + * + * @hide + */ + public static final String WEBVIEW_REQUESTED_CREDENTIAL_KEY = "webview_requested_credential"; + + private final IAutoFillService mInterface = new IAutoFillService.Stub() { @Override public void onConnectedStateChanged(boolean connected) { diff --git a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt index 07f1fa34580b..f496c1f09c95 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt @@ -116,8 +116,10 @@ class CredentialAutofillService : AutofillService() { return } + val responseClientState = Bundle() + responseClientState.putBoolean(WEBVIEW_REQUESTED_CREDENTIAL_KEY, false) val getCredRequest: GetCredentialRequest? = getCredManRequest(structure, sessionId, - requestId) + requestId, responseClientState) if (getCredRequest == null) { Log.i(TAG, "No credential manager request found") callback.onFailure("No credential manager request found") @@ -153,7 +155,8 @@ class CredentialAutofillService : AutofillService() { return } - val fillResponse = convertToFillResponse(result, request) + val fillResponse = convertToFillResponse(result, request, + responseClientState) if (fillResponse != null) { callback.onSuccess(fillResponse) } else { @@ -260,7 +263,8 @@ class CredentialAutofillService : AutofillService() { private fun convertToFillResponse( getCredResponse: GetCandidateCredentialsResponse, - filLRequest: FillRequest + filLRequest: FillRequest, + responseClientState: Bundle ): FillResponse? { val candidateProviders = getCredResponse.candidateProviderDataList if (candidateProviders.isEmpty()) { @@ -281,6 +285,7 @@ class CredentialAutofillService : AutofillService() { if (!validFillResponse) { return null } + fillResponseBuilder.setClientState(responseClientState) return fillResponseBuilder.build() } @@ -578,10 +583,11 @@ class CredentialAutofillService : AutofillService() { private fun getCredManRequest( structure: AssistStructure, sessionId: Int, - requestId: Int + requestId: Int, + responseClientState: Bundle ): GetCredentialRequest? { val credentialOptions: MutableList<CredentialOption> = mutableListOf() - traverseStructure(structure, credentialOptions) + traverseStructure(structure, credentialOptions, responseClientState) if (credentialOptions.isNotEmpty()) { val dataBundle = Bundle() @@ -596,7 +602,8 @@ class CredentialAutofillService : AutofillService() { private fun traverseStructure( structure: AssistStructure, - cmRequests: MutableList<CredentialOption> + cmRequests: MutableList<CredentialOption>, + responseClientState: Bundle ) { val windowNodes: List<AssistStructure.WindowNode> = structure.run { @@ -604,16 +611,17 @@ class CredentialAutofillService : AutofillService() { } windowNodes.forEach { windowNode: AssistStructure.WindowNode -> - traverseNode(windowNode.rootViewNode, cmRequests) + traverseNode(windowNode.rootViewNode, cmRequests, responseClientState) } } private fun traverseNode( viewNode: AssistStructure.ViewNode, - cmRequests: MutableList<CredentialOption> + cmRequests: MutableList<CredentialOption>, + responseClientState: Bundle ) { viewNode.autofillId?.let { - val options = getCredentialOptionsFromViewNode(viewNode, it) + val options = getCredentialOptionsFromViewNode(viewNode, it, responseClientState) cmRequests.addAll(options) } @@ -623,13 +631,14 @@ class CredentialAutofillService : AutofillService() { } children.forEach { childNode: AssistStructure.ViewNode -> - traverseNode(childNode, cmRequests) + traverseNode(childNode, cmRequests, responseClientState) } } private fun getCredentialOptionsFromViewNode( viewNode: AssistStructure.ViewNode, - autofillId: AutofillId + autofillId: AutofillId, + responseClientState: Bundle ): List<CredentialOption> { // TODO(b/293945193) Replace with isCredential check from viewNode val credentialHints: MutableList<String> = mutableListOf() @@ -637,6 +646,9 @@ class CredentialAutofillService : AutofillService() { for (hint in viewNode.autofillHints!!) { if (hint.startsWith(CRED_HINT_PREFIX)) { credentialHints.add(hint.substringAfter(CRED_HINT_PREFIX)) + if (viewNode.webDomain != null) { + responseClientState.putBoolean(WEBVIEW_REQUESTED_CREDENTIAL_KEY, true) + } } } } diff --git a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java index cf414d145db1..3645c40aeda2 100644 --- a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java +++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java @@ -254,6 +254,14 @@ public final class PresentationStatsEventLogger { mEventInternal.ifPresent(event -> event.mIsCredentialRequest = isCredentialRequest); } + /** + * Set webview_requested_credential + */ + public void maybeSetWebviewRequestedCredential(boolean webviewRequestedCredential) { + mEventInternal.ifPresent(event -> + event.mWebviewRequestedCredential = webviewRequestedCredential); + } + public void maybeSetNoPresentationEventReason(@NotShownReason int reason) { mEventInternal.ifPresent(event -> { if (event.mCountShown == 0) { @@ -578,7 +586,8 @@ public final class PresentationStatsEventLogger { + " mDetectionPreference=" + event.mDetectionPreference + " mFieldClassificationRequestId=" + event.mFieldClassificationRequestId + " mAppPackageUid=" + mCallingAppUid - + " mIsCredentialRequest=" + event.mIsCredentialRequest); + + " mIsCredentialRequest=" + event.mIsCredentialRequest + + " mWebviewRequestedCredential=" + event.mWebviewRequestedCredential); } // TODO(b/234185326): Distinguish empty responses from other no presentation reasons. @@ -618,7 +627,8 @@ public final class PresentationStatsEventLogger { event.mDetectionPreference, event.mFieldClassificationRequestId, mCallingAppUid, - event.mIsCredentialRequest); + event.mIsCredentialRequest, + event.mWebviewRequestedCredential); mEventInternal = Optional.empty(); } @@ -653,6 +663,7 @@ public final class PresentationStatsEventLogger { @DetectionPreference int mDetectionPreference = DETECTION_PREFER_UNKNOWN; int mFieldClassificationRequestId = -1; boolean mIsCredentialRequest = false; + boolean mWebviewRequestedCredential = false; PresentationStatsEventInternal() {} } diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 049feeed2fa1..83d9cdbd2843 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -18,6 +18,7 @@ package com.android.server.autofill; import static android.service.autofill.AutofillFieldClassificationService.EXTRA_SCORES; import static android.service.autofill.AutofillService.EXTRA_FILL_RESPONSE; +import static android.service.autofill.AutofillService.WEBVIEW_REQUESTED_CREDENTIAL_KEY; import static android.service.autofill.Dataset.PICK_REASON_NO_PCC; import static android.service.autofill.Dataset.PICK_REASON_PCC_DETECTION_ONLY; import static android.service.autofill.Dataset.PICK_REASON_PCC_DETECTION_PREFERRED_WITH_PROVIDER; @@ -5516,8 +5517,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mResponses.put(requestId, newResponse); mClientState = newClientState != null ? newClientState : newResponse.getClientState(); + boolean webviewRequestedCredman = newClientState != null && newClientState.getBoolean( + WEBVIEW_REQUESTED_CREDENTIAL_KEY, false); List<Dataset> datasetList = newResponse.getDatasets(); + mPresentationStatsEventLogger.maybeSetWebviewRequestedCredential(webviewRequestedCredman); mPresentationStatsEventLogger.maybeSetFieldClassificationRequestId(sIdCounterForPcc.get()); mPresentationStatsEventLogger.maybeSetAvailableCount(datasetList, mCurrentViewId); mFillResponseEventLogger.maybeSetDatasetsCountAfterPotentialPccFiltering(datasetList); |