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 
InitialPhaseMetric(int sessionIdTrackOne)53     public InitialPhaseMetric(int sessionIdTrackOne) {
54         mSessionIdCaller = sessionIdTrackOne;
55     }
56 
57     /* ---------- Latencies ---------- */
58 
59     /* -- Direct Latency Utility -- */
60 
getServiceStartToQueryLatencyMicroseconds()61     public int getServiceStartToQueryLatencyMicroseconds() {
62         return (int) ((mCredentialServiceStartedTimeNanoseconds
63                 - mCredentialServiceBeginQueryTimeNanoseconds) / 1000);
64     }
65 
66     /* -- Timestamps -- */
67 
setCredentialServiceStartedTimeNanoseconds( long credentialServiceStartedTimeNanoseconds )68     public void setCredentialServiceStartedTimeNanoseconds(
69             long credentialServiceStartedTimeNanoseconds
70     ) {
71         mCredentialServiceStartedTimeNanoseconds = credentialServiceStartedTimeNanoseconds;
72     }
73 
setCredentialServiceBeginQueryTimeNanoseconds( long credentialServiceBeginQueryTimeNanoseconds)74     public void setCredentialServiceBeginQueryTimeNanoseconds(
75             long credentialServiceBeginQueryTimeNanoseconds) {
76         mCredentialServiceBeginQueryTimeNanoseconds = credentialServiceBeginQueryTimeNanoseconds;
77     }
78 
getCredentialServiceStartedTimeNanoseconds()79     public long getCredentialServiceStartedTimeNanoseconds() {
80         return mCredentialServiceStartedTimeNanoseconds;
81     }
82 
getCredentialServiceBeginQueryTimeNanoseconds()83     public long getCredentialServiceBeginQueryTimeNanoseconds() {
84         return mCredentialServiceBeginQueryTimeNanoseconds;
85     }
86 
87     /* ------ ApiName ------ */
88 
setApiName(int apiName)89     public void setApiName(int apiName) {
90         mApiName = apiName;
91     }
92 
getApiName()93     public int getApiName() {
94         return mApiName;
95     }
96 
97     /* ------ CallerUid ------ */
98 
setCallerUid(int callerUid)99     public void setCallerUid(int callerUid) {
100         mCallerUid = callerUid;
101     }
102 
getCallerUid()103     public int getCallerUid() {
104         return mCallerUid;
105     }
106 
107     /* ------ SessionId ------ */
108 
getSessionIdCaller()109     public int getSessionIdCaller() {
110         return mSessionIdCaller;
111     }
112 
113     /* ------ Count Request Class Types ------ */
114 
getCountRequestClassType()115     public int getCountRequestClassType() {
116         return mRequestCounts.size();
117     }
118 
119     /* ------ Origin Specified ------ */
120 
setOriginSpecified(boolean originSpecified)121     public void setOriginSpecified(boolean originSpecified) {
122         mOriginSpecified = originSpecified;
123     }
124 
isOriginSpecified()125     public boolean isOriginSpecified() {
126         return mOriginSpecified;
127     }
128 
129     /* ------ Unique Request Counts Map Information ------ */
130 
setRequestCounts(Map<String, Integer> requestCounts)131     public void setRequestCounts(Map<String, Integer> requestCounts) {
132         mRequestCounts = requestCounts;
133     }
134 
135     /**
136      * Returns the unique, deduped, request classtypes for logging.
137      * @return a string array for deduped classtypes
138      */
getUniqueRequestStrings()139     public String[] getUniqueRequestStrings() {
140         String[] result = new String[mRequestCounts.keySet().size()];
141         mRequestCounts.keySet().toArray(result);
142         return result;
143     }
144 
145     /**
146      * Returns the unique, deduped, request classtype counts for logging.
147      * @return a string array for deduped classtype counts
148      */
getUniqueRequestCounts()149     public int[] getUniqueRequestCounts() {
150         return mRequestCounts.values().stream().mapToInt(Integer::intValue).toArray();
151     }
152 }
153