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

Commit e4166e13 authored by Hakjun Choi's avatar Hakjun Choi
Browse files

Verify metrics for Satellite CTS TC

It is needed to provide a way to verify actually logged metrics data is as expected after each CTS run.

Bug: 415833572
Flag: EXEMPT bug fix
Test: run satellite CTS then verified metrics data
Test: manually run live e2e test for regression b/425894570
Change-Id: I412bfb6a81349c4f48a670ce13673dd5c9f9d43f
parent 81c7a18d
Loading
Loading
Loading
Loading
+55 −2
Original line number Diff line number Diff line
@@ -16,7 +16,11 @@

package com.android.internal.telephony;

import android.annotation.NonNull;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Base64;

import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.telephony.Rlog;
@@ -33,10 +37,12 @@ import java.io.PrintWriter;
 */
public class DebugService {
    private static String TAG = "DebugService";
    private final Context mContext;

    /** Constructor */
    public DebugService() {
    public DebugService(@NonNull Context context) {
        log("DebugService:");
        mContext = context;
    }

    /**
@@ -58,9 +64,52 @@ public class DebugService {
                    }
                    return;
                case "--clearatoms":
                    if (Build.IS_DEBUGGABLE) {
                    if (Build.IS_DEBUGGABLE || mContext.checkCallingOrSelfPermission(
                            android.Manifest.permission.DUMP)
                            == PackageManager.PERMISSION_GRANTED) {
                        log("Clearing atoms..");
                        PhoneFactory.getMetricsCollector().clearAtomsStorage();

                        if (args.length > 1 && "--saveFileImmediately".equals(args[1])) {
                            log("Setting save-immediately mode to true after clearing.");
                            PhoneFactory.getMetricsCollector().setSaveFileImmediately(true);
                        } else {
                            log("Restoring default save-delay mode after clearing.");
                            PhoneFactory.getMetricsCollector().setSaveFileImmediately(false);
                        }
                    } else {
                        pw.println("ERROR: Failed to clear atom, does not have permission.");
                        logw("Clearing atoms.. failed, does not have permission");
                    }
                    return;
                case "--pullAtomsBase64":
                    if (Build.IS_DEBUGGABLE || mContext.checkCallingOrSelfPermission(
                            android.Manifest.permission.DUMP)
                            == PackageManager.PERMISSION_GRANTED) {
                        log("Pulling atoms..");
                        try {
                            // This method should be implemented to get the real atom proto
                            // from PersistAtomsStorage and serialize it to bytes.
                            byte[] atomProtoBytes =
                                    PhoneFactory.getMetricsCollector().getAtomsProtoBytes();

                            if (atomProtoBytes != null) {
                                // Encode byte array to Base64 String and print it.
                                String base64String = Base64.encodeToString(atomProtoBytes,
                                        Base64.NO_WRAP);
                                pw.println(base64String);
                            }

                            if (args.length > 1 && "--clearAtoms".equals(args[1])) {
                                log("clear atoms after pulling.");
                                PhoneFactory.getMetricsCollector().clearAtomsStorage();
                                PhoneFactory.getMetricsCollector().setSaveFileImmediately(true);
                            }
                        } catch (Exception e) {
                            Rlog.e(TAG, "Failed to get/encode atom data", e);
                        }
                    } else {
                        logw("Pulling atoms.. failed does not have permission");
                    }
                    return;
            }
@@ -72,4 +121,8 @@ public class DebugService {
    private static void log(String s) {
        Rlog.d(TAG, "DebugService " + s);
    }

    private static void logw(String s) {
        Rlog.w(TAG, "DebugService " + s);
    }
}
+18 −0
Original line number Diff line number Diff line
@@ -384,6 +384,24 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
        mStorage.clearAtoms();
    }

    /** For CTS test purpose only. Sets whether atoms should be saved immediately. */
    public void setSaveFileImmediately(boolean enable) {
        mStorage.setSaveImmediately(enable);
    }

    /**
     * Retrieves the persisted atoms from storage as a serialized byte array.
     * <p>
     * This is a pass-through method to get the raw protobuf data for debugging
     * or CTS verification purposes.
     *
     * @return A byte array representing the serialized atom data.
     */
    public byte[] getAtomsProtoBytes() {
        concludeAll();
        return mStorage.getAtomsProtoBytes();
    }

    /**
     * Registers a {@link DataCallSessionStats} which will be pinged for on-going data calls when
     * data call atoms are pulled.
+32 −4
Original line number Diff line number Diff line
@@ -774,6 +774,7 @@ public class PersistAtomsStorage {
            existingStats.countOfDisallowedSatelliteAccess
                    += stats.countOfDisallowedSatelliteAccess;
            existingStats.countOfSatelliteAccessCheckFail += stats.countOfSatelliteAccessCheckFail;
            existingStats.isProvisioned = stats.isProvisioned;
            // Does not update isProvisioned and carrierId due to they are dimension fields.
            existingStats.countOfSatelliteAllowedStateChangedEvents
                    += stats.countOfSatelliteAllowedStateChangedEvents;
@@ -784,7 +785,7 @@ public class PersistAtomsStorage {
                    += stats.countOfP2PSmsAvailableNotificationShown;
            existingStats.countOfP2PSmsAvailableNotificationRemoved
                    += stats.countOfP2PSmsAvailableNotificationRemoved;
            // Does not update isNtnOnlyCarrier due to it is a dimension field.
            existingStats.isNtnOnlyCarrier = stats.isNtnOnlyCarrier;
            existingStats.versionOfSatelliteAccessConfig = stats.versionOfSatelliteAccessConfig;
            existingStats.countOfIncomingDatagramTypeSosSmsSuccess
                    += stats.countOfIncomingDatagramTypeSosSmsSuccess;
@@ -1728,6 +1729,25 @@ public class PersistAtomsStorage {
        saveAtomsToFile(0);
    }

    /**
     * Gets the in-memory atoms as a serialized byte array.
     * <p>
     * This method serializes the current state of the in-memory {@link PersistAtoms}
     * into a byte array, which can be used for exporting or debugging.
     *
     * @return A byte array representing the serialized atom data, or null if the
     *         in-memory atoms object is null.
     */
    @Nullable
    public synchronized byte[] getAtomsProtoBytes() {
        if (mAtoms == null) {
            Rlog.w(TAG, "getAtomsProtoBytes: mAtoms is null, returning null.");
            return null;
        }

        return PersistAtoms.toByteArray(mAtoms);
    }

    /** Loads {@link PersistAtoms} from a file in private storage. */
    private PersistAtoms loadAtomsFromFile() {
        try {
@@ -2432,9 +2452,7 @@ public class PersistAtomsStorage {
     */
    private @Nullable SatelliteController find(SatelliteController key) {
        for (SatelliteController stats : mAtoms.satelliteController) {
            if (stats.carrierId == key.carrierId
                    && stats.isProvisioned == key.isProvisioned
                    && stats.isNtnOnlyCarrier == key.isNtnOnlyCarrier) {
            if (stats.carrierId == key.carrierId) {
                return stats;
            }
        }
@@ -2758,4 +2776,14 @@ public class PersistAtomsStorage {
        // Epoch time in UTC, preserved across reboots, but can be adjusted e.g. by the user or NTP
        return System.currentTimeMillis();
    }

    /**
     * For CTS test purpose only. Sets whether atoms should be saved immediately.
     *
     * @param enabled true to enable immediate saving.
     */
    public synchronized void setSaveImmediately(boolean enabled) {
        Rlog.d(TAG, "setSaveImmediately(" + enabled + ")");
        mSaveImmediately = enabled;
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -950,6 +950,7 @@ public class SatelliteStats {
                    + mCountOfP2PSmsAvailableNotificationShown
                    + ", countOfP2PSmsAvailableNotificationRemoved="
                    + mCountOfP2PSmsAvailableNotificationRemoved
                    + ", isNtnOnlyCarrier=" + sIsNtnOnlyCarrier
                    + ", versionOfSatelliteAccessConfig=" + sVersionOfSatelliteAccessConfig
                    + ", countOfIncomingDatagramTypeSosSmsSuccess="
                    + mCountOfIncomingDatagramTypeSosSmsSuccess
@@ -3377,10 +3378,10 @@ public class SatelliteStats {
        proto.initializationProcessingTimeMillis = param.getInitializationProcessingTime();
        proto.terminationProcessingTimeMillis = param.getTerminationProcessingTime();
        proto.sessionDurationSeconds = param.getSessionDuration();
        proto.countOfOutgoingDatagramSuccess = param.getCountOfIncomingDatagramSuccess();
        proto.countOfOutgoingDatagramSuccess = param.getCountOfOutgoingDatagramSuccess();
        proto.countOfOutgoingDatagramFailed = param.getCountOfOutgoingDatagramFailed();
        proto.countOfIncomingDatagramSuccess = param.getCountOfIncomingDatagramSuccess();
        proto.countOfIncomingDatagramFailed = param.getCountOfOutgoingDatagramFailed();
        proto.countOfIncomingDatagramFailed = param.getCountOfIncomingDatagramFailed();
        proto.isDemoMode = param.getIsDemoMode();
        proto.maxNtnSignalStrengthLevel = param.getMaxNtnSignalStrengthLevel();
        proto.carrierId = param.getCarrierId();
+9 −12
Original line number Diff line number Diff line
@@ -1583,16 +1583,19 @@ public class SatelliteController extends Handler {
                                    getElapsedRealtime() - mSessionProcessingTimeStamp.get())
                            .setIsDemoMode(mIsDemoModeEnabled.get())
                            .setCarrierId(getSatelliteCarrierId())
                            .setIsNtnOnlyCarrier(isNtnOnlyCarrier())
                            .setIsEmergency(argument.isEmergency);
                    mSessionProcessingTimeStamp.set(0);

                    if (error == SATELLITE_RESULT_SUCCESS) {
                        mControllerMetricsStats.onSatelliteEnabled();
                        mControllerMetricsStats.reportServiceEnablementSuccessCount();
                        mControllerMetricsStats.reportServiceEnablementSuccessCount(
                                argument.enableDemoMode);
                    } else {
                        mSessionMetricsStats.reportSessionMetrics();
                        mSessionStartTimeStamp.set(0);
                        mControllerMetricsStats.reportServiceEnablementFailCount();
                        mControllerMetricsStats.reportServiceEnablementFailCount(
                                argument.enableDemoMode);
                    }
                } else {
                    mSessionMetricsStats.setTerminationResult(error)
@@ -2972,9 +2975,8 @@ public class SatelliteController extends Handler {
            if (resultCode != SatelliteManager.SATELLITE_RESULT_SUCCESS) {
                plogd("requestSatelliteEnabled enable satellite is already in progress.");
            }
            sendErrorAndReportSessionMetrics(resultCode, result);
            result.accept(resultCode);
        }
        return;
    }

    /**
@@ -7382,13 +7384,14 @@ public class SatelliteController extends Handler {
                sendRequestAsync(CMD_SET_SATELLITE_ENABLED, request, null);
            }

            mControllerMetricsStats.reportServiceEnablementFailCount();
            mControllerMetricsStats.reportServiceEnablementFailCount(argument.enableDemoMode);
            mSessionMetricsStats.setInitializationResult(SATELLITE_RESULT_MODEM_TIMEOUT)
                    .setSatelliteTechnology(getSupportedNtnRadioTechnology())
                    .setInitializationProcessingTime(
                            getElapsedRealtime() - mSessionProcessingTimeStamp.get())
                    .setIsDemoMode(mIsDemoModeEnabled.get())
                    .setCarrierId(getSatelliteCarrierId())
                    .setIsNtnOnlyCarrier(isNtnOnlyCarrier())
                    .reportSessionMetrics();
        } else {
            resetSatelliteDisabledRequest();
@@ -8423,13 +8426,7 @@ public class SatelliteController extends Handler {

        setSatellitePhone(selectedSubId);
        if (selectedSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
            int carrierId = getSatelliteCarrierId();
            if (carrierId != UNKNOWN_CARRIER_ID) {
                mControllerMetricsStats.setCarrierId(carrierId);
            } else {
                logd("selectBindingSatelliteSubscription: Carrier ID is UNKNOWN_CARRIER_ID");
            }
            mControllerMetricsStats.setIsNtnOnlyCarrier(isNtnOnlyCarrier());
            mControllerMetricsStats.setCarrierIdInfo(getSatelliteCarrierId(), isNtnOnlyCarrier());
        }
        plogd("selectBindingSatelliteSubscription: SelectedSatelliteSubId=" + selectedSubId);
    }
Loading