Candidate Phase Metric Collector Data Type
Updated to match new atom, this handles the candidate phase. Note this is *per provider* and thus we store this in a collection until the logging occurs. How that happens may slightly change given our new funnel points. In any case, this local collection of the metric will help us emit properly. Bug: 270403549 Test: To be chained in - are visually tested Change-Id: Iad387c33f10c43b31308b18c339d72f9176a658e
This commit is contained in:
@@ -24,7 +24,7 @@ import android.util.Log;
|
||||
import com.android.internal.util.FrameworkStatsLog;
|
||||
import com.android.server.credentials.metrics.ApiName;
|
||||
import com.android.server.credentials.metrics.ApiStatus;
|
||||
import com.android.server.credentials.metrics.CandidateProviderMetric;
|
||||
import com.android.server.credentials.metrics.CandidatePhaseMetric;
|
||||
import com.android.server.credentials.metrics.ChosenProviderMetric;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -98,7 +98,7 @@ public class MetricUtilities {
|
||||
int[] candidateStatusList = new int[providerSize];
|
||||
int index = 0;
|
||||
for (var session : providerSessions) {
|
||||
CandidateProviderMetric metric = session.mCandidateProviderMetric;
|
||||
CandidatePhaseMetric metric = session.mCandidateProviderMetric;
|
||||
candidateUidList[index] = metric.getCandidateUid();
|
||||
candidateQueryRoundTripTimeList[index] = metric.getQueryLatencyMicroseconds();
|
||||
candidateStatusList[index] = metric.getProviderQueryStatus();
|
||||
|
||||
@@ -31,7 +31,7 @@ import android.os.ICancellationSignal;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.server.credentials.metrics.CandidateProviderMetric;
|
||||
import com.android.server.credentials.metrics.CandidatePhaseMetric;
|
||||
import com.android.server.credentials.metrics.ProviderStatusForMetrics;
|
||||
|
||||
import java.util.UUID;
|
||||
@@ -59,7 +59,7 @@ public abstract class ProviderSession<T, R>
|
||||
@Nullable protected R mProviderResponse;
|
||||
@NonNull protected Boolean mProviderResponseSet = false;
|
||||
// Specific candidate provider metric for the provider this session handles
|
||||
@Nullable protected CandidateProviderMetric mCandidateProviderMetric;
|
||||
@Nullable protected CandidatePhaseMetric mCandidateProviderMetric;
|
||||
@NonNull private int mProviderSessionUid;
|
||||
|
||||
/**
|
||||
@@ -126,7 +126,7 @@ public abstract class ProviderSession<T, R>
|
||||
mUserId = userId;
|
||||
mComponentName = info.getServiceInfo().getComponentName();
|
||||
mRemoteCredentialService = remoteCredentialService;
|
||||
mCandidateProviderMetric = new CandidateProviderMetric();
|
||||
mCandidateProviderMetric = new CandidatePhaseMetric();
|
||||
mProviderSessionUid = MetricUtilities.getPackageUid(mContext, mComponentName);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ import android.util.Log;
|
||||
import com.android.internal.R;
|
||||
import com.android.server.credentials.metrics.ApiName;
|
||||
import com.android.server.credentials.metrics.ApiStatus;
|
||||
import com.android.server.credentials.metrics.CandidateProviderMetric;
|
||||
import com.android.server.credentials.metrics.CandidatePhaseMetric;
|
||||
import com.android.server.credentials.metrics.ChosenProviderMetric;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -218,7 +218,7 @@ abstract class RequestSession<T, U> implements CredentialManagerUi.CredentialMan
|
||||
* @param componentName the componentName to associate with a provider
|
||||
*/
|
||||
protected void setChosenMetric(ComponentName componentName) {
|
||||
CandidateProviderMetric metric = this.mProviders.get(componentName.flattenToString())
|
||||
CandidatePhaseMetric metric = this.mProviders.get(componentName.flattenToString())
|
||||
.mCandidateProviderMetric;
|
||||
mChosenProviderMetric.setChosenUid(metric.getCandidateUid());
|
||||
mChosenProviderMetric.setFinalFinishTimeNanoseconds(System.nanoTime());
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.credentials.metrics;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.server.credentials.MetricUtilities;
|
||||
|
||||
/**
|
||||
* The central candidate provider metric object that mimics our defined metric setup.
|
||||
* Some types are redundant across these metric collectors, but that has debug use-cases as
|
||||
* these data-types are available at different moments of the flow (and typically, one can feed
|
||||
* into the next).
|
||||
* TODO(b/270403549) - iterate on this in V3+
|
||||
*/
|
||||
public class CandidatePhaseMetric {
|
||||
|
||||
private static final String TAG = "CandidateProviderMetric";
|
||||
// Since this will always be the second in the split sequence, this is statically 2
|
||||
private static final int SESSION_ID = 2;
|
||||
// The sequence number of this emit of the API call, default -1, equal for all candidates
|
||||
private int mSequenceId = -1;
|
||||
// Indicates if this provider returned from the query phase, default false
|
||||
private boolean mQueryReturned = false;
|
||||
|
||||
// The candidate provider uid
|
||||
private int mCandidateUid = -1;
|
||||
|
||||
// Raw timestamp in nanoseconds, will be converted to microseconds for logging
|
||||
|
||||
//For reference, the initial log timestamp when the service started running the API call
|
||||
private long mServiceBeganTimeNanoseconds = -1;
|
||||
// The moment when the query phase began
|
||||
private long mStartQueryTimeNanoseconds = -1;
|
||||
// The moment when the query phase ended
|
||||
private long mQueryFinishTimeNanoseconds = -1;
|
||||
|
||||
// The status of this particular provider
|
||||
private int mProviderQueryStatus = -1;
|
||||
// Indicates if an exception was thrown by this provider, false by default
|
||||
private boolean mHasException = false;
|
||||
// Indicates the number of total entries available. We can also locally store the entries, but
|
||||
// cannot emit them in the current split form. TODO(b/271135048) - possibly readjust candidate
|
||||
// entries. Also, it may be okay to remove this and instead aggregate from inner counts.
|
||||
// Defaults to -1
|
||||
private int mNumEntriesTotal = -1;
|
||||
// The count of action entries from this provider, defaults to -1
|
||||
private int mActionEntryCount = -1;
|
||||
// The count of credential entries from this provider, defaults to -1
|
||||
private int mCredentialEntryCount = -1;
|
||||
// The *type-count* of the credential entries, defaults to -1
|
||||
private int mCredentialEntryTypeCount = -1;
|
||||
// The count of remote entries from this provider, defaults to -1
|
||||
private int mRemoteEntryCount = -1;
|
||||
// The count of authentication entries from this provider, defaults to -1
|
||||
private int mAuthenticationEntryCount = -1;
|
||||
|
||||
public CandidatePhaseMetric() {
|
||||
}
|
||||
|
||||
/* ---------- Latencies ---------- */
|
||||
|
||||
/* -- Timestamps -- */
|
||||
|
||||
public void setServiceBeganTimeNanoseconds(long serviceBeganTimeNanoseconds) {
|
||||
this.mServiceBeganTimeNanoseconds = serviceBeganTimeNanoseconds;
|
||||
}
|
||||
|
||||
public void setStartQueryTimeNanoseconds(long startQueryTimeNanoseconds) {
|
||||
this.mStartQueryTimeNanoseconds = startQueryTimeNanoseconds;
|
||||
}
|
||||
|
||||
public void setQueryFinishTimeNanoseconds(long queryFinishTimeNanoseconds) {
|
||||
this.mQueryFinishTimeNanoseconds = queryFinishTimeNanoseconds;
|
||||
}
|
||||
|
||||
public long getServiceBeganTimeNanoseconds() {
|
||||
return this.mServiceBeganTimeNanoseconds;
|
||||
}
|
||||
|
||||
public long getStartQueryTimeNanoseconds() {
|
||||
return this.mStartQueryTimeNanoseconds;
|
||||
}
|
||||
|
||||
public long getQueryFinishTimeNanoseconds() {
|
||||
return this.mQueryFinishTimeNanoseconds;
|
||||
}
|
||||
|
||||
/* -- Actual time delta latencies (for local utility) -- */
|
||||
|
||||
/**
|
||||
* Returns the latency in microseconds for the query phase.
|
||||
*/
|
||||
public int getQueryLatencyMicroseconds() {
|
||||
return (int) ((this.getQueryFinishTimeNanoseconds()
|
||||
- this.getStartQueryTimeNanoseconds()) / 1000);
|
||||
}
|
||||
|
||||
/* --- Time Stamp Conversion to Microseconds from Reference --- */
|
||||
|
||||
/**
|
||||
* We collect raw timestamps in nanoseconds for ease of collection. However, given the scope
|
||||
* of our logging timeframe, and size considerations of the metric, we require these to give us
|
||||
* the microsecond timestamps from the start reference point.
|
||||
*
|
||||
* @param specificTimestamp the timestamp to consider, must be greater than the reference
|
||||
* @return the microsecond integer timestamp from service start to query began
|
||||
*/
|
||||
public int getTimestampFromReferenceStartMicroseconds(long specificTimestamp) {
|
||||
if (specificTimestamp < this.mServiceBeganTimeNanoseconds) {
|
||||
Log.i(TAG, "The timestamp is before service started, falling back to default int");
|
||||
return MetricUtilities.DEFAULT_INT_32;
|
||||
}
|
||||
return (int) ((specificTimestamp
|
||||
- this.mServiceBeganTimeNanoseconds) / 1000);
|
||||
}
|
||||
|
||||
/* ------------- Provider Query Status ------------ */
|
||||
|
||||
public void setProviderQueryStatus(int providerQueryStatus) {
|
||||
this.mProviderQueryStatus = providerQueryStatus;
|
||||
}
|
||||
|
||||
public int getProviderQueryStatus() {
|
||||
return this.mProviderQueryStatus;
|
||||
}
|
||||
|
||||
/* -------------- Candidate Uid ---------------- */
|
||||
|
||||
public void setCandidateUid(int candidateUid) {
|
||||
this.mCandidateUid = candidateUid;
|
||||
}
|
||||
|
||||
public int getCandidateUid() {
|
||||
return this.mCandidateUid;
|
||||
}
|
||||
|
||||
/* -------------- Session Id ---------------- */
|
||||
public int getSessionId() {
|
||||
return SESSION_ID;
|
||||
}
|
||||
|
||||
/* -------------- Sequence Id ---------------- */
|
||||
|
||||
public void setSequenceId(int sequenceId) {
|
||||
mSequenceId = sequenceId;
|
||||
}
|
||||
|
||||
public int getSequenceId() {
|
||||
return mSequenceId;
|
||||
}
|
||||
|
||||
/* -------------- Query Returned Status ---------------- */
|
||||
|
||||
public void setQueryReturned(boolean queryReturned) {
|
||||
mQueryReturned = queryReturned;
|
||||
}
|
||||
|
||||
public boolean isQueryReturned() {
|
||||
return mQueryReturned;
|
||||
}
|
||||
|
||||
/* -------------- Has Exception Status ---------------- */
|
||||
|
||||
public void setHasException(boolean hasException) {
|
||||
mHasException = hasException;
|
||||
}
|
||||
|
||||
public boolean isHasException() {
|
||||
return mHasException;
|
||||
}
|
||||
|
||||
/* -------------- Number of Entries ---------------- */
|
||||
|
||||
public void setNumEntriesTotal(int numEntriesTotal) {
|
||||
mNumEntriesTotal = numEntriesTotal;
|
||||
}
|
||||
|
||||
public int getNumEntriesTotal() {
|
||||
return mNumEntriesTotal;
|
||||
}
|
||||
|
||||
/* -------------- Count of Action Entries ---------------- */
|
||||
|
||||
public void setActionEntryCount(int actionEntryCount) {
|
||||
mActionEntryCount = actionEntryCount;
|
||||
}
|
||||
|
||||
public int getActionEntryCount() {
|
||||
return mActionEntryCount;
|
||||
}
|
||||
|
||||
/* -------------- Count of Credential Entries ---------------- */
|
||||
|
||||
public void setCredentialEntryCount(int credentialEntryCount) {
|
||||
mCredentialEntryCount = credentialEntryCount;
|
||||
}
|
||||
|
||||
public int getCredentialEntryCount() {
|
||||
return mCredentialEntryCount;
|
||||
}
|
||||
|
||||
/* -------------- Count of Credential Entry Types ---------------- */
|
||||
|
||||
public void setCredentialEntryTypeCount(int credentialEntryTypeCount) {
|
||||
mCredentialEntryTypeCount = credentialEntryTypeCount;
|
||||
}
|
||||
|
||||
public int getCredentialEntryTypeCount() {
|
||||
return mCredentialEntryTypeCount;
|
||||
}
|
||||
|
||||
/* -------------- Count of Remote Entries ---------------- */
|
||||
|
||||
public void setRemoteEntryCount(int remoteEntryCount) {
|
||||
mRemoteEntryCount = remoteEntryCount;
|
||||
}
|
||||
|
||||
public int getRemoteEntryCount() {
|
||||
return mRemoteEntryCount;
|
||||
}
|
||||
|
||||
/* -------------- Count of Authentication Entries ---------------- */
|
||||
|
||||
public void setAuthenticationEntryCount(int authenticationEntryCount) {
|
||||
mAuthenticationEntryCount = authenticationEntryCount;
|
||||
}
|
||||
|
||||
public int getAuthenticationEntryCount() {
|
||||
return mAuthenticationEntryCount;
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.credentials.metrics;
|
||||
|
||||
/**
|
||||
* The central candidate provider metric object that mimics our defined metric setup.
|
||||
* Some types are redundant across these metric collectors, but that has debug use-cases as
|
||||
* these data-types are available at different moments of the flow (and typically, one can feed
|
||||
* into the next).
|
||||
* TODO(b/270403549) - iterate on this in V3+
|
||||
*/
|
||||
public class CandidateProviderMetric {
|
||||
|
||||
private static final String TAG = "CandidateProviderMetric";
|
||||
private int mCandidateUid = -1;
|
||||
|
||||
// Raw timestamp in nanoseconds, will be converted to microseconds for logging
|
||||
|
||||
private long mStartQueryTimeNanoseconds = -1;
|
||||
private long mQueryFinishTimeNanoseconds = -1;
|
||||
|
||||
private int mProviderQueryStatus = -1;
|
||||
|
||||
public CandidateProviderMetric() {
|
||||
}
|
||||
|
||||
/* ---------- Latencies ---------- */
|
||||
|
||||
public void setStartQueryTimeNanoseconds(long startQueryTimeNanoseconds) {
|
||||
this.mStartQueryTimeNanoseconds = startQueryTimeNanoseconds;
|
||||
}
|
||||
|
||||
public void setQueryFinishTimeNanoseconds(long queryFinishTimeNanoseconds) {
|
||||
this.mQueryFinishTimeNanoseconds = queryFinishTimeNanoseconds;
|
||||
}
|
||||
|
||||
public long getStartQueryTimeNanoseconds() {
|
||||
return this.mStartQueryTimeNanoseconds;
|
||||
}
|
||||
|
||||
public long getQueryFinishTimeNanoseconds() {
|
||||
return this.mQueryFinishTimeNanoseconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the latency in microseconds for the query phase.
|
||||
*/
|
||||
public int getQueryLatencyMicroseconds() {
|
||||
return (int) ((this.getQueryFinishTimeNanoseconds()
|
||||
- this.getStartQueryTimeNanoseconds()) / 1000);
|
||||
}
|
||||
|
||||
// TODO (in direct next dependent CL, so this is transient) - add reference timestamp in micro
|
||||
// seconds for this too.
|
||||
|
||||
/* ------------- Provider Query Status ------------ */
|
||||
|
||||
public void setProviderQueryStatus(int providerQueryStatus) {
|
||||
this.mProviderQueryStatus = providerQueryStatus;
|
||||
}
|
||||
|
||||
public int getProviderQueryStatus() {
|
||||
return this.mProviderQueryStatus;
|
||||
}
|
||||
|
||||
/* -------------- Candidate Uid ---------------- */
|
||||
|
||||
public void setCandidateUid(int candidateUid) {
|
||||
this.mCandidateUid = candidateUid;
|
||||
}
|
||||
|
||||
public int getCandidateUid() {
|
||||
return this.mCandidateUid;
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,7 @@ public class ChosenProviderMetric {
|
||||
/* ---------------- Latencies ------------------ */
|
||||
|
||||
|
||||
/* ----- Direct Latencies ------- */
|
||||
/* ----- Direct Delta Latencies for Local Utility ------- */
|
||||
|
||||
/**
|
||||
* In order for a chosen provider to be selected, the call must have successfully begun.
|
||||
@@ -85,7 +85,7 @@ public class ChosenProviderMetric {
|
||||
* metric.
|
||||
*
|
||||
* @param queryPhaseLatencyMicroseconds the millisecond latency for the query phase, typically
|
||||
* passed in through the {@link CandidateProviderMetric}
|
||||
* passed in through the {@link CandidatePhaseMetric}
|
||||
*/
|
||||
public void setQueryPhaseLatencyMicroseconds(int queryPhaseLatencyMicroseconds) {
|
||||
mQueryPhaseLatencyMicroseconds = queryPhaseLatencyMicroseconds;
|
||||
@@ -106,7 +106,7 @@ public class ChosenProviderMetric {
|
||||
|
||||
/**
|
||||
* Returns the full provider (invocation to response) latency in microseconds. Expects the
|
||||
* start time to be provided, such as from {@link CandidateProviderMetric}.
|
||||
* start time to be provided, such as from {@link CandidatePhaseMetric}.
|
||||
*/
|
||||
public int getEntireProviderLatencyMicroseconds() {
|
||||
return (int) ((this.mFinalFinishTimeNanoseconds
|
||||
@@ -172,7 +172,7 @@ public class ChosenProviderMetric {
|
||||
return mFinalFinishTimeNanoseconds;
|
||||
}
|
||||
|
||||
/* --- Time Stamp Conversion to Microseconds --- */
|
||||
/* --- Time Stamp Conversion to Microseconds from Reference Point --- */
|
||||
|
||||
/**
|
||||
* We collect raw timestamps in nanoseconds for ease of collection. However, given the scope
|
||||
|
||||
Reference in New Issue
Block a user