Loading services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java +70 −22 Original line number Diff line number Diff line Loading @@ -295,6 +295,38 @@ public final class PresentationStatsEventLogger { }); } /** * Called for inline suggestions - inflated one at * a time. If InlineSuggestions were filtered, * reset the count be incrementing */ public void maybeIncrementCountShown() { mEventInternal.ifPresent(event -> { if (event.shouldResetShownCount) { event.shouldResetShownCount = false; event.mCountShown = 0; } if (event.mCountShown == 0) { // The first time suggestions are rendered // set time stamp maybeSetSuggestionPresentedTimestampMs(); } event.mCountShown += 1; }); } /** * Call this when UI is hidden. This will set a flag to reset count for inline. We do this * instead of resetting right away in case there are 0 inline presentations after. */ public void markShownCountAsResettable() { mEventInternal.ifPresent(event -> { event.shouldResetShownCount = true; }); } public void maybeSetCountShown(@Nullable List<Dataset> datasetList, AutofillId currentViewId) { mEventInternal.ifPresent(event -> { Loading @@ -306,6 +338,13 @@ public final class PresentationStatsEventLogger { }); } public void maybeSetCountShown(int datasets) { mEventInternal.ifPresent( event -> { event.mCountShown = datasets; }); } private static CountContainer getDatasetCountForAutofillId(@Nullable List<Dataset> datasetList, AutofillId currentViewId) { Loading Loading @@ -567,30 +606,35 @@ public final class PresentationStatsEventLogger { * <p>If the ViewState contains ViewState.STATE_AUTOFILLED, sets field_autofilled_timestamp_ms * else, set field_first_modified_timestamp_ms (if unset) and field_last_modified_timestamp_ms */ public void onFieldTextUpdated(ViewState state) { mEventInternal.ifPresent( event -> { public void onFieldTextUpdated(ViewState state, int length) { mEventInternal.ifPresent(event -> { int timestamp = getElapsedTime(); // Focused id should be set before this is called if (state.id != null && state.id.getViewId() != event.mFocusedId) { if (state == null || state.id == null || state.id.getViewId() != event.mFocusedId) { // if these don't match, the currently field different than before Slog.w( TAG, "current id: " + state.id.getViewId() + " is different than focused id: " + event.mFocusedId); "Bad view state for: " + event.mFocusedId); return; } // Text changed because filling into form, just log Autofill timestamp if ((state.getState() & ViewState.STATE_AUTOFILLED) != 0) { event.mAutofilledTimestampMs = timestamp; } else { return; } // Set length variables if (event.mFieldFirstLength == DEFAULT_VALUE_INT) { event.mFieldFirstLength = length; } event.mFieldLastLength = length; // Set timestamp variables if (event.mFieldModifiedFirstTimestampMs == DEFAULT_VALUE_INT) { event.mFieldModifiedFirstTimestampMs = timestamp; } event.mFieldModifiedLastTimestampMs = timestamp; } }); } Loading Loading @@ -661,15 +705,16 @@ public final class PresentationStatsEventLogger { /** Sets focused_autofill_id using view id */ public void maybeSetFocusedId(AutofillId id) { maybeSetFocusedId(id.getViewId()); mEventInternal.ifPresent( event -> { event.mFocusedId = id.getViewId(); if (id.isVirtualInt()) { event.mFocusedVirtualAutofillId = id.getVirtualChildIntId() % 100; } /** Sets focused_autofill_id as long as mEventInternal is present */ public void maybeSetFocusedId(int id) { mEventInternal.ifPresent(event -> { event.mFocusedId = id; }); } /** * Set views_filled_failure_count using failure count as long as mEventInternal * presents. Loading Loading @@ -823,7 +868,7 @@ public final class PresentationStatsEventLogger { @NotShownReason int mNoPresentationReason = NOT_SHOWN_REASON_UNKNOWN; boolean mIsDatasetAvailable; int mAvailableCount; int mCountShown; int mCountShown = 0; int mCountFilteredUserTyping; int mCountNotShownImePresentationNotDrawn; int mCountNotShownImeUserNotSeen; Loading Loading @@ -870,6 +915,9 @@ public final class PresentationStatsEventLogger { ArraySet<AutofillId> mAutofillIdsAttemptedAutofill; ArraySet<AutofillId> mAlreadyFilledAutofillIds = new ArraySet<>(); // Not logged - used for internal logic boolean shouldResetShownCount = false; PresentationStatsEventInternal() {} } Loading services/autofill/java/com/android/server/autofill/Session.java +22 −21 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import static android.service.autofill.Dataset.PICK_REASON_UNKNOWN; import static android.service.autofill.FillEventHistory.Event.UI_TYPE_CREDMAN_BOTTOM_SHEET; import static android.service.autofill.FillEventHistory.Event.UI_TYPE_DIALOG; import static android.service.autofill.FillEventHistory.Event.UI_TYPE_INLINE; import static android.service.autofill.FillEventHistory.Event.UI_TYPE_MENU; import static android.service.autofill.FillEventHistory.Event.UI_TYPE_UNKNOWN; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE; Loading Loading @@ -2661,19 +2660,30 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // AutofillUiCallback @Override public void onShown(int uiType) { public void onShown(int uiType, int numDatasetsShown) { synchronized (mLock) { mPresentationStatsEventLogger.maybeSetDisplayPresentationType(uiType); if (uiType == UI_TYPE_INLINE) { if (mLoggedInlineDatasetShown) { // Inline Suggestions are inflated one at a time // This number will be reset when filtered // This will also call maybeSetSuggestionPresentedTimestampMs mPresentationStatsEventLogger.maybeIncrementCountShown(); if (!mLoggedInlineDatasetShown) { // Chip inflation already logged, do not log again. // This is needed because every chip inflation will call this. return; mService.logDatasetShown(this.id, mClientState, uiType); Slog.d(TAG, "onShown(): " + uiType + ", " + numDatasetsShown); } mLoggedInlineDatasetShown = true; } mService.logDatasetShown(this.id, mClientState, uiType); } else { mPresentationStatsEventLogger.maybeSetCountShown(numDatasetsShown); // Explicitly sets maybeSetSuggestionPresentedTimestampMs mPresentationStatsEventLogger.maybeSetSuggestionPresentedTimestampMs(); Slog.d(TAG, "onShown(): " + uiType); mService.logDatasetShown(this.id, mClientState, uiType); Slog.d(TAG, "onShown(): " + uiType + ", " + numDatasetsShown); } } } Loading Loading @@ -2739,6 +2749,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } mInlineSessionController.hideInlineSuggestionsUiLocked(id); mPresentationStatsEventLogger.markShownCountAsResettable(); } } Loading Loading @@ -4868,7 +4879,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState currentView.maybeCallOnFillReady(flags); } } mPresentationStatsEventLogger.onFieldTextUpdated(viewState); if (textValue != null) { mPresentationStatsEventLogger.onFieldTextUpdated(viewState, textValue.length()); } if (viewState.id.equals(this.mCurrentViewId) && (viewState.getState() & ViewState.STATE_INLINE_SHOWN) != 0) { Loading Loading @@ -4965,8 +4978,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState synchronized (mLock) { final ViewState currentView = mViewStates.get(mCurrentViewId); currentView.setState(ViewState.STATE_FILL_DIALOG_SHOWN); mPresentationStatsEventLogger.maybeSetCountShown( response.getDatasets(), mCurrentViewId); mPresentationStatsEventLogger.maybeSetDisplayPresentationType(UI_TYPE_DIALOG); } // Just show fill dialog once, so disabled after shown. Loading @@ -4987,10 +4998,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // back a response via callback. final ViewState currentView = mViewStates.get(mCurrentViewId); currentView.setState(ViewState.STATE_INLINE_SHOWN); // TODO(b/234475358): Log more accurate value of number of inline suggestions // shown, inflated, and filtered. mPresentationStatsEventLogger.maybeSetCountShown( response.getDatasets(), mCurrentViewId); mPresentationStatsEventLogger.maybeSetInlinePresentationAndSuggestionHostUid( mContext, userId); return; Loading @@ -5003,12 +5010,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState serviceLabel, serviceIcon, this, mContext, id, mCompatMode, mService.getMaster().getMaxInputLengthForAutofill()); synchronized (mLock) { mPresentationStatsEventLogger.maybeSetCountShown( response.getDatasets(), mCurrentViewId); mPresentationStatsEventLogger.maybeSetDisplayPresentationType(UI_TYPE_MENU); } synchronized (mLock) { if (mUiShownTime == 0) { // Log first time UI is shown. Loading Loading @@ -5249,7 +5250,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @Override public void onInflate() { Session.this.onShown(UI_TYPE_INLINE); Session.this.onShown(UI_TYPE_INLINE, 1); } }, mService.getMaster().getMaxInputLengthForAutofill()); return mInlineSessionController.setInlineFillUiLocked(inlineFillUi); Loading services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java +4 −4 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ public final class AutoFillUI { void cancelSession(); void requestShowSoftInput(AutofillId id); void requestFallbackFromFillDialog(); void onShown(int uiType); void onShown(int uiType, int datasetSize); } public AutoFillUI(@NonNull Context context) { Loading Loading @@ -246,9 +246,9 @@ public final class AutoFillUI { } @Override public void onShown() { public void onShown(int datasetSize) { if (mCallback != null) { mCallback.onShown(UI_TYPE_MENU); mCallback.onShown(UI_TYPE_MENU, datasetSize); } } Loading Loading @@ -462,7 +462,7 @@ public final class AutoFillUI { @Override public void onShown() { callback.onShown(UI_TYPE_DIALOG); mCallback.onShown(UI_TYPE_DIALOG, response.getDatasets().size()); } @Override Loading services/autofill/java/com/android/server/autofill/ui/FillUi.java +4 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.autofill.ui; import static android.service.autofill.FillResponse.FLAG_CREDENTIAL_MANAGER_RESPONSE; import static com.android.server.autofill.Helper.paramsToString; import static com.android.server.autofill.Helper.sDebug; import static com.android.server.autofill.Helper.sFullScreenMode; Loading Loading @@ -90,7 +91,7 @@ final class FillUi { void onDatasetPicked(@NonNull Dataset dataset); void onCanceled(); void onDestroy(); void onShown(); void onShown(int datasetSize); void requestShowFillUi(int width, int height, IAutofillWindowPresenter windowPresenter); void requestHideFillUi(); Loading Loading @@ -742,7 +743,8 @@ final class FillUi { mWm.addView(mContentView, params); mOverlayControl.hideOverlays(); mShowing = true; mCallback.onShown(); int numShownDatasets = (mAdapter == null) ? 0 : mAdapter.getCount(); mCallback.onShown(numShownDatasets); } else { mWm.updateViewLayout(mContentView, params); } Loading Loading
services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java +70 −22 Original line number Diff line number Diff line Loading @@ -295,6 +295,38 @@ public final class PresentationStatsEventLogger { }); } /** * Called for inline suggestions - inflated one at * a time. If InlineSuggestions were filtered, * reset the count be incrementing */ public void maybeIncrementCountShown() { mEventInternal.ifPresent(event -> { if (event.shouldResetShownCount) { event.shouldResetShownCount = false; event.mCountShown = 0; } if (event.mCountShown == 0) { // The first time suggestions are rendered // set time stamp maybeSetSuggestionPresentedTimestampMs(); } event.mCountShown += 1; }); } /** * Call this when UI is hidden. This will set a flag to reset count for inline. We do this * instead of resetting right away in case there are 0 inline presentations after. */ public void markShownCountAsResettable() { mEventInternal.ifPresent(event -> { event.shouldResetShownCount = true; }); } public void maybeSetCountShown(@Nullable List<Dataset> datasetList, AutofillId currentViewId) { mEventInternal.ifPresent(event -> { Loading @@ -306,6 +338,13 @@ public final class PresentationStatsEventLogger { }); } public void maybeSetCountShown(int datasets) { mEventInternal.ifPresent( event -> { event.mCountShown = datasets; }); } private static CountContainer getDatasetCountForAutofillId(@Nullable List<Dataset> datasetList, AutofillId currentViewId) { Loading Loading @@ -567,30 +606,35 @@ public final class PresentationStatsEventLogger { * <p>If the ViewState contains ViewState.STATE_AUTOFILLED, sets field_autofilled_timestamp_ms * else, set field_first_modified_timestamp_ms (if unset) and field_last_modified_timestamp_ms */ public void onFieldTextUpdated(ViewState state) { mEventInternal.ifPresent( event -> { public void onFieldTextUpdated(ViewState state, int length) { mEventInternal.ifPresent(event -> { int timestamp = getElapsedTime(); // Focused id should be set before this is called if (state.id != null && state.id.getViewId() != event.mFocusedId) { if (state == null || state.id == null || state.id.getViewId() != event.mFocusedId) { // if these don't match, the currently field different than before Slog.w( TAG, "current id: " + state.id.getViewId() + " is different than focused id: " + event.mFocusedId); "Bad view state for: " + event.mFocusedId); return; } // Text changed because filling into form, just log Autofill timestamp if ((state.getState() & ViewState.STATE_AUTOFILLED) != 0) { event.mAutofilledTimestampMs = timestamp; } else { return; } // Set length variables if (event.mFieldFirstLength == DEFAULT_VALUE_INT) { event.mFieldFirstLength = length; } event.mFieldLastLength = length; // Set timestamp variables if (event.mFieldModifiedFirstTimestampMs == DEFAULT_VALUE_INT) { event.mFieldModifiedFirstTimestampMs = timestamp; } event.mFieldModifiedLastTimestampMs = timestamp; } }); } Loading Loading @@ -661,15 +705,16 @@ public final class PresentationStatsEventLogger { /** Sets focused_autofill_id using view id */ public void maybeSetFocusedId(AutofillId id) { maybeSetFocusedId(id.getViewId()); mEventInternal.ifPresent( event -> { event.mFocusedId = id.getViewId(); if (id.isVirtualInt()) { event.mFocusedVirtualAutofillId = id.getVirtualChildIntId() % 100; } /** Sets focused_autofill_id as long as mEventInternal is present */ public void maybeSetFocusedId(int id) { mEventInternal.ifPresent(event -> { event.mFocusedId = id; }); } /** * Set views_filled_failure_count using failure count as long as mEventInternal * presents. Loading Loading @@ -823,7 +868,7 @@ public final class PresentationStatsEventLogger { @NotShownReason int mNoPresentationReason = NOT_SHOWN_REASON_UNKNOWN; boolean mIsDatasetAvailable; int mAvailableCount; int mCountShown; int mCountShown = 0; int mCountFilteredUserTyping; int mCountNotShownImePresentationNotDrawn; int mCountNotShownImeUserNotSeen; Loading Loading @@ -870,6 +915,9 @@ public final class PresentationStatsEventLogger { ArraySet<AutofillId> mAutofillIdsAttemptedAutofill; ArraySet<AutofillId> mAlreadyFilledAutofillIds = new ArraySet<>(); // Not logged - used for internal logic boolean shouldResetShownCount = false; PresentationStatsEventInternal() {} } Loading
services/autofill/java/com/android/server/autofill/Session.java +22 −21 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import static android.service.autofill.Dataset.PICK_REASON_UNKNOWN; import static android.service.autofill.FillEventHistory.Event.UI_TYPE_CREDMAN_BOTTOM_SHEET; import static android.service.autofill.FillEventHistory.Event.UI_TYPE_DIALOG; import static android.service.autofill.FillEventHistory.Event.UI_TYPE_INLINE; import static android.service.autofill.FillEventHistory.Event.UI_TYPE_MENU; import static android.service.autofill.FillEventHistory.Event.UI_TYPE_UNKNOWN; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE; Loading Loading @@ -2661,19 +2660,30 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // AutofillUiCallback @Override public void onShown(int uiType) { public void onShown(int uiType, int numDatasetsShown) { synchronized (mLock) { mPresentationStatsEventLogger.maybeSetDisplayPresentationType(uiType); if (uiType == UI_TYPE_INLINE) { if (mLoggedInlineDatasetShown) { // Inline Suggestions are inflated one at a time // This number will be reset when filtered // This will also call maybeSetSuggestionPresentedTimestampMs mPresentationStatsEventLogger.maybeIncrementCountShown(); if (!mLoggedInlineDatasetShown) { // Chip inflation already logged, do not log again. // This is needed because every chip inflation will call this. return; mService.logDatasetShown(this.id, mClientState, uiType); Slog.d(TAG, "onShown(): " + uiType + ", " + numDatasetsShown); } mLoggedInlineDatasetShown = true; } mService.logDatasetShown(this.id, mClientState, uiType); } else { mPresentationStatsEventLogger.maybeSetCountShown(numDatasetsShown); // Explicitly sets maybeSetSuggestionPresentedTimestampMs mPresentationStatsEventLogger.maybeSetSuggestionPresentedTimestampMs(); Slog.d(TAG, "onShown(): " + uiType); mService.logDatasetShown(this.id, mClientState, uiType); Slog.d(TAG, "onShown(): " + uiType + ", " + numDatasetsShown); } } } Loading Loading @@ -2739,6 +2749,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } mInlineSessionController.hideInlineSuggestionsUiLocked(id); mPresentationStatsEventLogger.markShownCountAsResettable(); } } Loading Loading @@ -4868,7 +4879,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState currentView.maybeCallOnFillReady(flags); } } mPresentationStatsEventLogger.onFieldTextUpdated(viewState); if (textValue != null) { mPresentationStatsEventLogger.onFieldTextUpdated(viewState, textValue.length()); } if (viewState.id.equals(this.mCurrentViewId) && (viewState.getState() & ViewState.STATE_INLINE_SHOWN) != 0) { Loading Loading @@ -4965,8 +4978,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState synchronized (mLock) { final ViewState currentView = mViewStates.get(mCurrentViewId); currentView.setState(ViewState.STATE_FILL_DIALOG_SHOWN); mPresentationStatsEventLogger.maybeSetCountShown( response.getDatasets(), mCurrentViewId); mPresentationStatsEventLogger.maybeSetDisplayPresentationType(UI_TYPE_DIALOG); } // Just show fill dialog once, so disabled after shown. Loading @@ -4987,10 +4998,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // back a response via callback. final ViewState currentView = mViewStates.get(mCurrentViewId); currentView.setState(ViewState.STATE_INLINE_SHOWN); // TODO(b/234475358): Log more accurate value of number of inline suggestions // shown, inflated, and filtered. mPresentationStatsEventLogger.maybeSetCountShown( response.getDatasets(), mCurrentViewId); mPresentationStatsEventLogger.maybeSetInlinePresentationAndSuggestionHostUid( mContext, userId); return; Loading @@ -5003,12 +5010,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState serviceLabel, serviceIcon, this, mContext, id, mCompatMode, mService.getMaster().getMaxInputLengthForAutofill()); synchronized (mLock) { mPresentationStatsEventLogger.maybeSetCountShown( response.getDatasets(), mCurrentViewId); mPresentationStatsEventLogger.maybeSetDisplayPresentationType(UI_TYPE_MENU); } synchronized (mLock) { if (mUiShownTime == 0) { // Log first time UI is shown. Loading Loading @@ -5249,7 +5250,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @Override public void onInflate() { Session.this.onShown(UI_TYPE_INLINE); Session.this.onShown(UI_TYPE_INLINE, 1); } }, mService.getMaster().getMaxInputLengthForAutofill()); return mInlineSessionController.setInlineFillUiLocked(inlineFillUi); Loading
services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java +4 −4 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ public final class AutoFillUI { void cancelSession(); void requestShowSoftInput(AutofillId id); void requestFallbackFromFillDialog(); void onShown(int uiType); void onShown(int uiType, int datasetSize); } public AutoFillUI(@NonNull Context context) { Loading Loading @@ -246,9 +246,9 @@ public final class AutoFillUI { } @Override public void onShown() { public void onShown(int datasetSize) { if (mCallback != null) { mCallback.onShown(UI_TYPE_MENU); mCallback.onShown(UI_TYPE_MENU, datasetSize); } } Loading Loading @@ -462,7 +462,7 @@ public final class AutoFillUI { @Override public void onShown() { callback.onShown(UI_TYPE_DIALOG); mCallback.onShown(UI_TYPE_DIALOG, response.getDatasets().size()); } @Override Loading
services/autofill/java/com/android/server/autofill/ui/FillUi.java +4 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.autofill.ui; import static android.service.autofill.FillResponse.FLAG_CREDENTIAL_MANAGER_RESPONSE; import static com.android.server.autofill.Helper.paramsToString; import static com.android.server.autofill.Helper.sDebug; import static com.android.server.autofill.Helper.sFullScreenMode; Loading Loading @@ -90,7 +91,7 @@ final class FillUi { void onDatasetPicked(@NonNull Dataset dataset); void onCanceled(); void onDestroy(); void onShown(); void onShown(int datasetSize); void requestShowFillUi(int width, int height, IAutofillWindowPresenter windowPresenter); void requestHideFillUi(); Loading Loading @@ -742,7 +743,8 @@ final class FillUi { mWm.addView(mContentView, params); mOverlayControl.hideOverlays(); mShowing = true; mCallback.onShown(); int numShownDatasets = (mAdapter == null) ? 0 : mAdapter.getCount(); mCallback.onShown(numShownDatasets); } else { mWm.updateViewLayout(mContentView, params); } Loading