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.credentials.metrics;
18 
19 import java.util.LinkedHashMap;
20 import java.util.Map;
21 
22 /**
23  * This handles metrics collected prior to any remote calls to providers.
24  * Some types are redundant across these metric collectors, but that has debug use-cases as
25  * these data-types are available at different moments of the flow (and typically, one can feed
26  * into the next).
27  */
28 public class InitialPhaseMetric {
29     private static final String TAG = "InitialPhaseMetric";
30 
31     // The api being called, default set to unknown
32     private int mApiName = ApiName.UNKNOWN.getMetricCode();
33     // The caller uid of the calling application, default to -1
34     private int mCallerUid = -1;
35     // The session id to unite multiple atom emits
36     private final int mSessionIdCaller;
37 
38     // Raw timestamps in nanoseconds, *the only* one logged as such (i.e. 64 bits) since it is a
39     // reference point.
40     private long mCredentialServiceStartedTimeNanoseconds = -1;
41 
42     // A reference point to give this object utility to capture latency. Can be directly handed
43     // over to the next latency object.
44     private long mCredentialServiceBeginQueryTimeNanoseconds = -1;
45 
46     // Indicates if the origin was specified when making this API request
47     private boolean mOriginSpecified = false;
48 
49     // Stores the deduped request information, particularly {"req":5}
50     private Map<String, Integer> mRequestCounts = new LinkedHashMap<>();
51 
52     // The session id of autofill if the request is from autofill, defaults to -1
53     private int mAutofillSessionId = -1;
54 
55     // The request id of autofill if the request is from autofill, defaults to -1
56     private int mAutofillRequestId = -1;
57 
58 
InitialPhaseMetric(int sessionIdTrackOne)59     public InitialPhaseMetric(int sessionIdTrackOne) {
60         mSessionIdCaller = sessionIdTrackOne;
61     }
62 
63     /* ---------- Latencies ---------- */
64 
65     /* -- Direct Latency Utility -- */
66 
getServiceStartToQueryLatencyMicroseconds()67     public int getServiceStartToQueryLatencyMicroseconds() {
68         return (int) ((mCredentialServiceStartedTimeNanoseconds
69                 - mCredentialServiceBeginQueryTimeNanoseconds) / 1000);
70     }
71 
72     /* -- Timestamps -- */
73 
setCredentialServiceStartedTimeNanoseconds( long credentialServiceStartedTimeNanoseconds )74     public void setCredentialServiceStartedTimeNanoseconds(
75             long credentialServiceStartedTimeNanoseconds
76     ) {
77         mCredentialServiceStartedTimeNanoseconds = credentialServiceStartedTimeNanoseconds;
78     }
79 
setCredentialServiceBeginQueryTimeNanoseconds( long credentialServiceBeginQueryTimeNanoseconds)80     public void setCredentialServiceBeginQueryTimeNanoseconds(
81             long credentialServiceBeginQueryTimeNanoseconds) {
82         mCredentialServiceBeginQueryTimeNanoseconds = credentialServiceBeginQueryTimeNanoseconds;
83     }
84 
getCredentialServiceStartedTimeNanoseconds()85     public long getCredentialServiceStartedTimeNanoseconds() {
86         return mCredentialServiceStartedTimeNanoseconds;
87     }
88 
getCredentialServiceBeginQueryTimeNanoseconds()89     public long getCredentialServiceBeginQueryTimeNanoseconds() {
90         return mCredentialServiceBeginQueryTimeNanoseconds;
91     }
92 
93     /* ------ ApiName ------ */
94 
setApiName(int apiName)95     public void setApiName(int apiName) {
96         mApiName = apiName;
97     }
98 
getApiName()99     public int getApiName() {
100         return mApiName;
101     }
102 
103     /* ------ CallerUid ------ */
104 
setCallerUid(int callerUid)105     public void setCallerUid(int callerUid) {
106         mCallerUid = callerUid;
107     }
108 
getCallerUid()109     public int getCallerUid() {
110         return mCallerUid;
111     }
112 
113     /* ------ SessionId ------ */
114 
getSessionIdCaller()115     public int getSessionIdCaller() {
116         return mSessionIdCaller;
117     }
118 
119     /* ------ Count Request Class Types ------ */
120 
getCountRequestClassType()121     public int getCountRequestClassType() {
122         return mRequestCounts.size();
123     }
124 
125     /* ------ Origin Specified ------ */
126 
setOriginSpecified(boolean originSpecified)127     public void setOriginSpecified(boolean originSpecified) {
128         mOriginSpecified = originSpecified;
129     }
130 
isOriginSpecified()131     public boolean isOriginSpecified() {
132         return mOriginSpecified;
133     }
134 
135     /* ------ Autofill Integration ------ */
136 
setAutofillSessionId(int autofillSessionId)137     public void setAutofillSessionId(int autofillSessionId) {
138         mAutofillSessionId = autofillSessionId;
139     }
140 
getAutofillSessionId()141     public int getAutofillSessionId() {
142         return mAutofillSessionId;
143     }
144 
setAutofillRequestId(int autofillRequestId)145     public void setAutofillRequestId(int autofillRequestId) {
146         mAutofillRequestId = autofillRequestId;
147     }
148 
getAutofillRequestId()149     public int getAutofillRequestId() {
150         return mAutofillRequestId;
151     }
152 
153     /* ------ Unique Request Counts Map Information ------ */
154 
setRequestCounts(Map<String, Integer> requestCounts)155     public void setRequestCounts(Map<String, Integer> requestCounts) {
156         mRequestCounts = requestCounts;
157     }
158 
159     /**
160      * Returns the unique, deduped, request classtypes for logging.
161      * @return a string array for deduped classtypes
162      */
getUniqueRequestStrings()163     public String[] getUniqueRequestStrings() {
164         String[] result = new String[mRequestCounts.keySet().size()];
165         mRequestCounts.keySet().toArray(result);
166         return result;
167     }
168 
169     /**
170      * Returns the unique, deduped, request classtype counts for logging.
171      * @return a string array for deduped classtype counts
172      */
getUniqueRequestCounts()173     public int[] getUniqueRequestCounts() {
174         return mRequestCounts.values().stream().mapToInt(Integer::intValue).toArray();
175     }
176 }
177