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 candidate provider metric object that mimics our defined metric setup.
28  * Some types are redundant across these metric collectors, but that has debug use-cases as
29  * these data-types are available at different moments of the flow (and typically, one can feed
30  * into the next).
31  */
32 public class CandidatePhaseMetric {
33 
34     private static final String TAG = "CandidateProviderMetric";
35     // The session id of this provider metric
36     private final int mSessionIdProvider;
37     // Indicates if this provider returned from the query phase, default false
38     private boolean mQueryReturned = false;
39 
40     // The candidate provider uid
41     private int mCandidateUid = -1;
42 
43     // Raw timestamp in nanoseconds, will be converted to microseconds for logging
44 
45     //For reference, the initial log timestamp when the service started running the API call
46     private long mServiceBeganTimeNanoseconds = -1;
47     // The moment when the query phase began
48     private long mStartQueryTimeNanoseconds = -1;
49     // The moment when the query phase ended
50     private long mQueryFinishTimeNanoseconds = -1;
51 
52     // The status of this particular provider
53     private int mProviderQueryStatus = -1;
54     // Indicates if an exception was thrown by this provider, false by default
55     private boolean mHasException = false;
56     // Indicates the framework only exception belonging to this provider
57     private String mFrameworkException = "";
58 
59     // Stores the response credential information, as well as the response entry information which
60     // by default, contains empty info
61     private ResponseCollective mResponseCollective = new ResponseCollective(Map.of(), Map.of());
62     // Indicates if this candidate is a primary provider, false by default
63     private boolean mIsPrimary = false;
64 
CandidatePhaseMetric(int sessionIdTrackTwo)65     public CandidatePhaseMetric(int sessionIdTrackTwo) {
66         mSessionIdProvider = sessionIdTrackTwo;
67     }
68 
69     /* ---------- Latencies ---------- */
70 
71     /* -- Timestamps -- */
72 
setServiceBeganTimeNanoseconds(long serviceBeganTimeNanoseconds)73     public void setServiceBeganTimeNanoseconds(long serviceBeganTimeNanoseconds) {
74         mServiceBeganTimeNanoseconds = serviceBeganTimeNanoseconds;
75     }
76 
setStartQueryTimeNanoseconds(long startQueryTimeNanoseconds)77     public void setStartQueryTimeNanoseconds(long startQueryTimeNanoseconds) {
78         mStartQueryTimeNanoseconds = startQueryTimeNanoseconds;
79     }
80 
setQueryFinishTimeNanoseconds(long queryFinishTimeNanoseconds)81     public void setQueryFinishTimeNanoseconds(long queryFinishTimeNanoseconds) {
82         mQueryFinishTimeNanoseconds = queryFinishTimeNanoseconds;
83     }
84 
getServiceBeganTimeNanoseconds()85     public long getServiceBeganTimeNanoseconds() {
86         return mServiceBeganTimeNanoseconds;
87     }
88 
getStartQueryTimeNanoseconds()89     public long getStartQueryTimeNanoseconds() {
90         return mStartQueryTimeNanoseconds;
91     }
92 
getQueryFinishTimeNanoseconds()93     public long getQueryFinishTimeNanoseconds() {
94         return mQueryFinishTimeNanoseconds;
95     }
96 
97     /* -- Actual time delta latencies (for local utility) -- */
98 
99     /**
100      * Returns the latency in microseconds for the query phase.
101      */
getQueryLatencyMicroseconds()102     public int getQueryLatencyMicroseconds() {
103         return (int) ((getQueryFinishTimeNanoseconds()
104                 - getStartQueryTimeNanoseconds()) / 1000);
105     }
106 
107     /* --- Time Stamp Conversion to Microseconds from Reference --- */
108 
109     /**
110      * We collect raw timestamps in nanoseconds for ease of collection. However, given the scope
111      * of our logging timeframe, and size considerations of the metric, we require these to give us
112      * the microsecond timestamps from the start reference point.
113      *
114      * @param specificTimestamp the timestamp to consider, must be greater than the reference
115      * @return the microsecond integer timestamp from service start to query began
116      */
getTimestampFromReferenceStartMicroseconds(long specificTimestamp)117     public int getTimestampFromReferenceStartMicroseconds(long specificTimestamp) {
118         if (specificTimestamp < mServiceBeganTimeNanoseconds) {
119             Slog.i(TAG, "The timestamp is before service started, falling back to default int");
120             return MetricUtilities.DEFAULT_INT_32;
121         }
122         return (int) ((specificTimestamp
123                 - mServiceBeganTimeNanoseconds) / 1000);
124     }
125 
126     /* ------------- Provider Query Status ------------ */
127 
setProviderQueryStatus(int providerQueryStatus)128     public void setProviderQueryStatus(int providerQueryStatus) {
129         mProviderQueryStatus = providerQueryStatus;
130     }
131 
getProviderQueryStatus()132     public int getProviderQueryStatus() {
133         return mProviderQueryStatus;
134     }
135 
136     /* -------------- Candidate Uid ---------------- */
137 
setCandidateUid(int candidateUid)138     public void setCandidateUid(int candidateUid) {
139         mCandidateUid = candidateUid;
140     }
141 
getCandidateUid()142     public int getCandidateUid() {
143         return mCandidateUid;
144     }
145 
146     /* -------------- Session Id ---------------- */
147 
getSessionIdProvider()148     public int getSessionIdProvider() {
149         return mSessionIdProvider;
150     }
151 
152     /* -------------- Query Returned Status ---------------- */
153 
setQueryReturned(boolean queryReturned)154     public void setQueryReturned(boolean queryReturned) {
155         mQueryReturned = queryReturned;
156     }
157 
isQueryReturned()158     public boolean isQueryReturned() {
159         return mQueryReturned;
160     }
161 
162     /* -------------- Has Exception Status ---------------- */
163 
setHasException(boolean hasException)164     public void setHasException(boolean hasException) {
165         mHasException = hasException;
166     }
167 
isHasException()168     public boolean isHasException() {
169         return mHasException;
170     }
171 
172     /* -------------- The Entries and Responses Gathered ---------------- */
setResponseCollective(ResponseCollective responseCollective)173     public void setResponseCollective(ResponseCollective responseCollective) {
174         mResponseCollective = responseCollective;
175     }
176 
getResponseCollective()177     public ResponseCollective getResponseCollective() {
178         return mResponseCollective;
179     }
180 
181     /* ------ Framework Exception for this Candidate ------ */
182 
setFrameworkException(String frameworkException)183     public void setFrameworkException(String frameworkException) {
184         mFrameworkException = frameworkException;
185     }
186 
getFrameworkException()187     public String getFrameworkException() {
188         return mFrameworkException;
189     }
190 
setPrimary(boolean primary)191     public void setPrimary(boolean primary) {
192         mIsPrimary = primary;
193     }
194 
isPrimary()195     public boolean isPrimary() {
196         return mIsPrimary;
197     }
198 }
199