Adding isPrimary to Final Phase Metrics

This captures, for any API flows, if the chosen provider was the primary
provider. It's the first of a few changes that capture these additional
details and smaller API metrics.

Bug: 271135048
Test: Build and Won't Submit without E2E Test
Change-Id: Ib3870fb1f1f0ce870dd05bc1fc3901b5ef9e8200
This commit is contained in:
Arpan Kaphle
2023-05-04 20:02:28 +00:00
parent e68cc2f42b
commit 8fad04bb1d
7 changed files with 55 additions and 26 deletions

View File

@@ -30,8 +30,6 @@ import android.os.RemoteException;
import android.service.credentials.CallingAppInfo;
import android.util.Slog;
import com.android.server.credentials.metrics.ProviderSessionMetric;
import java.util.ArrayList;
import java.util.Set;
@@ -95,12 +93,8 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta
public void onFinalResponseReceived(
ComponentName componentName,
Void response) {
if (mProviders.get(componentName.flattenToString()) != null) {
ProviderSessionMetric providerSessionMetric =
mProviders.get(componentName.flattenToString()).mProviderSessionMetric;
mRequestSessionMetric.collectChosenMetricViaCandidateTransfer(providerSessionMetric
.getCandidatePhasePerProviderMetric());
}
mRequestSessionMetric.updateMetricsOnResponseReceived(mProviders, componentName,
isPrimaryProviderViaProviderInfo(componentName));
respondToClientWithResponseAndFinish(null);
}

View File

