diff options
| author | 2018-05-25 00:18:41 +0000 | |
|---|---|---|
| committer | 2018-05-25 00:18:41 +0000 | |
| commit | 94594d1290a15ff56770301debfce2097fa5996c (patch) | |
| tree | cacc2d5017e0433fe53a0c4efae0bff91a5220e1 | |
| parent | a9050275ba4bc05da778b38060e9d06c4434302e (diff) | |
| parent | f61ba5cabf031181154d82c46715ef4fad2d3557 (diff) | |
Merge "Merged many autofill session metrics into AUTOFILL_REQUEST:" into pi-dev
7 files changed, 294 insertions, 94 deletions
diff --git a/core/java/android/service/autofill/FillCallback.java b/core/java/android/service/autofill/FillCallback.java index 105cd3867463..0257891e5f38 100644 --- a/core/java/android/service/autofill/FillCallback.java +++ b/core/java/android/service/autofill/FillCallback.java @@ -70,7 +70,7 @@ public final class FillCallback { assertNotCalled(); mCalled = true; try { - mCallback.onFailure(message); + mCallback.onFailure(mRequestId, message); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } diff --git a/core/java/android/service/autofill/IFillCallback.aidl b/core/java/android/service/autofill/IFillCallback.aidl index 2bb3e9acd3e1..1bad1d7f474a 100644 --- a/core/java/android/service/autofill/IFillCallback.aidl +++ b/core/java/android/service/autofill/IFillCallback.aidl @@ -28,5 +28,5 @@ import android.service.autofill.FillResponse; interface IFillCallback { void onCancellable(in ICancellationSignal cancellation); void onSuccess(in FillResponse response); - void onFailure(CharSequence message); + void onFailure(int requestId, CharSequence message); } diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index d06410597391..1c701d7c7391 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -3986,27 +3986,40 @@ message MetricsEvent { // OS: O APP_TRANSITION_IS_EPHEMERAL = 905; - // An autofill session was started + // An autofill session was started. + // OS: O // Package: Package of app that is autofilled // NOTE: starting on OS MR1, it also added the following field: // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // NOTE: starting on OS P, it also added the following field: - // Tag FIELD_FLAGS - Flags used to start the session + // Tag FIELD_AUTOFIL_FLAGS - Flags used to start the session // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SESSION_STARTED = 906; // An autofill request was processed by a service - // Type TYPE_SUCCESS: The request succeeded - // Type TYPE_FAILURE: The request failed + // Type TYPE_SUCCESS: service called FillCalback.onSuccess() + // Type TYPE_FAILURE: service called FillCallback.onFailure() // Package: Package of app that is autofilled // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_NUM_DATASETS: The number of datasets returned in the response, or -1 if - // the service returned a null response. - // NOTE: starting on OS P, it also added: - // Type TYPE_CLOSE: Service returned a null response. + // the service returned a null response + // NOTE: starting on OS P, it also added the following fields: + // TYPE_CLOSE: request timed out before service called a FillCallback method + // Tag FIELD_AUTOFILL_REQUEST_ORDINAL: sequence number of the request inside a session; starts + // with 1. + // Tag FIELD_AUTOFILL_FLAGS: flags used to request autofill + // Tag FIELD_AUTOFILL_DURATION: how long it took (in ms) to show the autofill UI after a field + // was focused. + // Tag FIELD_AUTOFILL_AUTHENTICATION_STATUS: status of authenticated datasets or responses. // Tag FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS: if service requested field classification, - // number of entries field ids in the request. - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // number of entries field ids in the request. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: Prior to P, some of the fields above were logged by 5 different metrics: + // - AUTOFILL_UI_LATENCY + // - AUTOFILL_AUTHENTICATED; + // - AUTOFILL_DATASET_AUTHENTICATED + // - AUTOFILL_INVALID_AUTHENTICATION + // - AUTOFILL_INVALID_DATASET_AUTHENTICATION AUTOFILL_REQUEST = 907; // Tag of a field for a package of an autofill service @@ -4025,7 +4038,7 @@ message MetricsEvent { // Tag FIELD_AUTOFILL_NUM_DATASETS: The number of datasets shown // NOTE: starting on OS P, it also added the following field: // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_FILL_UI = 910; // Tag of a field for the length of the filter text @@ -4034,8 +4047,7 @@ message MetricsEvent { // An autofill authentication succeeded // Package: Package of app that was autofilled // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, this metric became a value for FIELD_AUTOFILL_AUTHENTICATION_STATUS AUTOFILL_AUTHENTICATED = 912; // An activity was autofilled and all values could be applied @@ -4043,7 +4055,7 @@ message MetricsEvent { // Tag FIELD_AUTOFILL_NUM_VALUES: Number of values that were suggested to be autofilled // Tag FIELD_AUTOFILL_NUM_VIEWS_FILLED: Number of views that could be filled // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_DATASET_APPLIED = 913; // Tag of a field for the number values to be filled in @@ -4060,26 +4072,30 @@ message MetricsEvent { // Tag FIELD_AUTOFILL_NUM_IDS: The number of ids that are saved // NOTE: starting on OS P, it also added the following field: // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SAVE_UI = 916; // Tag of a field for the number of saveable ids FIELD_AUTOFILL_NUM_IDS = 917; - // ACTION: An autofill service was reqiested to save data + // ACTION: An autofill service was requested to save data // Type TYPE_SUCCESS: The request succeeded right away // Type TYPE_OPEN: The request succeeded but the service launched an IntentSender // Type TYPE_FAILURE: The request failed // Package: Package of app that was autofilled // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_DATA_SAVE_REQUEST = 918; // An auto-fill session was finished + // OS: O // Package: Package of app that was autofilled - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, it also added the following fields: + // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_NUMBER_REQUESTS: number of requests made to the service (each request + // is logged by a separate AUTOFILL_REQUEST metric) AUTOFILL_SESSION_FINISHED = 919; // meta-event: a reader has checkpointed the log here. @@ -4206,7 +4222,7 @@ message MetricsEvent { // Tag FIELD_AUTOFILL_SERVICE: Package of the autofill service that processed the request // TAG FIELD_AUTOFILL_FORGED_COMPONENT_NAME: Component name being forged // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_FORGED_COMPONENT_ATTEMPT = 948; // FIELD - The component that an app tried tro forged. @@ -4665,7 +4681,7 @@ message MetricsEvent { // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_PREVIOUS_LENGTH: the previous length of the value // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_VALUE_RESET = 1124; // Tag of AUTOFILL_VALUE_RESET @@ -4675,25 +4691,21 @@ message MetricsEvent { // An autofill dataset authentication succeeded // Package: Package of app that was autofilled // OS: O MR - // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, this metric became a value for FIELD_AUTOFILL_AUTHENTICATION_STATUS AUTOFILL_DATASET_AUTHENTICATED = 1126; // An autofill service provided an invalid dataset authentication // Package: Package of app that was autofilled // OS: O MR // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, this metric became a value for FIELD_AUTOFILL_AUTHENTICATION_STATUS AUTOFILL_INVALID_DATASET_AUTHENTICATION = 1127; // An autofill service provided an invalid authentication extra // Package: Package of app that was autofilled // OS: O MR // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, this metric became a value for FIELD_AUTOFILL_AUTHENTICATION_STATUS AUTOFILL_INVALID_AUTHENTICATION = 1128; // An autofill service used a custom description (using RemoteViews) in the autofill save UI @@ -4702,7 +4714,7 @@ message MetricsEvent { // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SAVE_CUSTOM_DESCRIPTION = 1129; // FIELD - Type of save object passed by the service when the Save UI is shown @@ -4715,7 +4727,7 @@ message MetricsEvent { // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SAVE_CUSTOM_SUBTITLE = 1131; // User tapped a link in the custom description of the autofill save UI provided by an autofill service @@ -4727,7 +4739,7 @@ message MetricsEvent { // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SAVE_LINK_TAPPED = 1132; // Result of the validation on save when an autofill service provided a validator @@ -4739,7 +4751,7 @@ message MetricsEvent { // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SAVE_VALIDATION = 1133; // Result of an operation in the autofill save UI after the user tapped a link in the custom description @@ -4750,7 +4762,7 @@ message MetricsEvent { // Type TYPE_DISMISS: The autofill save UI was destroyed // Type TYPE_FAILURE: An invalid opperation was reported by the app's AutofillManager // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_PENDING_SAVE_UI_OPERATION = 1134; // Autofill service called API that disables itself @@ -4758,13 +4770,12 @@ message MetricsEvent { // OS: O MR AUTOFILL_SERVICE_DISABLED_SELF = 1135; + // DEPRECATED - on P it was merged with AUTOFILL_REQUEST // Reports how long it took to show the autofill UI after a field was focused // Tag FIELD_AUTOFILL_DURATION: Duration in ms // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Package: Package of the autofill service // OS: O MR - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_UI_LATENCY = 1136; // Action: the snooze leave-behind was shown after the user clicked the snooze icon @@ -4932,14 +4943,14 @@ message MetricsEvent { // Package: Package of app that is autofilled // OS: P // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_EXPLICIT_SAVE_TRIGGER_DEFINITION = 1228; // The autofill context was commited when the user clicked a view explicitly marked by the // service as committing it // Package: Package of app that is autofilled // OS: P - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SAVE_EXPLICITLY_TRIGGERED = 1229; // OPEN: Settings > Network & Internet > Mobile network > Wi-Fi calling @@ -4952,7 +4963,7 @@ message MetricsEvent { // OS: P // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_DURATION: duration (in ms) that autofill will be disabled - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SERVICE_DISABLED_APP = 1231; // An autofill service asked to disable autofill for a given activity. @@ -4961,7 +4972,7 @@ message MetricsEvent { // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_CLASS_NAME: Class name of the activity that is being disabled for autofill // Tag FIELD_AUTOFILL_DURATION: duration (in ms) that autofill will be disabled - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SERVICE_DISABLED_ACTIVITY = 1232; // ACTION: Stop an app and turn on background check @@ -5173,7 +5184,7 @@ message MetricsEvent { // OS: P // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_MATCH_SCORE: Average score of the matches, in the range of 0 to 100 - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_FIELD_CLASSIFICATION_MATCHES = 1273; // Tag used to report autofill field classification scores @@ -5840,6 +5851,7 @@ message MetricsEvent { ACTION_STORAGE_MIGRATE_LATER = 1413; // Tag used to report whether an activity is being autofilled on compatibility mode. + // OS: P FIELD_AUTOFILL_COMPAT_MODE = 1414; // OPEN: Settings > Sound > Switch a2dp devices dialog @@ -6045,6 +6057,28 @@ message MetricsEvent { // OS: P ACTION_BATTERY_CAUSED_SHUTDOWN = 1451; + // FIELD: Flags used on autofill-related metrics + // OS: P + FIELD_AUTOFILL_FLAGS = 1452; + + // Tag used when the service returned an authenticated dataset or response. + // Used to replace the following individual metrics, which now are logged as the value of this + // field in the AUTOFILL_REQUEST metric: + // - AUTOFILL_AUTHENTICATED; + // - AUTOFILL_DATASET_AUTHENTICATED + // - AUTOFILL_INVALID_AUTHENTICATION + // - AUTOFILL_INVALID_DATASET_AUTHENTICATION + // OS: P + FIELD_AUTOFILL_AUTHENTICATION_STATUS = 1453; + + // FIELD: Index of the autofill request inside of a session. + // OS: P + FIELD_AUTOFILL_REQUEST_ORDINAL = 1454; + + // FIELD: Number of requests made to an autofill service during a session. + // OS: P + FIELD_AUTOFILL_NUMBER_REQUESTS = 1455; + // ---- End P Constants, all P constants go above this line ---- // Add new aosp constants above this line. // END OF AOSP CONSTANTS diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java index f78101338d2e..ad884c6b8d69 100644 --- a/services/autofill/java/com/android/server/autofill/Helper.java +++ b/services/autofill/java/com/android/server/autofill/Helper.java @@ -121,8 +121,11 @@ public final class Helper { @NonNull public static LogMaker newLogMaker(int category, String packageName, String servicePackageName, boolean compatMode) { - return newLogMaker(category, packageName, servicePackageName) - .addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, compatMode ? 1 : 0); + final LogMaker log = newLogMaker(category, packageName, servicePackageName); + if (compatMode) { + log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, 1); + } + return log; } public static void printlnRedactedText(@NonNull PrintWriter pw, @Nullable CharSequence text) { @@ -193,6 +196,18 @@ public final class Helper { return urlBarNode; } + /** + * Gets the value of a metric tag, or {@code 0} if not found or NaN. + */ + static int getNumericValue(@NonNull LogMaker log, int tag) { + final Object value = log.getTaggedData(tag); + if (!(value instanceof Number)) { + return 0; + } else { + return ((Number) value).intValue(); + } + } + private interface ViewNodeFilter { boolean matches(ViewNode node); } diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java index 4ded3fe29f2a..3e932e8d6daf 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java @@ -99,12 +99,14 @@ final class RemoteFillService implements DeathRecipient { private PendingRequest mPendingRequest; public interface FillServiceCallbacks { - void onFillRequestSuccess(int requestFlags, @Nullable FillResponse response, - @NonNull String servicePackageName); - void onFillRequestFailure(@Nullable CharSequence message, + void onFillRequestSuccess(int requestId, @Nullable FillResponse response, + @NonNull String servicePackageName, int requestFlags); + void onFillRequestFailure(int requestId, @Nullable CharSequence message, @NonNull String servicePackageName); + void onFillRequestTimeout(int requestId, @NonNull String servicePackageName); void onSaveRequestSuccess(@NonNull String servicePackageName, @Nullable IntentSender intentSender); + // TODO(b/80093094): add timeout here too? void onSaveRequestFailure(@Nullable CharSequence message, @NonNull String servicePackageName); void onServiceDied(RemoteFillService service); @@ -301,21 +303,31 @@ final class RemoteFillService implements DeathRecipient { mContext.unbindService(mServiceConnection); } - private void dispatchOnFillRequestSuccess(PendingRequest pendingRequest, int requestFlags, - FillResponse response) { + private void dispatchOnFillRequestSuccess(@NonNull PendingFillRequest pendingRequest, + @Nullable FillResponse response, int requestFlags) { mHandler.post(() -> { if (handleResponseCallbackCommon(pendingRequest)) { - mCallbacks.onFillRequestSuccess(requestFlags, response, - mComponentName.getPackageName()); + mCallbacks.onFillRequestSuccess(pendingRequest.mRequest.getId(), response, + mComponentName.getPackageName(), requestFlags); } }); } - private void dispatchOnFillRequestFailure(PendingRequest pendingRequest, + private void dispatchOnFillRequestFailure(@NonNull PendingFillRequest pendingRequest, @Nullable CharSequence message) { mHandler.post(() -> { if (handleResponseCallbackCommon(pendingRequest)) { - mCallbacks.onFillRequestFailure(message, mComponentName.getPackageName()); + mCallbacks.onFillRequestFailure(pendingRequest.mRequest.getId(), message, + mComponentName.getPackageName()); + } + }); + } + + private void dispatchOnFillRequestTimeout(@NonNull PendingFillRequest pendingRequest) { + mHandler.post(() -> { + if (handleResponseCallbackCommon(pendingRequest)) { + mCallbacks.onFillRequestTimeout(pendingRequest.mRequest.getId(), + mComponentName.getPackageName()); } }); } @@ -538,18 +550,18 @@ final class RemoteFillService implements DeathRecipient { final RemoteFillService remoteService = getService(); if (remoteService != null) { remoteService.dispatchOnFillRequestSuccess(PendingFillRequest.this, - request.getFlags(), response); + response, request.getFlags()); } } @Override - public void onFailure(CharSequence message) { + public void onFailure(int requestId, CharSequence message) { if (!finish()) return; final RemoteFillService remoteService = getService(); if (remoteService != null) { - remoteService.dispatchOnFillRequestFailure( - PendingFillRequest.this, message); + remoteService.dispatchOnFillRequestFailure(PendingFillRequest.this, + message); } } }; @@ -566,7 +578,7 @@ final class RemoteFillService implements DeathRecipient { if (cancellation != null) { remoteService.dispatchOnFillTimeout(cancellation); } - remoteService.dispatchOnFillRequestFailure(PendingFillRequest.this, null); + remoteService.dispatchOnFillRequestTimeout(PendingFillRequest.this); } @Override diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 73c71725200c..ff3eb85aa90d 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -27,6 +27,7 @@ import static android.view.autofill.AutofillManager.ACTION_VIEW_ENTERED; import static android.view.autofill.AutofillManager.ACTION_VIEW_EXITED; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; +import static com.android.server.autofill.Helper.getNumericValue; import static com.android.server.autofill.Helper.sDebug; import static com.android.server.autofill.Helper.sPartitionMaxCount; import static com.android.server.autofill.Helper.sVerbose; @@ -93,6 +94,7 @@ import com.android.server.autofill.ui.AutoFillUI; import com.android.server.autofill.ui.PendingUi; import java.io.PrintWriter; +import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -176,7 +178,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState /** * Contexts read from the app; they will be updated (sanitized, change values for save) before - * sent to {@link AutofillService}. Ordered by the time they we read. + * sent to {@link AutofillService}. Ordered by the time they were read. */ @GuardedBy("mLock") private ArrayList<FillContext> mContexts; @@ -231,6 +233,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState private final LocalLog mWtfHistory; /** + * Map of {@link MetricsEvent#AUTOFILL_REQUEST} metrics, keyed by fill request id. + */ + @GuardedBy("mLock") + private final SparseArray<LogMaker> mRequestLogs = new SparseArray<>(1); + + /** * Receiver of assist data from the app's {@link Activity}. */ private final IAssistDataReceiver mAssistReceiver = new IAssistDataReceiver.Stub() { @@ -483,8 +491,18 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState requestId = sIdCounter.getAndIncrement(); } while (requestId == INVALID_REQUEST_ID); + // Create a metrics log for the request + final int ordinal = mRequestLogs.size() + 1; + final LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_REQUEST) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_REQUEST_ORDINAL, ordinal); + if (flags != 0) { + log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_FLAGS, flags); + } + mRequestLogs.put(requestId, log); + if (sVerbose) { - Slog.v(TAG, "Requesting structure for requestId=" + requestId + ", flags=" + flags); + Slog.v(TAG, "Requesting structure for request #" + ordinal + " ,requestId=" + + requestId + ", flags=" + flags); } // If the focus changes very quickly before the first request is returned each focus change @@ -537,7 +555,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState setClientLocked(client); mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_STARTED) - .addTaggedData(MetricsEvent.FIELD_FLAGS, flags)); + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FLAGS, flags)); } /** @@ -604,21 +622,30 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // FillServiceCallbacks @Override - public void onFillRequestSuccess(int requestFlags, @Nullable FillResponse response, - @NonNull String servicePackageName) { + public void onFillRequestSuccess(int requestId, @Nullable FillResponse response, + @NonNull String servicePackageName, int requestFlags) { final AutofillId[] fieldClassificationIds; + final LogMaker requestLog; + synchronized (mLock) { if (mDestroyed) { Slog.w(TAG, "Call to Session#onFillRequestSuccess() rejected - session: " + id + " destroyed"); return; } + + requestLog = mRequestLogs.get(requestId); + if (requestLog != null) { + requestLog.setType(MetricsEvent.TYPE_SUCCESS); + } else { + Slog.w(TAG, "onFillRequestSuccess(): no request log for id " + requestId); + } if (response == null) { + if (requestLog != null) { + requestLog.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, -1); + } processNullResponseLocked(requestFlags); - mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_REQUEST, servicePackageName) - .setType(MetricsEvent.TYPE_SUCCESS) - .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, -1)); return; } @@ -659,38 +686,54 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // Response is "empty" from an UI point of view, need to notify client. notifyUnavailableToClient(sessionFinishedState); } - synchronized (mLock) { - processResponseLocked(response, null, requestFlags); + + if (requestLog != null) { + requestLog.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, + response.getDatasets() == null ? 0 : response.getDatasets().size()); + if (fieldClassificationIds != null) { + requestLog.addTaggedData( + MetricsEvent.FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS, + fieldClassificationIds.length); + } } - final LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_REQUEST, servicePackageName) - .setType(MetricsEvent.TYPE_SUCCESS) - .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, - response.getDatasets() == null ? 0 : response.getDatasets().size()); - if (fieldClassificationIds != null) { - log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS, - fieldClassificationIds.length); + synchronized (mLock) { + processResponseLocked(response, null, requestFlags); } - mMetricsLogger.write(log); } // FillServiceCallbacks @Override - public void onFillRequestFailure(@Nullable CharSequence message, + public void onFillRequestFailure(int requestId, @Nullable CharSequence message, @NonNull String servicePackageName) { + onFillRequestFailureOrTimeout(requestId, false, message, servicePackageName); + } + + // FillServiceCallbacks + @Override + public void onFillRequestTimeout(int requestId, @NonNull String servicePackageName) { + onFillRequestFailureOrTimeout(requestId, true, null, servicePackageName); + } + + private void onFillRequestFailureOrTimeout(int requestId, boolean timedOut, + @Nullable CharSequence message, @NonNull String servicePackageName) { synchronized (mLock) { if (mDestroyed) { - Slog.w(TAG, "Call to Session#onFillRequestFailure() rejected - session: " - + id + " destroyed"); + Slog.w(TAG, "Call to Session#onFillRequestFailureOrTimeout(req=" + requestId + + ") rejected - session: " + id + " destroyed"); return; } mService.resetLastResponse(); + final LogMaker requestLog = mRequestLogs.get(requestId); + if (requestLog == null) { + Slog.w(TAG, "onFillRequestFailureOrTimeout(): no log for id " + requestId); + } else { + requestLog.setType(timedOut ? MetricsEvent.TYPE_CLOSE : MetricsEvent.TYPE_FAILURE); + } + } + if (message != null) { + getUiForShowing().showError(message, this); } - LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_REQUEST, servicePackageName) - .setType(MetricsEvent.TYPE_FAILURE); - mMetricsLogger.write(log); - - getUiForShowing().showError(message, this); removeSelf(); } @@ -973,11 +1016,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState + ", clientState=" + newClientState); } if (result instanceof FillResponse) { - writeLog(MetricsEvent.AUTOFILL_AUTHENTICATED); + logAuthenticationStatusLocked(requestId, MetricsEvent.AUTOFILL_AUTHENTICATED); replaceResponseLocked(authenticatedResponse, (FillResponse) result, newClientState); } else if (result instanceof Dataset) { if (datasetIdx != AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED) { - writeLog(MetricsEvent.AUTOFILL_DATASET_AUTHENTICATED); + logAuthenticationStatusLocked(requestId, + MetricsEvent.AUTOFILL_DATASET_AUTHENTICATED); if (newClientState != null) { if (sDebug) Slog.d(TAG, "Updating client state from auth dataset"); mClientState = newClientState; @@ -986,13 +1030,15 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState authenticatedResponse.getDatasets().set(datasetIdx, dataset); autoFill(requestId, datasetIdx, dataset, false); } else { - writeLog(MetricsEvent.AUTOFILL_INVALID_DATASET_AUTHENTICATION); + logAuthenticationStatusLocked(requestId, + MetricsEvent.AUTOFILL_INVALID_DATASET_AUTHENTICATION); } } else { if (result != null) { Slog.w(TAG, "service returned invalid auth type: " + result); } - writeLog(MetricsEvent.AUTOFILL_INVALID_AUTHENTICATION); + logAuthenticationStatusLocked(requestId, + MetricsEvent.AUTOFILL_INVALID_AUTHENTICATION); processNullResponseLocked(0); } } @@ -1404,7 +1450,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState * the current values of all fields in the screen. */ if (saveInfo == null) { - if (sVerbose) Slog.w(TAG, "showSaveLocked(): no saveInfo from service"); + if (sVerbose) Slog.v(TAG, "showSaveLocked(): no saveInfo from service"); return true; } @@ -2065,7 +2111,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } @Override - public void onFillReady(FillResponse response, AutofillId filledId, + public void onFillReady(@NonNull FillResponse response, @NonNull AutofillId filledId, @Nullable AutofillValue value) { synchronized (mLock) { if (mDestroyed) { @@ -2103,9 +2149,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState TimeUtils.formatDuration(duration, historyLog); mUiLatencyHistory.log(historyLog.toString()); - final LogMaker metricsLog = newLogMaker(MetricsEvent.AUTOFILL_UI_LATENCY) - .addTaggedData(MetricsEvent.FIELD_AUTOFILL_DURATION, duration); - mMetricsLogger.write(metricsLog); + addTaggedDataToRequestLogLocked(response.getRequestId(), + MetricsEvent.FIELD_AUTOFILL_DURATION, duration); } } } @@ -2474,6 +2519,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState TimeUtils.formatDuration(mUiShownTime - mStartTime, pw); pw.println(); } + final int requestLogsSizes = mRequestLogs.size(); + pw.print(prefix); pw.print("mSessionLogs: "); pw.println(requestLogsSizes); + for (int i = 0; i < requestLogsSizes; i++) { + final int requestId = mRequestLogs.keyAt(i); + final LogMaker log = mRequestLogs.valueAt(i); + pw.print(prefix2); pw.print('#'); pw.print(i); pw.print(": req="); + pw.print(requestId); pw.print(", log=" ); dumpRequestLog(pw, log); pw.println(); + } pw.print(prefix); pw.print("mResponses: "); if (mResponses == null) { pw.println("null"); @@ -2532,6 +2585,56 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mRemoteFillService.dump(prefix, pw); } + private static void dumpRequestLog(@NonNull PrintWriter pw, @NonNull LogMaker log) { + pw.print("CAT="); pw.print(log.getCategory()); + pw.print(", TYPE="); + final int type = log.getType(); + switch (type) { + case MetricsEvent.TYPE_SUCCESS: pw.print("SUCCESS"); break; + case MetricsEvent.TYPE_FAILURE: pw.print("FAILURE"); break; + case MetricsEvent.TYPE_CLOSE: pw.print("CLOSE"); break; + default: pw.print("UNSUPPORTED"); + } + pw.print('('); pw.print(type); pw.print(')'); + pw.print(", PKG="); pw.print(log.getPackageName()); + pw.print(", SERVICE="); pw.print(log + .getTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE)); + pw.print(", ORDINAL="); pw.print(log + .getTaggedData(MetricsEvent.FIELD_AUTOFILL_REQUEST_ORDINAL)); + dumpNumericValue(pw, log, "FLAGS", MetricsEvent.FIELD_AUTOFILL_FLAGS); + dumpNumericValue(pw, log, "NUM_DATASETS", MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS); + dumpNumericValue(pw, log, "UI_LATENCY", MetricsEvent.FIELD_AUTOFILL_DURATION); + final int authStatus = + getNumericValue(log, MetricsEvent.FIELD_AUTOFILL_AUTHENTICATION_STATUS); + if (authStatus != 0) { + pw.print(", AUTH_STATUS="); + switch (authStatus) { + case MetricsEvent.AUTOFILL_AUTHENTICATED: + pw.print("AUTHENTICATED"); break; + case MetricsEvent.AUTOFILL_DATASET_AUTHENTICATED: + pw.print("DATASET_AUTHENTICATED"); break; + case MetricsEvent.AUTOFILL_INVALID_AUTHENTICATION: + pw.print("INVALID_AUTHENTICATION"); break; + case MetricsEvent.AUTOFILL_INVALID_DATASET_AUTHENTICATION: + pw.print("INVALID_DATASET_AUTHENTICATION"); break; + default: pw.print("UNSUPPORTED"); + } + pw.print('('); pw.print(authStatus); pw.print(')'); + } + dumpNumericValue(pw, log, "FC_IDS", + MetricsEvent.FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS); + dumpNumericValue(pw, log, "COMPAT_MODE", + MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE); + } + + private static void dumpNumericValue(@NonNull PrintWriter pw, @NonNull LogMaker log, + @NonNull String field, int tag) { + final int value = getNumericValue(log, tag); + if (value != 0) { + pw.print(", "); pw.print(field); pw.print('='); pw.print(value); + } + } + void autoFillApp(Dataset dataset) { synchronized (mLock) { if (mDestroyed) { @@ -2610,7 +2713,19 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mUi.destroyAll(mPendingSaveUi, this, true); mUi.clearCallback(this); mDestroyed = true; - writeLog(MetricsEvent.AUTOFILL_SESSION_FINISHED); + + // Log metrics + final int totalRequests = mRequestLogs.size(); + if (totalRequests > 0) { + if (sVerbose) Slog.v(TAG, "destroyLocked(): logging " + totalRequests + " requests"); + for (int i = 0; i < totalRequests; i++) { + final LogMaker log = mRequestLogs.valueAt(i); + mMetricsLogger.write(log); + } + } + mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_FINISHED) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUMBER_REQUESTS, totalRequests)); + return mRemoteFillService; } @@ -2727,6 +2842,29 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mMetricsLogger.write(newLogMaker(category)); } + private void logAuthenticationStatusLocked(int requestId, int status) { + addTaggedDataToRequestLogLocked(requestId, + MetricsEvent.FIELD_AUTOFILL_AUTHENTICATION_STATUS, status); + } + + private void addTaggedDataToRequestLogLocked(int requestId, int tag, @Nullable Object value) { + final LogMaker requestLog = mRequestLogs.get(requestId); + if (requestLog == null) { + Slog.w(TAG, + "addTaggedDataToRequestLogLocked(tag=" + tag + "): no log for id " + requestId); + return; + } + requestLog.addTaggedData(tag, value); + } + + private static String requestLogToString(@NonNull LogMaker log) { + final StringWriter sw = new StringWriter(); + final PrintWriter pw = new PrintWriter(sw); + dumpRequestLog(pw, log); + pw.flush(); + return sw.toString(); + } + private void wtf(@Nullable Exception e, String fmt, Object...args) { final String message = String.format(fmt, args); mWtfHistory.log(message); diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java index cff1a84ceafe..bb97e4a97c97 100644 --- a/services/autofill/java/com/android/server/autofill/ViewState.java +++ b/services/autofill/java/com/android/server/autofill/ViewState.java @@ -19,6 +19,7 @@ package com.android.server.autofill; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static com.android.server.autofill.Helper.sDebug; +import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Rect; import android.service.autofill.FillResponse; @@ -40,7 +41,7 @@ final class ViewState { /** * Called when the fill UI is ready to be shown for this view. */ - void onFillReady(FillResponse fillResponse, AutofillId focusedId, + void onFillReady(@NonNull FillResponse fillResponse, @NonNull AutofillId focusedId, @Nullable AutofillValue value); } |