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

Commit 1f4143f4 authored by Mars Lin's avatar Mars Lin
Browse files

Use intent to send dsrm data to scone

Add extra 'EXTRA_DSRS_STATS_BUNDLE' to send bundled dsrm data.

Bug: 283776717
Test: Check DSRM behavior during data stall/atest pass.
Change-Id: I3e50fb122cbef2f9df7127b3bac5f6f423acfda3
parent a36a7612
Loading
Loading
Loading
Loading
+38 −13
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.Intent;
import android.net.NetworkAgent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -127,6 +128,9 @@ public class DataStallRecoveryManager extends Handler {
    /** The data stall recovered by user (Mobile Data Power off/on). */
    private static final int RECOVERED_REASON_USER = 3;

    /** Event for send data stall broadcast. */
    private static final int EVENT_SEND_DATA_STALL_BROADCAST = 1;

    /** Event for triggering recovery action. */
    private static final int EVENT_DO_RECOVERY = 2;

@@ -188,6 +192,7 @@ public class DataStallRecoveryManager extends Handler {
    private DataStallRecoveryManagerCallback mDataStallRecoveryManagerCallback;

    private final DataStallRecoveryStats mStats;

    /**
     * The data stall recovery manager callback. Note this is only used for passing information
     * internally in the data stack, should not be used externally.
@@ -289,6 +294,19 @@ public class DataStallRecoveryManager extends Handler {
    public void handleMessage(Message msg) {
        logv("handleMessage = " + msg);
        switch (msg.what) {
            case EVENT_SEND_DATA_STALL_BROADCAST:
                mRecoveryTriggered = true;
                // Verify that DSRM needs to process the recovery action
                if (!isRecoveryNeeded(false)) {
                    cancelNetworkCheckTimer();
                    startNetworkCheckTimer(getRecoveryAction());
                    return;
                }
                // Broadcast intent that data stall has been detected.
                broadcastDataStallDetected(getRecoveryAction());
                // Send EVENT_DO_RECOVERY to start recovery process.
                sendMessage(obtainMessage(EVENT_DO_RECOVERY));
                break;
            case EVENT_DO_RECOVERY:
                doRecovery();
                break;
@@ -388,7 +406,7 @@ public class DataStallRecoveryManager extends Handler {
            mIsValidNetwork = false;
            log("trigger data stall recovery");
            mTimeLastRecoveryStartMs = SystemClock.elapsedRealtime();
            sendMessage(obtainMessage(EVENT_DO_RECOVERY));
            sendMessage(obtainMessage(EVENT_SEND_DATA_STALL_BROADCAST));
        }
    }

@@ -493,6 +511,22 @@ public class DataStallRecoveryManager extends Handler {
        Intent intent = new Intent(TelephonyManager.ACTION_DATA_STALL_DETECTED);
        SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
        intent.putExtra(TelephonyManager.EXTRA_RECOVERY_ACTION, recoveryAction);

        // Get the information for DSRS state
        final boolean isRecovered = !mDataStalled;
        final int duration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs);
        final @RecoveredReason int reason = getRecoveredReason(mIsValidNetwork);
        final boolean isFirstValidationOfAction = false;
        final int durationOfAction = (int) getDurationOfCurrentRecoveryMs();

        // Get the bundled DSRS stats.
        Bundle bundle = mStats.getDataStallRecoveryMetricsData(
                recoveryAction, isRecovered, duration, reason, isFirstValidationOfAction,
                durationOfAction);

        // Put the bundled stats extras on the intent.
        intent.putExtra("EXTRA_DSRS_STATS_BUNDLE", bundle);

        mPhone.getContext().sendBroadcast(intent, READ_PRIVILEGED_PHONE_STATE);
    }

@@ -534,7 +568,8 @@ public class DataStallRecoveryManager extends Handler {
            mNetworkCheckTimerStarted = true;
            mTimeLastRecoveryStartMs = SystemClock.elapsedRealtime();
            sendMessageDelayed(
                    obtainMessage(EVENT_DO_RECOVERY), getDataStallRecoveryDelayMillis(action));
                    obtainMessage(EVENT_SEND_DATA_STALL_BROADCAST),
                    getDataStallRecoveryDelayMillis(action));
        }
    }

@@ -543,7 +578,7 @@ public class DataStallRecoveryManager extends Handler {
        log("cancelNetworkCheckTimer()");
        if (mNetworkCheckTimerStarted) {
            mNetworkCheckTimerStarted = false;
            removeMessages(EVENT_DO_RECOVERY);
            removeMessages(EVENT_SEND_DATA_STALL_BROADCAST);
        }
    }

@@ -700,22 +735,12 @@ public class DataStallRecoveryManager extends Handler {
    private void doRecovery() {
        @RecoveryAction final int recoveryAction = getRecoveryAction();
        final int signalStrength = mPhone.getSignalStrength().getLevel();
        mRecoveryTriggered = true;

        // DSRM used sendMessageDelayed to process the next event EVENT_DO_RECOVERY, so it need
        // to check the condition if DSRM need to process the recovery action.
        if (!isRecoveryNeeded(false)) {
            cancelNetworkCheckTimer();
            startNetworkCheckTimer(recoveryAction);
            return;
        }

        TelephonyMetrics.getInstance()
                .writeSignalStrengthEvent(mPhone.getPhoneId(), signalStrength);
        TelephonyMetrics.getInstance().writeDataStallEvent(mPhone.getPhoneId(), recoveryAction);
        mLastAction = recoveryAction;
        mLastActionReported = false;
        broadcastDataStallDetected(recoveryAction);
        mNetworkCheckTimerStarted = false;
        mTimeElapsedOfCurrentAction = SystemClock.elapsedRealtime();

+41 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.internal.telephony.metrics;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.NetworkCapabilities;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.telephony.AccessNetworkConstants;
@@ -304,6 +305,46 @@ public class DataStallRecoveryStats {
        }
    }

    /**
     * Return bundled data stall recovery metrics data.
     *
     * @param action The recovery action.
     * @param isRecovered Whether the data stall has been recovered.
     * @param duration The duration from data stall occurred in milliseconds.
     * @param reason The reason for the recovery.
     * @param isFirstValidation Whether this is the first validation after recovery.
     * @param durationOfAction The duration of the current action in milliseconds.
     */
    public Bundle getDataStallRecoveryMetricsData(
            @DataStallRecoveryManager.RecoveryAction int action,
            boolean isRecovered,
            int duration,
            @DataStallRecoveryManager.RecoveredReason int reason,
            boolean isFirstValidation,
            int durationOfAction) {
        Bundle bundle = new Bundle();
        bundle.putInt("Action", action);
        bundle.putBoolean("IsRecovered", isRecovered);
        bundle.putInt("Duration", duration);
        bundle.putInt("Reason", reason);
        bundle.putBoolean("IsFirstValidation", isFirstValidation);
        bundle.putInt("DurationOfAction", durationOfAction);
        bundle.putInt("PhoneId", mPhoneId);
        bundle.putInt("CarrierId", mCarrierId);
        bundle.putInt("SignalStrength", mSignalStrength);
        bundle.putInt("Band", mBand);
        bundle.putInt("Rat", mRat);
        bundle.putBoolean("IsOpportunistic", mIsOpportunistic);
        bundle.putBoolean("IsMultiSim", mIsMultiSim);
        bundle.putInt("NetworkRegState", mNetworkRegState);
        bundle.putInt("OtherSignalStrength", mOtherSignalStrength);
        bundle.putInt("OtherNetworkRegState", mOtherNetworkRegState);
        bundle.putInt("InternetLinkStatus", mInternetLinkStatus);
        bundle.putInt("LinkDownBandwidthKbps", mLinkDownBandwidthKbps);
        bundle.putInt("LinkUpBandwidthKbps", mLinkUpBandwidthKbps);
        return bundle;
    }

    private void log(@NonNull String s) {
        Rlog.i(mTag, s);
    }
+46 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.internal.telephony.data;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
@@ -25,9 +26,12 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.content.Intent;
import android.net.NetworkAgent;
import android.os.Bundle;
import android.telephony.Annotation.ValidationStatus;
import android.telephony.CarrierConfigManager;
import android.telephony.TelephonyManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;

@@ -363,4 +367,46 @@ public class DataStallRecoveryManagerTest extends TelephonyTest {
        }
        assertThat(mDataStallRecoveryManager.mDataStallStartMs != 0).isTrue();
    }

    /**
     * Tests the DSRM process to send three intents for three action changes.
     */
    @Test
    public void testSendDSRMData() throws Exception {
        ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);

        logd("Set phone status to normal status.");
        sendOnInternetDataNetworkCallback(true);
        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
        doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();

        // Set the expected behavior of the DataStallRecoveryManager.
        logd("Start DSRM process, set action to 1");
        mDataStallRecoveryManager.setRecoveryAction(1);
        logd("Sending validation failed callback");
        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
        processAllFutureMessages();

        logd("Verify that the DataStallRecoveryManager sends the expected intents.");
        verify(mPhone.getContext(), times(3)).sendBroadcast(captorIntent.capture());
        logd(captorIntent.getAllValues().toString());
        for (int i = 0; i < captorIntent.getAllValues().size(); i++) {
            Intent intent = captorIntent.getAllValues().get(i);
            // Check and assert if intent is null
            assertNotNull(intent);
            // Check and assert if intent is not ACTION_DATA_STALL_DETECTED
            assertThat(intent.getAction()).isEqualTo(
                    TelephonyManager.ACTION_DATA_STALL_DETECTED);
            // Get the extra data
            Bundle bundle = (Bundle) intent.getExtra("EXTRA_DSRS_STATS_BUNDLE");
            // Check and assert if bundle is null
            assertNotNull(bundle);
            // Dump bundle data
            logd(bundle.toString());
            int size = bundle.size();
            logd("bundle size is " + size);
            // Check if bundle size is 19
            assertThat(size).isEqualTo(19);
        }
    }
}