Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 990e33e9 authored by Arpan Kaphle's avatar Arpan Kaphle
Browse files

Adding isEnabled and Improving Metric Design

isEnabled has a different flow from the rest of the logging, so I've
redesigned the metric logging objects to account for this. We will have
different logging methods, and have a more contained way to call the
constants.

Bug: 269290341
Test: Testing locally
Change-Id: I881594e6e02b7752a57000792eb09f0415ddce82
parent e56fc10a
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -29,6 +29,9 @@ import android.service.credentials.CallingAppInfo;
import android.service.credentials.CredentialProviderInfo;
import android.util.Log;

import com.android.server.credentials.metrics.ApiName;
import com.android.server.credentials.metrics.ApiStatus;

import java.util.ArrayList;

/**
@@ -119,18 +122,21 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta
            // TODO: Differentiate btw cancelled and false
            mChosenProviderMetric.setChosenProviderStatus(
                    MetricUtilities.METRICS_PROVIDER_STATUS_FINAL_SUCCESS);
            logApiCalled(RequestType.CLEAR_CREDENTIALS, /* isSuccessful */ true);
            logApiCall(ApiName.CLEAR_CREDENTIAL, /* apiStatus */
                    ApiStatus.METRICS_API_STATUS_CLIENT_CANCELED);
            finishSession(/*propagateCancellation=*/true);
            return;
        }
        try {
            mClientCallback.onSuccess();
            logApiCalled(RequestType.CLEAR_CREDENTIALS, /* isSuccessful */ true);
            logApiCall(ApiName.CLEAR_CREDENTIAL, /* apiStatus */
                    ApiStatus.METRICS_API_STATUS_SUCCESS);
        } catch (RemoteException e) {
            mChosenProviderMetric.setChosenProviderStatus(
                    MetricUtilities.METRICS_PROVIDER_STATUS_FINAL_FAILURE);
            Log.i(TAG, "Issue while propagating the response to the client");
            logApiCalled(RequestType.CLEAR_CREDENTIALS, /* isSuccessful */ false);
            logApiCall(ApiName.CLEAR_CREDENTIAL, /* apiStatus */
                    ApiStatus.METRICS_API_STATUS_FAILURE);
        }
        finishSession(/*propagateCancellation=*/false);
    }
@@ -139,7 +145,8 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta
        Log.i(TAG, "respondToClientWithErrorAndFinish");
        if (isSessionCancelled()) {
            // TODO: Differentiate btw cancelled and false
            logApiCalled(RequestType.CLEAR_CREDENTIALS, /* isSuccessful */ true);
            logApiCall(ApiName.CLEAR_CREDENTIAL, /* apiStatus */
                    ApiStatus.METRICS_API_STATUS_CLIENT_CANCELED);
            finishSession(/*propagateCancellation=*/true);
            return;
        }
@@ -148,7 +155,8 @@ public final class ClearRequestSession extends RequestSession<ClearCredentialSta
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        logApiCalled(RequestType.CLEAR_CREDENTIALS, /* isSuccessful */ false);
        logApiCall(ApiName.CLEAR_CREDENTIAL, /* apiStatus */
                ApiStatus.METRICS_API_STATUS_FAILURE);
        finishSession(/*propagateCancellation=*/false);
    }

+22 −5
Original line number Diff line number Diff line
@@ -36,6 +36,9 @@ import android.service.credentials.CallingAppInfo;
import android.service.credentials.CredentialProviderInfo;
import android.util.Log;

import com.android.server.credentials.metrics.ApiName;
import com.android.server.credentials.metrics.ApiStatus;

import java.util.ArrayList;

/**
@@ -141,16 +144,19 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
        }
        if (isSessionCancelled()) {
            // TODO: Differentiate btw cancelled and false
            logApiCalled(RequestType.CREATE_CREDENTIALS, /* isSuccessful */ true);
            logApiCall(ApiName.CREATE_CREDENTIAL, /* apiStatus */
                    ApiStatus.METRICS_API_STATUS_CLIENT_CANCELED);
            finishSession(/*propagateCancellation=*/true);
            return;
        }
        try {
            mClientCallback.onResponse(response);
            logApiCalled(RequestType.CREATE_CREDENTIALS, /* isSuccessful */ true);
            logApiCall(ApiName.CREATE_CREDENTIAL, /* apiStatus */
                    ApiStatus.METRICS_API_STATUS_SUCCESS);
        } catch (RemoteException e) {
            Log.i(TAG, "Issue while responding to client: " + e.getMessage());
            logApiCalled(RequestType.CREATE_CREDENTIALS, /* isSuccessful */ false);
            logApiCall(ApiName.CREATE_CREDENTIAL, /* apiStatus */
                    ApiStatus.METRICS_API_STATUS_FAILURE);
        }
        finishSession(/*propagateCancellation=*/false);
    }