@@ -35,7 +35,6 @@ import android.service.credentials.CallingAppInfo;
import android.service.credentials.PermissionUtils;
import android.util.Slog;
import com.android.server.credentials.metrics.ProviderSessionMetric;
import com.android.server.credentials.metrics.ProviderStatusForMetrics;
import java.util.ArrayList;
@@ -132,12 +131,8 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
@Nullable CreateCredentialResponse response) {
Slog.i(TAG, "Final credential received from: " + componentName.flattenToString());
mRequestSessionMetric.collectUiResponseData(/*uiReturned=*/ true, System.nanoTime());
if (mProviders.get(componentName.flattenToString()) != null) {
ProviderSessionMetric providerSessionMetric =
mProviders.get(componentName.flattenToString()).mProviderSessionMetric;
mRequestSessionMetric.collectChosenMetricViaCandidateTransfer(providerSessionMetric
.getCandidatePhasePerProviderMetric());
}
mRequestSessionMetric.updateMetricsOnResponseReceived(mProviders, componentName,
isPrimaryProviderViaProviderInfo(componentName));
if (response != null) {
mRequestSessionMetric.collectChosenProviderStatus(
ProviderStatusForMetrics.FINAL_SUCCESS.getMetricCode());

View File

@@ -34,7 +34,6 @@ import android.service.credentials.CallingAppInfo;
import android.service.credentials.PermissionUtils;
import android.util.Slog;
import com.android.server.credentials.metrics.ProviderSessionMetric;
import com.android.server.credentials.metrics.ProviderStatusForMetrics;
import java.util.ArrayList;
@@ -134,13 +133,8 @@ public class GetRequestSession extends RequestSession<GetCredentialRequest,
public void onFinalResponseReceived(ComponentName componentName,
@Nullable GetCredentialResponse response) {
Slog.i(TAG, "onFinalResponseReceived from: " + componentName.flattenToString());
mRequestSessionMetric.collectUiResponseData(/*uiReturned=*/ true, System.nanoTime());
if (mProviders.get(componentName.flattenToString()) != null) {
ProviderSessionMetric providerSessionMetric =
mProviders.get(componentName.flattenToString()).mProviderSessionMetric;
mRequestSessionMetric.collectChosenMetricViaCandidateTransfer(providerSessionMetric
.getCandidatePhasePerProviderMetric());
}
mRequestSessionMetric.updateMetricsOnResponseReceived(mProviders, componentName,
isPrimaryProviderViaProviderInfo(componentName));
if (response != null) {
mRequestSessionMetric.collectChosenProviderStatus(
ProviderStatusForMetrics.FINAL_SUCCESS.getMetricCode());

View File

@@ -188,7 +188,7 @@ public class MetricUtilities {
finalPhaseMetric.getResponseCollective().getUniqueResponseCounts(),
/* framework_exception_unique_classtype */
finalPhaseMetric.getFrameworkException(),
/* primary_indicated */ false
/* primary_indicated */ finalPhaseMetric.isPrimary()
);
} catch (Exception e) {
Slog.w(TAG, "Unexpected error during final provider uid emit: " + e);
@@ -565,7 +565,7 @@ public class MetricUtilities {
/* clicked_entries */ browsedClickedEntries,
/* provider_of_clicked_entry */ browsedProviderUid,
/* api_status */ apiStatus,
/* primary_indicated */ false
/* primary_indicated */ finalPhaseMetric.isPrimary()
);
} catch (Exception e) {
Slog.w(TAG, "Unexpected error during metric logging: " + e);

View File

@@ -361,4 +361,16 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential
mRequestSessionMetric.logFailureOrUserCancel(isUserCanceled);
finishSession(/*propagateCancellation=*/false);
}
/**
* Reveals if a certain provider is primary after ensuring it exists at all in the designated
* provider info.
*
* @param componentName used to identify the provider we want to check primary status for
*/
protected boolean isPrimaryProviderViaProviderInfo(ComponentName componentName) {
var chosenProviderSession = mProviders.get(componentName.flattenToString());
return chosenProviderSession != null && chosenProviderSession.mProviderInfo != null
&& chosenProviderSession.mProviderInfo.isPrimary();
}
}

View File

@@ -76,6 +76,8 @@ public class ChosenProviderFinalPhaseMetric {
// Stores the response credential information, as well as the response entry information which
// by default, contains empty info
private ResponseCollective mResponseCollective = new ResponseCollective(Map.of(), Map.of());
// Indicates if this chosen provider was the primary provider, false by default
private boolean mIsPrimary = false;
public ChosenProviderFinalPhaseMetric(int sessionIdCaller, int sessionIdProvider) {
@@ -292,4 +294,12 @@ public class ChosenProviderFinalPhaseMetric {
public int getSessionIdCaller() {
return mSessionIdCaller;
}
public void setPrimary(boolean primary) {
mIsPrimary = primary;
}
public boolean isPrimary() {
return mIsPrimary;
}
}

View File

@@ -28,6 +28,7 @@ import static com.android.server.credentials.MetricUtilities.logApiCalledFinalPh
import static com.android.server.credentials.MetricUtilities.logApiCalledNoUidFinal;
import android.annotation.NonNull;
import android.content.ComponentName;
import android.credentials.GetCredentialRequest;
import android.credentials.ui.UserSelectionDialogResult;
import android.util.Slog;
@@ -280,6 +281,26 @@ public class RequestSessionMetric {
}
}
/**
* Used to update metrics when a response is received in a RequestSession.
*
* @param componentName the component name associated with the provider the response is for
*/
public void updateMetricsOnResponseReceived(Map<String, ProviderSession> providers,
ComponentName componentName, boolean isPrimary) {
try {
var chosenProviderSession = providers.get(componentName.flattenToString());
if (chosenProviderSession != null) {
ProviderSessionMetric providerSessionMetric =
chosenProviderSession.getProviderSessionMetric();
collectChosenMetricViaCandidateTransfer(providerSessionMetric
.getCandidatePhasePerProviderMetric(), isPrimary);
}
} catch (Exception e) {
Slog.i(TAG, "Exception upon candidate to chosen metric transfer: " + e);
}
}
/**
* Called by RequestSessions upon chosen metric determination. It's expected that most bits
* are transferred here. However, certain new information, such as the selected provider's final
@@ -289,10 +310,13 @@ public class RequestSessionMetric {
* {@link com.android.internal.util.FrameworkStatsLog} metric generation.
*
* @param candidatePhaseMetric the componentName to associate with a provider
* @param isPrimary indicates that this chosen provider is the primary provider (or not)
*/
public void collectChosenMetricViaCandidateTransfer(CandidatePhaseMetric candidatePhaseMetric) {
public void collectChosenMetricViaCandidateTransfer(CandidatePhaseMetric candidatePhaseMetric,
boolean isPrimary) {
try {
mChosenProviderFinalPhaseMetric.setChosenUid(candidatePhaseMetric.getCandidateUid());
mChosenProviderFinalPhaseMetric.setPrimary(isPrimary);
mChosenProviderFinalPhaseMetric.setQueryPhaseLatencyMicroseconds(
candidatePhaseMetric.getQueryLatencyMicroseconds());