• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.util.Slog;
20 
21 import com.android.server.credentials.MetricUtilities;
22 import com.android.server.credentials.metrics.shared.ResponseCollective;
23 
24 import java.util.Map;
25 
26 /**
27  * The central chosen provider metric object that mimics our defined metric setup. This is used
28  * in the final phase of the flow and emits final status metrics.
29  * Some types are redundant across these metric collectors, but that has debug use-cases as
30  * these data-types are available at different moments of the flow (and typically, one can feed
31  * into the next).
32  */
33 public class ChosenProviderFinalPhaseMetric {
34     private static final String TAG = "ChosenFinalPhaseMetric";
35     // The session id associated with this API call, used to unite split emits, for the flow
36     // where we know the calling app
37     private final int mSessionIdCaller;
38     // The session id associated with this API call, used to unite split emits, for the flow
39     // where we know the provider apps
40     private final int mSessionIdProvider;
41     // Reveals if the UI was returned, false by default
42     private boolean mUiReturned = false;
43     private int mChosenUid = -1;
44 
45     // Latency figures typically fed in from prior CandidateProviderMetric
46 
47     private int mPreQueryPhaseLatencyMicroseconds = -1;
48     private int mQueryPhaseLatencyMicroseconds = -1;
49 
50     // Timestamps kept in raw nanoseconds. Expected to be converted to microseconds from using
51     // reference 'mServiceBeganTimeNanoseconds' during metric log point
52 
53     // Kept for local reference purposes, the initial timestamp of the service called passed in
54     private long mServiceBeganTimeNanoseconds = -1;
55     // The first query timestamp, which upon emit is normalized to microseconds using the reference
56     // start timestamp
57     private long mQueryStartTimeNanoseconds = -1;
58     // The timestamp at query end, which upon emit will be normalized to microseconds with reference
59     private long mQueryEndTimeNanoseconds = -1;
60     // The UI call timestamp, which upon emit will be normalized to microseconds using reference
61     private long mUiCallStartTimeNanoseconds = -1;
62     // The UI return timestamp, which upon emit will be normalized to microseconds using reference
63     private long mUiCallEndTimeNanoseconds = -1;
64     // The final finish timestamp, which upon emit will be normalized to microseconds with reference
65     private long mFinalFinishTimeNanoseconds = -1;
66     // The status of this provider after selection
67 
68     // Other General Information, such as final api status, provider status, entry info, etc...
69 
70     private int mOemUiUid = -1;
71     private int mFallbackUiUid = -1;
72     private OemUiUsageStatus mOemUiUsageStatus = OemUiUsageStatus.UNKNOWN;
73 
74     private int mChosenProviderStatus = -1;
75     // Indicates if an exception was thrown by this provider, false by default
76     private boolean mHasException = false;
77     // Indicates a framework only exception that occurs in the final phase of the flow
78     private String mFrameworkException = "";
79 
80     // Stores the response credential information, as well as the response entry information which
81     // by default, contains empty info
82     private ResponseCollective mResponseCollective = new ResponseCollective(Map.of(), Map.of());
83     // Indicates if this chosen provider was the primary provider, false by default
84     private boolean mIsPrimary = false;
85 
86     private String mChosenClassType = "";
87 
88 
ChosenProviderFinalPhaseMetric(int sessionIdCaller, int sessionIdProvider)89     public ChosenProviderFinalPhaseMetric(int sessionIdCaller, int sessionIdProvider) {
90         mSessionIdCaller = sessionIdCaller;
91         mSessionIdProvider = sessionIdProvider;
92     }
93 
94     /* ------------------- Chosen Credential ------------------- */
95 
setChosenClassType(String clickedClassType)96     public void setChosenClassType(String clickedClassType) {
97         mChosenClassType = clickedClassType;
98     }
99 
getChosenClassType()100     public String getChosenClassType() {
101         return mChosenClassType;
102     }
103 
104     /* ------------------- UID ------------------- */
105 
getChosenUid()106     public int getChosenUid() {
107         return mChosenUid;
108     }
109 
setChosenUid(int chosenUid)110     public void setChosenUid(int chosenUid) {
111         mChosenUid = chosenUid;
112     }
113 
114     /* ---------------- Latencies ------------------ */
115 
116 
117     /* ----- Direct Delta Latencies for Local Utility ------- */
118 
119     /**
120      * In order for a chosen provider to be selected, the call must have successfully begun.
121      * Thus, the {@link InitialPhaseMetric} can directly pass this initial latency figure into
122      * this chosen provider metric.
123      *
124      * @param preQueryPhaseLatencyMicroseconds the millisecond latency for the service start,
125      *                                         typically passed in through the
126      *                                         {@link InitialPhaseMetric}
127      */
setPreQueryPhaseLatencyMicroseconds(int preQueryPhaseLatencyMicroseconds)128     public void setPreQueryPhaseLatencyMicroseconds(int preQueryPhaseLatencyMicroseconds) {
129         mPreQueryPhaseLatencyMicroseconds = preQueryPhaseLatencyMicroseconds;
130     }
131 
132     /**
133      * In order for a chosen provider to be selected, a candidate provider must exist. The
134      * candidate provider can directly pass the final latency figure into this chosen provider
135      * metric.
136      *
137      * @param queryPhaseLatencyMicroseconds the millisecond latency for the query phase, typically
138      *                                      passed in through the {@link CandidatePhaseMetric}
139      */
setQueryPhaseLatencyMicroseconds(int queryPhaseLatencyMicroseconds)140     public void setQueryPhaseLatencyMicroseconds(int queryPhaseLatencyMicroseconds) {
141         mQueryPhaseLatencyMicroseconds = queryPhaseLatencyMicroseconds;
142     }
143 
getPreQueryPhaseLatencyMicroseconds()144     public int getPreQueryPhaseLatencyMicroseconds() {
145         return mPreQueryPhaseLatencyMicroseconds;
146     }
147 
getQueryPhaseLatencyMicroseconds()148     public int getQueryPhaseLatencyMicroseconds() {
149         return mQueryPhaseLatencyMicroseconds;
150     }
151 
getUiPhaseLatencyMicroseconds()152     public int getUiPhaseLatencyMicroseconds() {
153         return (int) ((mUiCallEndTimeNanoseconds
154                 - mUiCallStartTimeNanoseconds) / 1000);
155     }
156 
157     /**
158      * Returns the full provider (invocation to response) latency in microseconds. Expects the
159      * start time to be provided, such as from {@link CandidatePhaseMetric}.
160      */
getEntireProviderLatencyMicroseconds()161     public int getEntireProviderLatencyMicroseconds() {
162         return (int) ((mFinalFinishTimeNanoseconds
163                 - mQueryStartTimeNanoseconds) / 1000);
164     }
165 
166     /**
167      * Returns the full (platform invoked to response) latency in microseconds. Expects the
168      * start time to be provided, such as from {@link InitialPhaseMetric}.
169      */
getEntireLatencyMicroseconds()170     public int getEntireLatencyMicroseconds() {
171         return (int) ((mFinalFinishTimeNanoseconds
172                 - mServiceBeganTimeNanoseconds) / 1000);
173     }
174 
175     /* ----- Timestamps for Latency ----- */
176 
177     /**
178      * In order for a chosen provider to be selected, the call must have successfully begun.
179      * Thus, the {@link InitialPhaseMetric} can directly pass this initial timestamp into this
180      * chosen provider metric.
181      *
182      * @param serviceBeganTimeNanoseconds the timestamp moment when the platform was called,
183      *                                    typically passed in through the {@link InitialPhaseMetric}
184      */
setServiceBeganTimeNanoseconds(long serviceBeganTimeNanoseconds)185     public void setServiceBeganTimeNanoseconds(long serviceBeganTimeNanoseconds) {
186         mServiceBeganTimeNanoseconds = serviceBeganTimeNanoseconds;
187     }
188 
setQueryStartTimeNanoseconds(long queryStartTimeNanoseconds)189     public void setQueryStartTimeNanoseconds(long queryStartTimeNanoseconds) {
190         mQueryStartTimeNanoseconds = queryStartTimeNanoseconds;
191     }
192 
setQueryEndTimeNanoseconds(long queryEndTimeNanoseconds)193     public void setQueryEndTimeNanoseconds(long queryEndTimeNanoseconds) {
194         mQueryEndTimeNanoseconds = queryEndTimeNanoseconds;
195     }
196 
setUiCallStartTimeNanoseconds(long uiCallStartTimeNanoseconds)197     public void setUiCallStartTimeNanoseconds(long uiCallStartTimeNanoseconds) {
198         mUiCallStartTimeNanoseconds = uiCallStartTimeNanoseconds;
199     }
200 
setUiCallEndTimeNanoseconds(long uiCallEndTimeNanoseconds)201     public void setUiCallEndTimeNanoseconds(long uiCallEndTimeNanoseconds) {
202         mUiCallEndTimeNanoseconds = uiCallEndTimeNanoseconds;
203     }
204 
setFinalFinishTimeNanoseconds(long finalFinishTimeNanoseconds)205     public void setFinalFinishTimeNanoseconds(long finalFinishTimeNanoseconds) {
206         mFinalFinishTimeNanoseconds = finalFinishTimeNanoseconds;
207     }
208 
getServiceBeganTimeNanoseconds()209     public long getServiceBeganTimeNanoseconds() {
210         return mServiceBeganTimeNanoseconds;
211     }
212 
getQueryStartTimeNanoseconds()213     public long getQueryStartTimeNanoseconds() {
214         return mQueryStartTimeNanoseconds;
215     }
216 
getQueryEndTimeNanoseconds()217     public long getQueryEndTimeNanoseconds() {
218         return mQueryEndTimeNanoseconds;
219     }
220 
getUiCallStartTimeNanoseconds()221     public long getUiCallStartTimeNanoseconds() {
222         return mUiCallStartTimeNanoseconds;
223     }
224 
getUiCallEndTimeNanoseconds()225     public long getUiCallEndTimeNanoseconds() {
226         return mUiCallEndTimeNanoseconds;
227     }
228 
getFinalFinishTimeNanoseconds()229     public long getFinalFinishTimeNanoseconds() {
230         return mFinalFinishTimeNanoseconds;
231     }
232 
233     /* --- Time Stamp Conversion to Microseconds from Reference Point --- */
234 
235     /**
236      * We collect raw timestamps in nanoseconds for ease of collection. However, given the scope
237      * of our logging timeframe, and size considerations of the metric, we require these to give us
238      * the microsecond timestamps from the start reference point.
239      *
240      * @param specificTimestamp the timestamp to consider, must be greater than the reference
241      * @return the microsecond integer timestamp from service start to query began
242      */
getTimestampFromReferenceStartMicroseconds(long specificTimestamp)243     public int getTimestampFromReferenceStartMicroseconds(long specificTimestamp) {
244         if (specificTimestamp < mServiceBeganTimeNanoseconds) {
245             Slog.i(TAG, "The timestamp is before service started, falling back to default int");
246             return MetricUtilities.DEFAULT_INT_32;
247         }
248         return (int) ((specificTimestamp
249                 - mServiceBeganTimeNanoseconds) / 1000);
250     }
251 
252     /* ----------- Provider Status -------------- */
253 
getChosenProviderStatus()254     public int getChosenProviderStatus() {
255         return mChosenProviderStatus;
256     }
257 
setChosenProviderStatus(int chosenProviderStatus)258     public void setChosenProviderStatus(int chosenProviderStatus) {
259         mChosenProviderStatus = chosenProviderStatus;
260     }
261 
262     /* ----------- Session ID -------------- */
263 
getSessionIdProvider()264     public int getSessionIdProvider() {
265         return mSessionIdProvider;
266     }
267 
268     /* ----------- UI Returned Successfully -------------- */
269 
setUiReturned(boolean uiReturned)270     public void setUiReturned(boolean uiReturned) {
271         mUiReturned = uiReturned;
272     }
273 
isUiReturned()274     public boolean isUiReturned() {
275         return mUiReturned;
276     }
277 
278     /* -------------- Has Exception ---------------- */
279 
setHasException(boolean hasException)280     public void setHasException(boolean hasException) {
281         mHasException = hasException;
282     }
283 
isHasException()284     public boolean isHasException() {
285         return mHasException;
286     }
287 
288     /* -------------- The Entries and Responses Gathered ---------------- */
289 
setResponseCollective(ResponseCollective responseCollective)290     public void setResponseCollective(ResponseCollective responseCollective) {
291         mResponseCollective = responseCollective;
292     }
293 
getResponseCollective()294     public ResponseCollective getResponseCollective() {
295         return mResponseCollective;
296     }
297 
298     /* -------------- Framework Exception ---------------- */
299 
setFrameworkException(String frameworkException)300     public void setFrameworkException(String frameworkException) {
301         mFrameworkException = frameworkException;
302     }
303 
getFrameworkException()304     public String getFrameworkException() {
305         return mFrameworkException;
306     }
307 
308     /* -------------- Session ID for Track One (Known Calling App) ---------------- */
309 
getSessionIdCaller()310     public int getSessionIdCaller() {
311         return mSessionIdCaller;
312     }
313 
setPrimary(boolean primary)314     public void setPrimary(boolean primary) {
315         mIsPrimary = primary;
316     }
317 
isPrimary()318     public boolean isPrimary() {
319         return mIsPrimary;
320     }
321 
setOemUiUid(int oemUiUid)322     public void setOemUiUid(int oemUiUid) {
323         mOemUiUid = oemUiUid;
324     }
325 
getOemUiUid()326     public int getOemUiUid() {
327         return mOemUiUid;
328     }
329 
setFallbackUiUid(int fallbackUiUid)330     public void setFallbackUiUid(int fallbackUiUid) {
331         mFallbackUiUid = fallbackUiUid;
332     }
333 
getFallbackUiUid()334     public int getFallbackUiUid() {
335         return mFallbackUiUid;
336     }
337 
setOemUiUsageStatus(OemUiUsageStatus oemUiUsageStatus)338     public void setOemUiUsageStatus(OemUiUsageStatus oemUiUsageStatus) {
339         mOemUiUsageStatus = oemUiUsageStatus;
340     }
341 
getOemUiUsageStatus()342     public int getOemUiUsageStatus() {
343         return mOemUiUsageStatus.getLoggingInt();
344     }
345 }
346