1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.autofill; 18 19 import static android.view.autofill.AutofillManager.COMMIT_REASON_UNKNOWN; 20 21 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SESSION_COMMITTED; 22 import static com.android.server.autofill.Helper.sVerbose; 23 24 import android.util.Slog; 25 import android.view.autofill.AutofillManager.AutofillCommitReason; 26 27 import com.android.internal.util.FrameworkStatsLog; 28 29 import java.util.Optional; 30 31 /** 32 * Helper class to log Autofill session committed event stats. 33 */ 34 public final class SessionCommittedEventLogger { 35 private static final String TAG = "SessionCommittedEventLogger"; 36 37 private final int mSessionId; 38 private Optional<SessionCommittedEventInternal> mEventInternal; 39 SessionCommittedEventLogger(int sessionId)40 private SessionCommittedEventLogger(int sessionId) { 41 mSessionId = sessionId; 42 mEventInternal = Optional.of(new SessionCommittedEventInternal()); 43 } 44 45 /** 46 * A factory constructor to create SessionCommittedEventLogger. 47 */ forSessionId(int sessionId)48 public static SessionCommittedEventLogger forSessionId(int sessionId) { 49 return new SessionCommittedEventLogger(sessionId); 50 } 51 52 /** 53 * Set component_package_uid as long as mEventInternal presents. 54 */ maybeSetComponentPackageUid(int val)55 public void maybeSetComponentPackageUid(int val) { 56 mEventInternal.ifPresent(event -> { 57 event.mComponentPackageUid = val; 58 }); 59 } 60 61 /** 62 * Set request_count as long as mEventInternal presents. 63 */ maybeSetRequestCount(int val)64 public void maybeSetRequestCount(int val) { 65 mEventInternal.ifPresent(event -> { 66 event.mRequestCount = val; 67 }); 68 } 69 70 /** 71 * Set commit_reason as long as mEventInternal presents. 72 */ maybeSetCommitReason(@utofillCommitReason int val)73 public void maybeSetCommitReason(@AutofillCommitReason int val) { 74 mEventInternal.ifPresent(event -> { 75 event.mCommitReason = val; 76 }); 77 } 78 79 /** 80 * Set session_duration_millis as long as mEventInternal presents. 81 */ maybeSetSessionDurationMillis(long timestamp)82 public void maybeSetSessionDurationMillis(long timestamp) { 83 mEventInternal.ifPresent(event -> { 84 event.mSessionDurationMillis = timestamp; 85 }); 86 } 87 88 /** Set autofill_service_uid as long as mEventInternal presents. */ maybeSetAutofillServiceUid(int uid)89 public void maybeSetAutofillServiceUid(int uid) { 90 mEventInternal.ifPresent( 91 event -> { 92 event.mServiceUid = uid; 93 }); 94 } 95 96 /** 97 * Set how many save infos there are in current session as long as mEventInternal presents. 98 */ maybeSetSaveInfoCount(int saveInfoCount)99 public void maybeSetSaveInfoCount(int saveInfoCount) { 100 mEventInternal.ifPresent(event -> { 101 event.mSaveInfoCount = saveInfoCount; 102 }); 103 } 104 105 /** 106 * Set how many save data types there are in current session as long as mEventInternal presents. 107 */ maybeSetSaveDataTypeCount(int saveDataTypeCount)108 public void maybeSetSaveDataTypeCount(int saveDataTypeCount) { 109 mEventInternal.ifPresent(event -> { 110 event.mSaveDataTypeCount = saveDataTypeCount; 111 }); 112 } 113 114 /** 115 * Set whether last fill response in session has save info as long as mEventInternal presents. 116 */ maybeSetLastFillResponseHasSaveInfo(boolean lastFillResponseHasSaveInfo)117 public void maybeSetLastFillResponseHasSaveInfo(boolean lastFillResponseHasSaveInfo) { 118 mEventInternal.ifPresent(event -> { 119 event.mLastFillResponseHasSaveInfo = lastFillResponseHasSaveInfo; 120 }); 121 } 122 123 /** 124 * Log an AUTOFILL_SESSION_COMMITTED event. 125 */ logAndEndEvent()126 public void logAndEndEvent() { 127 if (!mEventInternal.isPresent()) { 128 Slog.w(TAG, "Shouldn't be logging AutofillSessionCommitted again for same session."); 129 return; 130 } 131 SessionCommittedEventInternal event = mEventInternal.get(); 132 if (sVerbose) { 133 Slog.v(TAG, "Log AutofillSessionCommitted:" 134 + " sessionId=" + mSessionId 135 + " mComponentPackageUid=" + event.mComponentPackageUid 136 + " mRequestCount=" + event.mRequestCount 137 + " mCommitReason=" + event.mCommitReason 138 + " mSessionDurationMillis=" + event.mSessionDurationMillis 139 + " mServiceUid=" + event.mServiceUid 140 + " mSaveInfoCount=" + event.mSaveInfoCount 141 + " mSaveDataTypeCount=" + event.mSaveDataTypeCount 142 + " mLastFillResponseHasSaveInfo=" + event.mLastFillResponseHasSaveInfo); 143 } 144 FrameworkStatsLog.write( 145 AUTOFILL_SESSION_COMMITTED, 146 mSessionId, 147 event.mComponentPackageUid, 148 event.mRequestCount, 149 event.mCommitReason, 150 event.mSessionDurationMillis, 151 event.mServiceUid, 152 event.mSaveInfoCount, 153 event.mSaveDataTypeCount, 154 event.mLastFillResponseHasSaveInfo); 155 mEventInternal = Optional.empty(); 156 } 157 158 private static final class SessionCommittedEventInternal { 159 int mComponentPackageUid = -1; 160 int mRequestCount = 0; 161 int mCommitReason = COMMIT_REASON_UNKNOWN; 162 long mSessionDurationMillis = 0; 163 int mSaveInfoCount = -1; 164 int mSaveDataTypeCount = -1; 165 boolean mLastFillResponseHasSaveInfo = false; 166 int mServiceUid = -1; 167 SessionCommittedEventInternal()168 SessionCommittedEventInternal() { 169 } 170 } 171 } 172