diff --git a/services/credentials/java/com/android/server/credentials/MetricUtilities.java b/services/credentials/java/com/android/server/credentials/MetricUtilities.java index 255b2f80ff4492e2760c0743c5f9380acd8fa344..2dc930d42d62a3b88e61cb3a4d3c1c2f64701838 100644 --- a/services/credentials/java/com/android/server/credentials/MetricUtilities.java +++ b/services/credentials/java/com/android/server/credentials/MetricUtilities.java @@ -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(); diff --git a/services/credentials/java/com/android/server/credentials/ProviderSession.java b/services/credentials/java/com/android/server/credentials/ProviderSession.java index a8b9bf6b1fd63003dec08ebfdd581c4468664bd8..3a72dbc440073fa817a427010e335eaa139e422e 100644 --- a/services/credentials/java/com/android/server/credentials/ProviderSession.java +++ b/services/credentials/java/com/android/server/credentials/ProviderSession.java @@ -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); } diff --git a/services/credentials/java/com/android/server/credentials/RequestSession.java b/services/credentials/java/com/android/server/credentials/RequestSession.java index c1f35d0f81950aebe83e1fb53251e65d04a07f9e..42ec42b170caa2e6f188fa02553852097d4e74ac 100644 --- a/services/credentials/java/com/android/server/credentials/RequestSession.java +++ b/services/credentials/java/com/android/server/credentials/RequestSession.java @@ -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()); diff --git a/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java b/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java new file mode 100644 index 0000000000000000000000000000000000000000..1c7fb69548fcdf53f00e61139a5c57bf8b4ac0d5 --- /dev/null +++ b/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java @@ -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; + } +} diff --git a/services/credentials/java/com/android/server/credentials/metrics/CandidateProviderMetric.java b/services/credentials/java/com/android/server/credentials/metrics/CandidateProviderMetric.java deleted file mode 100644 index 9f438ecc114604b49db9636597935eb24a68ab82..0000000000000000000000000000000000000000 --- a/services/credentials/java/com/android/server/credentials/metrics/CandidateProviderMetric.java +++ /dev/null @@ -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; - } -} diff --git a/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderMetric.java b/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderMetric.java index 03102558d21bc60aad074595b50ea89798425af9..1a6109116d385c4e32d149023b636f38d1376e05 100644 --- a/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderMetric.java +++ b/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderMetric.java @@ -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