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