@@ -163,7 +169,8 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
        }
        if (isSessionCancelled()) {
            // TODO: Differentiate btw cancelled and false
            logApiCalled(RequestType.CREATE_CREDENTIALS, /* isSuccessful */ true);
            logApiCall(ApiName.CREATE_CREDENTIAL, /* apiStatus */
                    ApiStatus.METRICS_API_STATUS_CLIENT_CANCELED);
            finishSession(/*propagateCancellation=*/true);
            return;
        }
@@ -172,10 +179,20 @@ public final class CreateRequestSession extends RequestSession<CreateCredentialR
        } catch (RemoteException e) {
            Log.i(TAG, "Issue while responding to client: " + e.getMessage());
        }
        logApiCalled(RequestType.CREATE_CREDENTIALS, /* isSuccessful */ false);
        logFailureOrUserCancel(errorType);
        finishSession(/*propagateCancellation=*/false);
    }

    private void logFailureOrUserCancel(String errorType) {
        if (CreateCredentialException.TYPE_USER_CANCELED.equals(errorType)) {
            logApiCall(ApiName.CREATE_CREDENTIAL,
                    /* apiStatus */ ApiStatus.METRICS_API_STATUS_USER_CANCELED);
        } else {
            logApiCall(ApiName.CREATE_CREDENTIAL,
                    /* apiStatus */ ApiStatus.METRICS_API_STATUS_FAILURE);
        }
    }

    @Override
    public void onProviderStatusChanged(ProviderSession.Status status,
            ComponentName componentName) {
+56 −49
Original line number Diff line number Diff line
@@ -64,6 +64,8 @@ import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.server.credentials.metrics.ApiName;
import com.android.server.credentials.metrics.ApiStatus;
import com.android.server.infra.AbstractMasterSystemService;
import com.android.server.infra.SecureSettingsServiceNameResolver;

@@ -267,7 +269,8 @@ public final class CredentialManagerService
        final long origId = Binder.clearCallingIdentity();
        try {
            return DeviceConfig.getBoolean(
                DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API, false);
                    DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API,
                    false);
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
@@ -654,13 +657,17 @@ public final class CredentialManagerService
                    if (serviceComponentName.equals(componentName)) {
                        if (!s.getServicePackageName().equals(callingPackage)) {
                            // The component name and the package name do not match.
                            MetricUtilities.logApiCalled(
                                    ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE,
                                    ApiStatus.METRICS_API_STATUS_FAILURE, callingUid);
                            Log.w(
                                    TAG,
                                    "isEnabledCredentialProviderService: Component name does not"
                                            + " match package name.");
                            return false;
                        }

                        MetricUtilities.logApiCalled(ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE,
                                ApiStatus.METRICS_API_STATUS_SUCCESS, callingUid);
                        return true;
                    }
                }
+22 −5
Original line number Diff line number Diff line
@@ -34,6 +34,9 @@ import android.service.credentials.CallingAppInfo;
import android.service.credentials.CredentialProviderInfo;
import android.util.Log;

import com.android.server.credentials.metrics.ApiName;
import com.android.server.credentials.metrics.ApiStatus;

import java.util.ArrayList;

