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 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SESSION_COMMITTED;
21 import static com.android.server.autofill.Helper.sVerbose;
22 
23 import android.annotation.IntDef;
24 import android.content.ComponentName;
25 import android.content.Context;
26 import android.content.pm.PackageManager;
27 import android.provider.Settings;
28 import android.text.TextUtils;
29 import android.util.Slog;
30 import android.view.autofill.AutofillManager.AutofillCommitReason;
31 import com.android.internal.util.FrameworkStatsLog;
32 
33 import java.lang.annotation.Retention;
34 import java.lang.annotation.RetentionPolicy;
35 import java.util.Optional;
36 
37 /**
38  * Helper class to log Autofill session committed event stats.
39  */
40 public final class SessionCommittedEventLogger {
41   private static final String TAG = "SessionCommittedEventLogger";
42 
43   private final int mSessionId;
44   private Optional<SessionCommittedEventInternal> mEventInternal;
45 
SessionCommittedEventLogger(int sessionId)46   private SessionCommittedEventLogger(int sessionId) {
47     mSessionId = sessionId;
48     mEventInternal = Optional.of(new SessionCommittedEventInternal());
49   }
50 
51   /**
52    * A factory constructor to create SessionCommittedEventLogger.
53    */
forSessionId(int sessionId)54   public static SessionCommittedEventLogger forSessionId(int sessionId) {
55     return new SessionCommittedEventLogger(sessionId);
56   }
57 
58   /**
59    * Set component_package_uid as long as mEventInternal presents.
60    */
maybeSetComponentPackageUid(int val)61   public void maybeSetComponentPackageUid(int val) {
62     mEventInternal.ifPresent(event -> {
63       event.mComponentPackageUid = val;
64     });
65   }
66 
67   /**
68    * Set request_count as long as mEventInternal presents.
69    */
maybeSetRequestCount(int val)70   public void maybeSetRequestCount(int val) {
71     mEventInternal.ifPresent(event -> {
72       event.mRequestCount = val;
73     });
74   }
75 
76   /**
77    * Set commit_reason as long as mEventInternal presents.
78    */
maybeSetCommitReason(@utofillCommitReason int val)79   public void maybeSetCommitReason(@AutofillCommitReason int val) {
80     mEventInternal.ifPresent(event -> {
81         event.mCommitReason = val;
82     });
83   }
84 
85   /**
86    * Set session_duration_millis as long as mEventInternal presents.
87    */
maybeSetSessionDurationMillis(long timestamp)88   public void maybeSetSessionDurationMillis(long timestamp) {
89     mEventInternal.ifPresent(event -> {
90       event.mSessionDurationMillis = timestamp;
91     });
92   }
93 
94   /**
95    * Log an AUTOFILL_SESSION_COMMITTED event.
96    */
logAndEndEvent()97   public void logAndEndEvent() {
98     if (!mEventInternal.isPresent()) {
99       Slog.w(TAG, "Shouldn't be logging AutofillSessionCommitted again for same session.");
100       return;
101     }
102     SessionCommittedEventInternal event = mEventInternal.get();
103     if (sVerbose) {
104       Slog.v(TAG, "Log AutofillSessionCommitted:"
105           + " sessionId=" + mSessionId
106           + " mComponentPackageUid=" + event.mComponentPackageUid
107           + " mRequestCount=" + event.mRequestCount
108           + " mCommitReason=" + event.mCommitReason
109           + " mSessionDurationMillis=" + event.mSessionDurationMillis);
110     }
111     FrameworkStatsLog.write(
112         AUTOFILL_SESSION_COMMITTED,
113         mSessionId,
114         event.mComponentPackageUid,
115         event.mRequestCount,
116         event.mCommitReason,
117         event.mSessionDurationMillis);
118     mEventInternal = Optional.empty();
119   }
120 
121   private static final class SessionCommittedEventInternal {
122     int mComponentPackageUid = -1;
123     int mRequestCount = 0;
124     int mCommitReason = COMMIT_REASON_UNKNOWN;
125     long mSessionDurationMillis = 0;
126 
SessionCommittedEventInternal()127     SessionCommittedEventInternal() {
128     }
129   }
130 }
131