diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java index f4b745e3db4e4..8728c3c647159 100644 --- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java +++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java @@ -697,8 +697,6 @@ public final class CredentialManagerService initMetric.setCredentialServiceBeginQueryTimeNanoseconds(System.nanoTime()); MetricUtilities.logApiCalledInitialPhase(initMetric, session.mRequestSessionMetric.returnIncrementSequence()); - session.mRequestSessionMetric.getCandidateAggregateMetric().setSessionId( - initMetric.getSessionId()); } catch (Exception e) { Slog.i(TAG, "Unexpected error during metric logging: ", e); } diff --git a/services/credentials/java/com/android/server/credentials/MetricUtilities.java b/services/credentials/java/com/android/server/credentials/MetricUtilities.java index e1854fa3ed1dd..704a22837002d 100644 --- a/services/credentials/java/com/android/server/credentials/MetricUtilities.java +++ b/services/credentials/java/com/android/server/credentials/MetricUtilities.java @@ -141,7 +141,7 @@ public class MetricUtilities { index++; } FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE_REPORTED, - /* session_id */ finalPhaseMetric.getSessionId(), + /* session_id */ finalPhaseMetric.getSessionIdTrackTwo(), /* sequence_num */ emitSequenceId, /* ui_returned_final_start */ finalPhaseMetric.isUiReturned(), /* chosen_provider_uid */ finalPhaseMetric.getChosenUid(), @@ -181,8 +181,7 @@ public class MetricUtilities { finalPhaseMetric.getResponseCollective().getUniqueResponseCounts(), /* framework_exception_unique_classtype */ finalPhaseMetric.getFrameworkException(), - /* primary_indicated */ - false + /* primary_indicated */ false ); } catch (Exception e) { Slog.w(TAG, "Unexpected error during final provider uid emit: " + e); @@ -226,7 +225,7 @@ public class MetricUtilities { CandidatePhaseMetric metric = session.mProviderSessionMetric .getCandidatePhasePerProviderMetric(); if (sessionId == -1) { - sessionId = metric.getSessionId(); + sessionId = metric.getSessionIdTrackTwo(); } if (!queryReturned) { queryReturned = metric.isQueryReturned(); @@ -363,8 +362,8 @@ public class MetricUtilities { FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_TOTAL_REPORTED, /*session_id*/ candidateAggregateMetric.getSessionId(), /*sequence_num*/ sequenceNum, - /*query_returned*/ true, - /*num_query_providers*/ DEFAULT_INT_32, + /*query_returned*/ candidateAggregateMetric.isQueryReturned(), + /*num_providers*/ candidateAggregateMetric.getNumProviders(), /*min_query_start_timestamp_microseconds*/ DEFAULT_INT_32, /*max_query_end_timestamp_microseconds*/ diff --git a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java index 16beaa4eb13e9..19a098eb84283 100644 --- a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java +++ b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java @@ -193,11 +193,11 @@ public final class ProviderCreateSession extends ProviderSession< mProviderResponseDataHandler.addResponseContent(response.getCreateEntries(), response.getRemoteCreateEntry()); if (mProviderResponseDataHandler.isEmptyResponse(response)) { - mProviderSessionMetric.collectCandidateEntryMetrics(response); + mProviderSessionMetric.collectCandidateEntryMetrics(response, /*isAuthEntry*/false); updateStatusAndInvokeCallback(Status.EMPTY_RESPONSE, /*source=*/ CredentialsSource.REMOTE_PROVIDER); } else { - mProviderSessionMetric.collectCandidateEntryMetrics(response); + mProviderSessionMetric.collectCandidateEntryMetrics(response, /*isAuthEntry*/false); updateStatusAndInvokeCallback(Status.SAVE_ENTRIES_RECEIVED, /*source=*/ CredentialsSource.REMOTE_PROVIDER); } diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java index 1e80703378e0c..28bc9de25cd80 100644 --- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java +++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java @@ -432,6 +432,7 @@ public final class ProviderGetSession extends ProviderSession @NonNull protected Boolean mProviderResponseSet = false; @NonNull - protected final ProviderSessionMetric mProviderSessionMetric = new ProviderSessionMetric(); + protected final ProviderSessionMetric mProviderSessionMetric; @NonNull private int mProviderSessionUid; @@ -113,6 +113,13 @@ public abstract class ProviderSession return status == Status.COMPLETE || status == Status.EMPTY_RESPONSE; } + /** + * Gives access to the objects metric collectors. + */ + public ProviderSessionMetric getProviderSessionMetric() { + return this.mProviderSessionMetric; + } + /** * Interface to be implemented by any class that wishes to get a callback when a particular * provider session's status changes. Typically, implemented by the {@link RequestSession} @@ -147,6 +154,8 @@ public abstract class ProviderSession mComponentName = componentName; mRemoteCredentialService = remoteCredentialService; mProviderSessionUid = MetricUtilities.getPackageUid(mContext, mComponentName); + mProviderSessionMetric = new ProviderSessionMetric( + ((RequestSession) mCallbacks).mRequestSessionMetric.getSessionIdTrackTwo()); } /** Provider status at various states of the provider session. */ @@ -206,7 +215,8 @@ public abstract class ProviderSession CredentialsSource source) { setStatus(status); mProviderSessionMetric.collectCandidateMetricUpdate(isTerminatingStatus(status), - isCompletionStatus(status), mProviderSessionUid); + isCompletionStatus(status), mProviderSessionUid, + source == CredentialsSource.AUTH_ENTRY); mCallbacks.onProviderStatusChanged(status, mComponentName, source); } /** Common method that transfers metrics from the init phase to candidates */ diff --git a/services/credentials/java/com/android/server/credentials/RequestSession.java b/services/credentials/java/com/android/server/credentials/RequestSession.java index 350a0bef80847..fb7aef0b7bd1c 100644 --- a/services/credentials/java/com/android/server/credentials/RequestSession.java +++ b/services/credentials/java/com/android/server/credentials/RequestSession.java @@ -75,6 +75,8 @@ abstract class RequestSession implements CredentialManagerUi.Credential protected final Handler mHandler; @UserIdInt protected final int mUserId; + + protected final int mUniqueSessionInteger; private final int mCallingUid; @NonNull protected final CallingAppInfo mClientAppInfo; @@ -82,7 +84,7 @@ abstract class RequestSession implements CredentialManagerUi.Credential protected final CancellationSignal mCancellationSignal; protected final Map mProviders = new ConcurrentHashMap<>(); - protected final RequestSessionMetric mRequestSessionMetric = new RequestSessionMetric(); + protected final RequestSessionMetric mRequestSessionMetric; protected final String mHybridService; protected final Object mLock; @@ -132,8 +134,12 @@ abstract class RequestSession implements CredentialManagerUi.Credential mUserId, this, mEnabledProviders); mHybridService = context.getResources().getString( R.string.config_defaultCredentialManagerHybridService); + mUniqueSessionInteger = MetricUtilities.getHighlyUniqueInteger(); + mRequestSessionMetric = new RequestSessionMetric(mUniqueSessionInteger, + MetricUtilities.getHighlyUniqueInteger()); mRequestSessionMetric.collectInitialPhaseMetricInfo(timestampStarted, - mCallingUid, ApiName.getMetricCodeFromRequestInfo(mRequestType)); + mCallingUid, ApiName.getMetricCodeFromRequestInfo(mRequestType), + mUniqueSessionInteger); setCancellationListener(); } diff --git a/services/credentials/java/com/android/server/credentials/metrics/BrowsedAuthenticationMetric.java b/services/credentials/java/com/android/server/credentials/metrics/BrowsedAuthenticationMetric.java new file mode 100644 index 0000000000000..20e33738b6e42 --- /dev/null +++ b/services/credentials/java/com/android/server/credentials/metrics/BrowsedAuthenticationMetric.java @@ -0,0 +1,35 @@ +/* + * 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; + +/** + * Encapsulates an authentication entry click atom, as a part of track 2. + * Contains information about what was collected from the authentication entry output. + */ +public class BrowsedAuthenticationMetric { + private final int mSessionIdTrackTwo; + // TODO(b/271135048) - Match the atom and provide a clean per provider session metric + // encapsulation. + + public BrowsedAuthenticationMetric(int sessionIdTrackTwo) { + mSessionIdTrackTwo = sessionIdTrackTwo; + } + + public int getSessionIdTrackTwo() { + return mSessionIdTrackTwo; + } +} diff --git a/services/credentials/java/com/android/server/credentials/metrics/CandidateAggregateMetric.java b/services/credentials/java/com/android/server/credentials/metrics/CandidateAggregateMetric.java index 25c2d9b6c112a..acf608447c64a 100644 --- a/services/credentials/java/com/android/server/credentials/metrics/CandidateAggregateMetric.java +++ b/services/credentials/java/com/android/server/credentials/metrics/CandidateAggregateMetric.java @@ -28,10 +28,16 @@ public class CandidateAggregateMetric { private static final String TAG = "CandidateProviderMetric"; // The session id of this provider, default set to -1 - private int mSessionId = -1; + private final int mSessionId; + // Indicates if this provider returned from the query phase, default false + private boolean mQueryReturned = false; + // Indicates the total number of providers this aggregate captures information for, default 0 + private int mNumProviders = 0; + // Indicates the total number of authentication entries that were tapped in aggregate, default 0 + private int mNumAuthEntriesTapped = 0; - public void setSessionId(int sessionId) { - mSessionId = sessionId; + public CandidateAggregateMetric(int sessionIdTrackOne) { + mSessionId = sessionIdTrackOne; } public int getSessionId() { @@ -42,9 +48,28 @@ public class CandidateAggregateMetric { * This will take all the candidate data captured and aggregate that information. * TODO(b/271135048) : Add on authentication entry outputs from track 2 here as well once * generated - * @param providers a map that associates with all provider sessions + * @param providers the providers associated with the candidate flow */ public void collectAverages(Map providers) { // TODO(b/271135048) : Complete this method + mNumProviders = providers.size(); + var providerSessions = providers.values(); + for (var session : providerSessions) { + var metric = session.getProviderSessionMetric(); + mQueryReturned = mQueryReturned || metric + .mCandidatePhasePerProviderMetric.isQueryReturned(); + } + } + + public int getNumProviders() { + return mNumProviders; + } + + public boolean isQueryReturned() { + return mQueryReturned; + } + + public int getNumAuthEntriesTapped() { + return mNumAuthEntriesTapped; } } diff --git a/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java b/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java index cb2e71f8ba9b1..9d7268f180e6e 100644 --- a/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java +++ b/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java @@ -33,7 +33,7 @@ public class CandidatePhaseMetric { private static final String TAG = "CandidateProviderMetric"; // The session id of this provider, default set to -1 - private int mSessionId = -1; + private final int mSessionIdTrackTwo; // Indicates if this provider returned from the query phase, default false private boolean mQueryReturned = false; @@ -60,7 +60,8 @@ public class CandidatePhaseMetric { // by default, contains empty info private ResponseCollective mResponseCollective = new ResponseCollective(Map.of(), Map.of()); - public CandidatePhaseMetric() { + public CandidatePhaseMetric(int sessionIdTrackTwo) { + mSessionIdTrackTwo = sessionIdTrackTwo; } /* ---------- Latencies ---------- */ @@ -142,12 +143,8 @@ public class CandidatePhaseMetric { /* -------------- Session Id ---------------- */ - public void setSessionId(int sessionId) { - mSessionId = sessionId; - } - - public int getSessionId() { - return mSessionId; + public int getSessionIdTrackTwo() { + return mSessionIdTrackTwo; } /* -------------- Query Returned Status ---------------- */ diff --git a/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderFinalPhaseMetric.java b/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderFinalPhaseMetric.java index 6af686587b88e..7e9c8baa564cc 100644 --- a/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderFinalPhaseMetric.java +++ b/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderFinalPhaseMetric.java @@ -32,8 +32,12 @@ import java.util.Map; */ public class ChosenProviderFinalPhaseMetric { private static final String TAG = "ChosenFinalPhaseMetric"; - // The session id associated with this API call, used to unite split emits - private int mSessionId = -1; + // The session id associated with this API call, used to unite split emits, for the flow + // where we know the calling app + private final int mSessionIdTrackOne; + // The session id associated with this API call, used to unite split emits, for the flow + // where we know the provider apps + private final int mSessionIdTrackTwo; // Reveals if the UI was returned, false by default private boolean mUiReturned = false; private int mChosenUid = -1; @@ -74,7 +78,9 @@ public class ChosenProviderFinalPhaseMetric { private ResponseCollective mResponseCollective = new ResponseCollective(Map.of(), Map.of()); - public ChosenProviderFinalPhaseMetric() { + public ChosenProviderFinalPhaseMetric(int sessionIdTrackOne, int sessionIdTrackTwo) { + mSessionIdTrackOne = sessionIdTrackOne; + mSessionIdTrackTwo = sessionIdTrackTwo; } /* ------------------- UID ------------------- */ @@ -237,12 +243,8 @@ public class ChosenProviderFinalPhaseMetric { /* ----------- Session ID -------------- */ - public void setSessionId(int sessionId) { - mSessionId = sessionId; - } - - public int getSessionId() { - return mSessionId; + public int getSessionIdTrackTwo() { + return mSessionIdTrackTwo; } /* ----------- UI Returned Successfully -------------- */ diff --git a/services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java b/services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java index 060e56ce965b3..eb88d37639436 100644 --- a/services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java +++ b/services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java @@ -33,7 +33,7 @@ public class InitialPhaseMetric { // The caller uid of the calling application, default to -1 private int mCallerUid = -1; // The session id to unite multiple atom emits, default to -1 - private int mSessionId = -1; + private final int mSessionId; // Raw timestamps in nanoseconds, *the only* one logged as such (i.e. 64 bits) since it is a // reference point. @@ -50,7 +50,8 @@ public class InitialPhaseMetric { private Map mRequestCounts = new LinkedHashMap<>(); - public InitialPhaseMetric() { + public InitialPhaseMetric(int sessionIdTrackOne) { + mSessionId = sessionIdTrackOne; } /* ---------- Latencies ---------- */ @@ -105,10 +106,6 @@ public class InitialPhaseMetric { /* ------ SessionId ------ */ - public void setSessionId(int sessionId) { - mSessionId = sessionId; - } - public int getSessionId() { return mSessionId; } diff --git a/services/credentials/java/com/android/server/credentials/metrics/ProviderSessionMetric.java b/services/credentials/java/com/android/server/credentials/metrics/ProviderSessionMetric.java index b0016e764a395..47db8f59ff355 100644 --- a/services/credentials/java/com/android/server/credentials/metrics/ProviderSessionMetric.java +++ b/services/credentials/java/com/android/server/credentials/metrics/ProviderSessionMetric.java @@ -44,10 +44,17 @@ public class ProviderSessionMetric { // Specific candidate provider metric for the provider this session handles @NonNull - protected final CandidatePhaseMetric mCandidatePhasePerProviderMetric = - new CandidatePhaseMetric(); + protected final CandidatePhaseMetric mCandidatePhasePerProviderMetric; - public ProviderSessionMetric() {} + // IFF there was an authentication entry clicked, this stores all required information for + // that event. This is for the 'get' flow. + @NonNull + protected final BrowsedAuthenticationMetric mBrowsedAuthenticationMetric; + + public ProviderSessionMetric(int sessionIdTrackTwo) { + mCandidatePhasePerProviderMetric = new CandidatePhaseMetric(sessionIdTrackTwo); + mBrowsedAuthenticationMetric = new BrowsedAuthenticationMetric(sessionIdTrackTwo); + } /** * Retrieve the candidate provider phase metric and the data it contains. @@ -56,6 +63,7 @@ public class ProviderSessionMetric { return mCandidatePhasePerProviderMetric; } + /** * This collects for ProviderSessions, with respect to the candidate providers, whether * an exception occurred in the candidate call. @@ -78,6 +86,13 @@ public class ProviderSessionMetric { } } + private void collectAuthEntryUpdate(boolean isFailureStatus, + boolean isCompletionStatus, int providerSessionUid) { + // TODO(b/271135048) - Mimic typical candidate update, but with authentication metric + // Collect the final timestamps (and start timestamp), status, exceptions and the provider + // uid. This occurs typically *after* the collection is complete. + } + /** * Used to collect metrics at the update stage when a candidate provider gives back an update. * @@ -86,8 +101,12 @@ public class ProviderSessionMetric { * @param providerSessionUid the uid of the provider */ public void collectCandidateMetricUpdate(boolean isFailureStatus, - boolean isCompletionStatus, int providerSessionUid) { + boolean isCompletionStatus, int providerSessionUid, boolean isAuthEntry) { try { + if (isAuthEntry) { + collectAuthEntryUpdate(isFailureStatus, isCompletionStatus, providerSessionUid); + return; + } mCandidatePhasePerProviderMetric.setCandidateUid(providerSessionUid); mCandidatePhasePerProviderMetric .setQueryFinishTimeNanoseconds(System.nanoTime()); @@ -119,7 +138,6 @@ public class ProviderSessionMetric { */ public void collectCandidateMetricSetupViaInitialMetric(InitialPhaseMetric initMetric) { try { - mCandidatePhasePerProviderMetric.setSessionId(MetricUtilities.getHighlyUniqueInteger()); mCandidatePhasePerProviderMetric.setServiceBeganTimeNanoseconds( initMetric.getCredentialServiceStartedTimeNanoseconds()); mCandidatePhasePerProviderMetric.setStartQueryTimeNanoseconds(System.nanoTime()); @@ -133,13 +151,14 @@ public class ProviderSessionMetric { * purposes. * * @param response contains entries and data from the candidate provider responses + * @param isAuthEntry indicates if this is an auth entry collection or not * @param the response type associated with the API flow in progress */ - public void collectCandidateEntryMetrics(R response) { + public void collectCandidateEntryMetrics(R response, boolean isAuthEntry) { try { if (response instanceof BeginGetCredentialResponse) { beginGetCredentialResponseCollectionCandidateEntryMetrics( - (BeginGetCredentialResponse) response); + (BeginGetCredentialResponse) response, isAuthEntry); } else if (response instanceof BeginCreateCredentialResponse) { beginCreateCredentialResponseCollectionCandidateEntryMetrics( (BeginCreateCredentialResponse) response); @@ -198,7 +217,7 @@ public class ProviderSessionMetric { } private void beginGetCredentialResponseCollectionCandidateEntryMetrics( - BeginGetCredentialResponse response) { + BeginGetCredentialResponse response, boolean isAuthEntry) { Map entryCounts = new LinkedHashMap<>(); Map responseCounts = new LinkedHashMap<>(); int numCredEntries = response.getCredentialEntries().size(); @@ -217,6 +236,11 @@ public class ProviderSessionMetric { }); ResponseCollective responseCollective = new ResponseCollective(responseCounts, entryCounts); - mCandidatePhasePerProviderMetric.setResponseCollective(responseCollective); + + if (!isAuthEntry) { + mCandidatePhasePerProviderMetric.setResponseCollective(responseCollective); + } else { + // TODO(b/immediately) - Add the auth entry get logic + } } } diff --git a/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java b/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java index 0c43f6fab6927..a399b1935accf 100644 --- a/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java +++ b/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java @@ -27,7 +27,6 @@ import android.credentials.GetCredentialRequest; import android.credentials.ui.UserSelectionDialogResult; import android.util.Slog; -import com.android.server.credentials.MetricUtilities; import com.android.server.credentials.ProviderSession; import java.util.ArrayList; @@ -49,17 +48,24 @@ public class RequestSessionMetric { // As emits occur in sequential order, increment this counter and utilize protected int mSequenceCounter = 0; - protected final InitialPhaseMetric mInitialPhaseMetric = new InitialPhaseMetric(); + protected final InitialPhaseMetric mInitialPhaseMetric; protected final ChosenProviderFinalPhaseMetric - mChosenProviderFinalPhaseMetric = new ChosenProviderFinalPhaseMetric(); + mChosenProviderFinalPhaseMetric; // TODO(b/271135048) - Replace this with a new atom per each browsing emit (V4) protected List mCandidateBrowsingPhaseMetric = new ArrayList<>(); // Specific aggregate candidate provider metric for the provider this session handles @NonNull - protected final CandidateAggregateMetric mCandidateAggregateMetric = - new CandidateAggregateMetric(); + protected final CandidateAggregateMetric mCandidateAggregateMetric; + // Since track two is shared, this allows provider sessions to capture a metric-specific + // session token for the flow where the provider is known + private final int mSessionIdTrackTwo; - public RequestSessionMetric() { + public RequestSessionMetric(int sessionIdTrackOne, int sessionIdTrackTwo) { + mSessionIdTrackTwo = sessionIdTrackTwo; + mInitialPhaseMetric = new InitialPhaseMetric(sessionIdTrackOne); + mCandidateAggregateMetric = new CandidateAggregateMetric(sessionIdTrackOne); + mChosenProviderFinalPhaseMetric = new ChosenProviderFinalPhaseMetric( + sessionIdTrackOne, sessionIdTrackTwo); } /** @@ -93,12 +99,13 @@ public class RequestSessionMetric { * @param timestampStarted the timestamp the service begins at * @param mCallingUid the calling process's uid * @param metricCode typically pulled from {@link ApiName} + * @param callingAppFlowUniqueInt the unique integer used as the session id for the calling app + * known flow */ public void collectInitialPhaseMetricInfo(long timestampStarted, - int mCallingUid, int metricCode) { + int mCallingUid, int metricCode, int callingAppFlowUniqueInt) { try { mInitialPhaseMetric.setCredentialServiceStartedTimeNanoseconds(timestampStarted); - mInitialPhaseMetric.setSessionId(MetricUtilities.getHighlyUniqueInteger()); mInitialPhaseMetric.setCallerUid(mCallingUid); mInitialPhaseMetric.setApiName(metricCode); } catch (Exception e) { @@ -284,7 +291,6 @@ public class RequestSessionMetric { */ public void collectChosenMetricViaCandidateTransfer(CandidatePhaseMetric candidatePhaseMetric) { try { - mChosenProviderFinalPhaseMetric.setSessionId(candidatePhaseMetric.getSessionId()); mChosenProviderFinalPhaseMetric.setChosenUid(candidatePhaseMetric.getCandidateUid()); mChosenProviderFinalPhaseMetric.setQueryPhaseLatencyMicroseconds( @@ -370,4 +376,7 @@ public class RequestSessionMetric { } } + public int getSessionIdTrackTwo() { + return mSessionIdTrackTwo; + } }