/**
@@ -117,16 +120,19 @@ public final class GetRequestSession extends RequestSession<GetCredentialRequest
        }
        if (isSessionCancelled()) {
            // TODO: Differentiate btw cancelled and false
            logApiCalled(RequestType.GET_CREDENTIALS, /* isSuccessful */ false);
            logApiCall(ApiName.GET_CREDENTIAL, /* apiStatus */
                    ApiStatus.METRICS_API_STATUS_CLIENT_CANCELED);
            finishSession(/*propagateCancellation=*/true);
            return;
        }
        try {
            mClientCallback.onResponse(response);
            logApiCalled(RequestType.GET_CREDENTIALS, /* isSuccessful */ true);
            logApiCall(ApiName.GET_CREDENTIAL, /* apiStatus */
                    ApiStatus.METRICS_API_STATUS_SUCCESS);
        } catch (RemoteException e) {
            Log.i(TAG, "Issue while responding to client with a response : " + e.getMessage());
            logApiCalled(RequestType.GET_CREDENTIALS, /* isSuccessful */ false);
            logApiCall(ApiName.GET_CREDENTIAL, /* apiStatus */
                    ApiStatus.METRICS_API_STATUS_FAILURE);
        }
        finishSession(/*propagateCancellation=*/false);
    }
@@ -137,7 +143,8 @@ public final class GetRequestSession extends RequestSession<GetCredentialRequest
            return;
        }
        if (isSessionCancelled()) {
            logApiCalled(RequestType.GET_CREDENTIALS, /* isSuccessful */ false);
            logApiCall(ApiName.GET_CREDENTIAL, /* apiStatus */
                    ApiStatus.METRICS_API_STATUS_CLIENT_CANCELED);
            finishSession(/*propagateCancellation=*/true);
            return;
        }
@@ -147,10 +154,20 @@ public final class GetRequestSession extends RequestSession<GetCredentialRequest
        } catch (RemoteException e) {
            Log.i(TAG, "Issue while responding to client with error : " + e.getMessage());
        }
        logApiCalled(RequestType.GET_CREDENTIALS, /* isSuccessful */ false);
        logFailureOrUserCancel(errorType);
        finishSession(/*propagateCancellation=*/false);
    }

    private void logFailureOrUserCancel(String errorType) {
        if (GetCredentialException.TYPE_USER_CANCELED.equals(errorType)) {
            logApiCall(ApiName.GET_CREDENTIAL,
                    /* apiStatus */ ApiStatus.METRICS_API_STATUS_USER_CANCELED);
        } else {
            logApiCall(ApiName.GET_CREDENTIAL,
                    /* apiStatus */ ApiStatus.METRICS_API_STATUS_FAILURE);
        }
    }

    @Override
    public void onUiCancellation(boolean isUserCancellation) {
        if (isUserCancellation) {
+84 −26
Original line number Diff line number Diff line
@@ -16,14 +16,6 @@

package com.android.server.credentials;

import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_CLEAR_CREDENTIAL;
import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_CREATE_CREDENTIAL;
import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_GET_CREDENTIAL;
import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_UNKNOWN;
import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_CLIENT_CANCELED;
import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_FAILURE;
import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_SUCCESS;
import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_USER_CANCELED;
import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_FINAL_FAILURE;
import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_FINAL_SUCCESS;
import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_QUERY_FAILURE;
@@ -35,6 +27,14 @@ import android.content.Context;
import android.content.pm.PackageManager;
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.ChosenProviderMetric;

import java.util.Map;

/**
 * For all future metric additions, this will contain their names for local usage after importing
 * from {@link com.android.internal.util.FrameworkStatsLog}.
@@ -43,24 +43,10 @@ public class MetricUtilities {

    private static final String TAG = "MetricUtilities";

    // Metrics constants
    protected static final int METRICS_API_NAME_UNKNOWN =
            CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_UNKNOWN;
    protected static final int METRICS_API_NAME_GET_CREDENTIAL =
            CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_GET_CREDENTIAL;
    protected static final int METRICS_API_NAME_CREATE_CREDENTIAL =
            CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_CREATE_CREDENTIAL;
    protected static final int METRICS_API_NAME_CLEAR_CREDENTIAL =
            CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_CLEAR_CREDENTIAL;
    // TODO add isEnabled
    protected static final int METRICS_API_STATUS_SUCCESS =
            CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_SUCCESS;
    protected static final int METRICS_API_STATUS_FAILURE =
            CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_FAILURE;
    protected static final int METRICS_API_STATUS_CLIENT_CANCEL =
            CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_CLIENT_CANCELED;
    protected static final int METRICS_API_STATUS_USER_CANCEL =
            CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_USER_CANCELED;
    private static final int DEFAULT_INT_32 = -1;
    private static final int[] DEFAULT_REPEATED_INT_32 = new int[0];

    // Metrics constants TODO(b/269290341) migrate to enums eventually to improve
    protected static final int METRICS_PROVIDER_STATUS_FINAL_FAILURE =
            CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_FINAL_FAILURE;
    protected static final int METRICS_PROVIDER_STATUS_QUERY_FAILURE =
@@ -77,6 +63,7 @@ public class MetricUtilities {
     * This retrieves the uid of any package name, given a context and a component name for the
     * package. By default, if the desired package uid cannot be found, it will fall back to a
     * bogus uid.
     *
     * @return the uid of a given package
     */
    protected static int getPackageUid(Context context, ComponentName componentName) {
@@ -92,4 +79,75 @@ public class MetricUtilities {
        return sessUid;
    }

    /**
     * The most common logging helper, handles the overall status of the API request with the
     * provider status and latencies. Other versions of this method may be more useful depending
     * on the situation, as this is geared towards the logging of {@link ProviderSession} types.
     *
     * @param apiName              the api type to log
     * @param apiStatus            the api status to log
     * @param providers            a map with known providers
     * @param callingUid           the calling UID of the client app
     * @param chosenProviderMetric the metric data type of the final chosen provider
     */
    protected static void logApiCalled(ApiName apiName, ApiStatus apiStatus,
            Map<String, ProviderSession> providers, int callingUid,
            ChosenProviderMetric chosenProviderMetric) {
        var providerSessions = providers.values();
        int providerSize = providerSessions.size();
        int[] candidateUidList = new int[providerSize];
        int[] candidateQueryRoundTripTimeList = new int[providerSize];
        int[] candidateStatusList = new int[providerSize];
        int index = 0;
        for (var session : providerSessions) {
            CandidateProviderMetric metric = session.mCandidateProviderMetric;
            candidateUidList[index] = metric.getCandidateUid();
            candidateQueryRoundTripTimeList[index] = metric.getQueryLatencyMs();
            candidateStatusList[index] = metric.getProviderQueryStatus();
            index++;
        }
        FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED,
                /* api_name */apiName.getMetricCode(),
                /* caller_uid */ callingUid,
                /* api_status */ apiStatus.getMetricCode(),
                /* repeated_candidate_provider_uid */ candidateUidList,
                /* repeated_candidate_provider_round_trip_time_query_microseconds */
                candidateQueryRoundTripTimeList,
                /* repeated_candidate_provider_status */ candidateStatusList,
                /* chosen_provider_uid */ chosenProviderMetric.getChosenUid(),
                /* chosen_provider_round_trip_time_overall_microseconds */
                chosenProviderMetric.getEntireProviderLatencyMs(),
                /* chosen_provider_final_phase_microseconds */
                chosenProviderMetric.getFinalPhaseLatencyMs(),
                /* chosen_provider_status */ chosenProviderMetric.getChosenProviderStatus());
    }

    /**
     * This is useful just to record an API calls' final event, and for no other purpose. It will
     * contain default values for all other optional parameters.
     *
     * TODO(b/271135048) - given space requirements, this may be a good candidate for another atom
     *
     * @param apiName    the api name to log
     * @param apiStatus  the status to log
     * @param callingUid the calling uid
     */
    protected static void logApiCalled(ApiName apiName, ApiStatus apiStatus,
            int callingUid) {
        FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED,
                /* api_name */apiName.getMetricCode(),
                /* caller_uid */ callingUid,
                /* api_status */ apiStatus.getMetricCode(),
                /* repeated_candidate_provider_uid */  DEFAULT_REPEATED_INT_32,
                /* repeated_candidate_provider_round_trip_time_query_microseconds */
                DEFAULT_REPEATED_INT_32,
                /* repeated_candidate_provider_status */ DEFAULT_REPEATED_INT_32,
                /* chosen_provider_uid */ DEFAULT_INT_32,
                /* chosen_provider_round_trip_time_overall_microseconds */
                DEFAULT_INT_32,
                /* chosen_provider_final_phase_microseconds */
                DEFAULT_INT_32,
                /* chosen_provider_status */ DEFAULT_INT_32);
    }

}
Loading