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

Commit ebea67d5 authored by Allen Xu's avatar Allen Xu
Browse files

Persist Telephony Satellite logs

1. Add feature flag for persistent satellite logging
2. Persist satellite telephony module logs

Bug: 343478281
Flag: com.android.internal.telephony.flags.satellite_persistent_logging
Test: make & manual tests
Change-Id: Iaeab24745fd493148274c986f418e3a117fcac48
Merged-In: Iaeab24745fd493148274c986f418e3a117fcac48
parent 9b00d030
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -20,3 +20,11 @@ flag {
    description: "This flag enables satellite internet support."
    bug:"326972202"
}

# OWNER=xalle TARGET=24Q3
flag {
    name: "satellite_persistent_logging"
    namespace: "telephony"
    description: "This flag enables satellite persistent logging"
    bug:"339877723"
}
 No newline at end of file
+62 −15
Original line number Diff line number Diff line
@@ -28,11 +28,14 @@ import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
import android.os.Looper;
import android.os.SystemProperties;
import android.telephony.DropBoxManagerLoggerBackend;
import android.telephony.PersistentLogger;
import android.telephony.Rlog;
import android.telephony.satellite.ISatelliteDatagramCallback;
import android.telephony.satellite.SatelliteDatagram;
@@ -41,6 +44,7 @@ import android.telephony.satellite.SatelliteManager;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.flags.FeatureFlags;

import java.util.ArrayList;
import java.util.List;
@@ -55,6 +59,7 @@ public class DatagramController {

    @NonNull private static DatagramController sInstance;
    @NonNull private final Context mContext;
    @NonNull private final FeatureFlags mFeatureFlags;
    @NonNull private final PointingAppController mPointingAppController;
    @NonNull private final DatagramDispatcher mDatagramDispatcher;
    @NonNull private final DatagramReceiver mDatagramReceiver;
@@ -109,6 +114,8 @@ public class DatagramController {
    @GuardedBy("mLock")
    @SatelliteManager.SatelliteModemState
    private int mSatelltieModemState = SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN;
    @Nullable
    private PersistentLogger mPersistentLogger = null;

    /**
     * @return The singleton instance of DatagramController.
@@ -124,14 +131,17 @@ public class DatagramController {
     * Create the DatagramController singleton instance.
     * @param context The Context to use to create the DatagramController.
     * @param looper The looper for the handler.
     * @param featureFlags The telephony feature flags.
     * @param pointingAppController PointingAppController is used to update
     *                              PointingApp about datagram transfer state changes.
     * @return The singleton instance of DatagramController.
     */
    public static DatagramController make(@NonNull Context context, @NonNull Looper looper,
            @NonNull FeatureFlags featureFlags,
            @NonNull PointingAppController pointingAppController) {
        if (sInstance == null) {
            sInstance = new DatagramController(context, looper, pointingAppController);
            sInstance = new DatagramController(
                    context, looper, featureFlags, pointingAppController);
        }
        return sInstance;
    }
@@ -141,22 +151,27 @@ public class DatagramController {
     *
     * @param context The Context for the DatagramController.
     * @param looper The looper for the handler
     * @param featureFlags The telephony feature flags.
     * @param pointingAppController PointingAppController is used to update PointingApp
     *                              about datagram transfer state changes.
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    public DatagramController(@NonNull Context context, @NonNull Looper  looper,
            @NonNull FeatureFlags featureFlags,
            @NonNull PointingAppController pointingAppController) {
        mContext = context;
        mFeatureFlags = featureFlags;
        mPointingAppController = pointingAppController;

        // Create the DatagramDispatcher singleton,
        // which is used to send satellite datagrams.
        mDatagramDispatcher = DatagramDispatcher.make(mContext, looper, this);
        mDatagramDispatcher = DatagramDispatcher.make(
                mContext, looper, mFeatureFlags, this);

        // Create the DatagramReceiver singleton,
        // which is used to receive satellite datagrams.
        mDatagramReceiver = DatagramReceiver.make(mContext, looper, this);
        mDatagramReceiver = DatagramReceiver.make(
                mContext, looper, mFeatureFlags, this);

        mDatagramWaitTimeForConnectedState = getDatagramWaitForConnectedStateTimeoutMillis();
        mModemImageSwitchingDuration = getSatelliteModemImageSwitchingDurationMillis();
@@ -165,6 +180,11 @@ public class DatagramController {
        mDatagramWaitTimeForConnectedStateForLastMessage =
                getDatagramWaitForConnectedStateForLastMessageTimeoutMillis();
        mDemoModeDatagramList = new ArrayList<>();

        if (isSatellitePersistentLoggingEnabled(context, featureFlags)) {
            mPersistentLogger = new PersistentLogger(
                    DropBoxManagerLoggerBackend.getInstance(context));
        }
    }

    /**
@@ -205,7 +225,7 @@ public class DatagramController {
     * @param callback The callback to get {@link SatelliteManager.SatelliteResult} of the request.
     */
    public void pollPendingSatelliteDatagrams(int subId, @NonNull Consumer<Integer> callback) {
        logd("pollPendingSatelliteDatagrams");
        plogd("pollPendingSatelliteDatagrams");
        mDatagramReceiver.pollPendingSatelliteDatagrams(subId, callback);
    }

@@ -247,13 +267,13 @@ public class DatagramController {
            @SatelliteManager.SatelliteDatagramTransferState int datagramTransferState,
            int sendPendingCount, int errorCode) {
        synchronized (mLock) {
            logd("updateSendStatus"
            plogd("updateSendStatus"
                    + " subId: " + subId
                    + " datagramType: " + datagramType
                    + " datagramTransferState: " + datagramTransferState
                    + " sendPendingCount: " + sendPendingCount + " errorCode: " + errorCode);
            if (shouldSuppressDatagramTransferStateUpdate(datagramType)) {
                logd("Ignore the request to update send status");
                plogd("Ignore the request to update send status");
                return;
            }

@@ -295,7 +315,7 @@ public class DatagramController {
            @SatelliteManager.SatelliteDatagramTransferState int datagramTransferState,
            int receivePendingCount, int errorCode) {
        synchronized (mLock) {
            logd("updateReceiveStatus"
            plogd("updateReceiveStatus"
                    + " subId: " + subId
                    + " datagramTransferState: " + datagramTransferState
                    + " receivePendingCount: " + receivePendingCount + " errorCode: " + errorCode);
@@ -411,7 +431,7 @@ public class DatagramController {
            }
            setDeviceAlignedWithSatellite(false);
        }
        logd("setDemoMode: mIsDemoMode=" + mIsDemoMode);
        plogd("setDemoMode: mIsDemoMode=" + mIsDemoMode);
    }

    /** Get the last sent datagram for demo mode */
@@ -422,7 +442,7 @@ public class DatagramController {
        }

        synchronized (mLock) {
            logd("popDemoModeDatagram");
            plogd("popDemoModeDatagram");
            return mDemoModeDatagramList.size() > 0 ? mDemoModeDatagramList.remove(0) : null;
        }
    }
@@ -440,7 +460,7 @@ public class DatagramController {
        if (mIsDemoMode && SatelliteServiceUtils.isSosMessage(datagramType)) {
            synchronized (mLock) {
                mDemoModeDatagramList.add(datagram);
                logd("pushDemoModeDatagram size=" + mDemoModeDatagramList.size());
                plogd("pushDemoModeDatagram size=" + mDemoModeDatagramList.size());
            }
        }
    }
@@ -473,11 +493,11 @@ public class DatagramController {
    boolean setDatagramControllerTimeoutDuration(
            boolean reset, int timeoutType, long timeoutMillis) {
        if (!isMockModemAllowed()) {
            loge("Updating timeout duration is not allowed");
            ploge("Updating timeout duration is not allowed");
            return false;
        }

        logd("setDatagramControllerTimeoutDuration: timeoutMillis=" + timeoutMillis
        plogd("setDatagramControllerTimeoutDuration: timeoutMillis=" + timeoutMillis
                + ", reset=" + reset + ", timeoutType=" + timeoutType);
        if (timeoutType == TIMEOUT_TYPE_ALIGN) {
            if (reset) {
@@ -499,7 +519,7 @@ public class DatagramController {
        } else if (timeoutType == TIMEOUT_TYPE_DATAGRAM_DELAY_IN_DEMO_MODE) {
            mDatagramDispatcher.setTimeoutDatagramDelayInDemoMode(reset, timeoutMillis);
        } else {
            loge("Invalid timeout type " + timeoutType);
            ploge("Invalid timeout type " + timeoutType);
            return false;
        }
        return true;
@@ -542,7 +562,7 @@ public class DatagramController {
    private void notifyDatagramTransferStateChangedToSessionController() {
        SatelliteSessionController sessionController = SatelliteSessionController.getInstance();
        if (sessionController == null) {
            loge("notifyDatagramTransferStateChangeToSessionController: SatelliteSessionController"
            ploge("notifyDatagramTransferStateChangeToSessionController: SatelliteSessionController"
                    + " is not initialized yet");
        } else {
            sessionController.onDatagramTransferStateChanged(
@@ -585,7 +605,7 @@ public class DatagramController {
                    @Override
                    public void accept(Integer result) {
                        if (result != SATELLITE_RESULT_SUCCESS) {
                            logd("retryPollPendingDatagramsInDemoMode result: " + result);
                            plogd("retryPollPendingDatagramsInDemoMode result: " + result);
                        }
                    }
                };
@@ -633,4 +653,31 @@ public class DatagramController {
    private static void loge(@NonNull String log) {
        Rlog.e(TAG, log);
    }

    private boolean isSatellitePersistentLoggingEnabled(
            @NonNull Context context, @NonNull FeatureFlags featureFlags) {
        if (featureFlags.satellitePersistentLogging()) {
            return true;
        }
        try {
            return context.getResources().getBoolean(
                    R.bool.config_dropboxmanager_persistent_logging_enabled);
        } catch (RuntimeException e) {
            return false;
        }
    }

    private void plogd(@NonNull String log) {
        Rlog.d(TAG, log);
        if (mPersistentLogger != null) {
            mPersistentLogger.debug(TAG, log);
        }
    }

    private void ploge(@NonNull String log) {
        Rlog.e(TAG, log);
        if (mPersistentLogger != null) {
            mPersistentLogger.error(TAG, log);
        }
    }
}
+84 −35

File changed.

Preview size limit exceeded, changes collapsed.

+65 −17
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.provider.Telephony;
import android.telephony.DropBoxManagerLoggerBackend;
import android.telephony.PersistentLogger;
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.telephony.satellite.ISatelliteDatagramCallback;
@@ -50,6 +52,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.IVoidConsumer;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.metrics.SatelliteStats;
import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
import com.android.internal.telephony.satellite.metrics.SessionMetricsStats;
@@ -83,6 +86,7 @@ public class DatagramReceiver extends Handler {
    @NonNull private final ControllerMetricsStats mControllerMetricsStats;
    @NonNull private final SessionMetricsStats mSessionMetricsStats;
    @NonNull private final Looper mLooper;
    @NonNull private final FeatureFlags mFeatureFlags;

    private long mDatagramTransferStartTime = 0;
    private boolean mIsDemoMode = false;
@@ -93,6 +97,8 @@ public class DatagramReceiver extends Handler {
    @Nullable
    private DatagramReceiverHandlerRequest mPendingPollSatelliteDatagramsRequest = null;
    private final Object mLock = new Object();
    @Nullable
    private PersistentLogger mPersistentLogger = null;

    /**
     * Map key: subId, value: SatelliteDatagramListenerHandler to notify registrants.
@@ -112,13 +118,15 @@ public class DatagramReceiver extends Handler {
     * Create the DatagramReceiver singleton instance.
     * @param context The Context to use to create the DatagramReceiver.
     * @param looper The looper for the handler.
     * @param featureFlags The telephony feature flags.
     * @param datagramController DatagramController which is used to update datagram transfer state.
     * @return The singleton instance of DatagramReceiver.
     */
    public static DatagramReceiver make(@NonNull Context context, @NonNull Looper looper,
            @NonNull FeatureFlags featureFlags,
            @NonNull DatagramController datagramController) {
        if (sInstance == null) {
            sInstance = new DatagramReceiver(context, looper, datagramController);
            sInstance = new DatagramReceiver(context, looper, featureFlags, datagramController);
        }
        return sInstance;
    }
@@ -129,25 +137,31 @@ public class DatagramReceiver extends Handler {
     *
     * @param context The Context for the DatagramReceiver.
     * @param looper The looper for the handler.
     * @param featureFlags The telephony feature flags.
     * @param datagramController DatagramController which is used to update datagram transfer state.
     */
    @VisibleForTesting
    protected DatagramReceiver(@NonNull Context context, @NonNull Looper looper,
            @NonNull FeatureFlags featureFlags,
            @NonNull DatagramController datagramController) {
        super(looper);
        mContext = context;
        mLooper = looper;
        mFeatureFlags = featureFlags;
        mContentResolver = context.getContentResolver();
        mDatagramController = datagramController;
        mControllerMetricsStats = ControllerMetricsStats.getInstance();
        mSessionMetricsStats = SessionMetricsStats.getInstance();

        if (isSatellitePersistentLoggingEnabled(context, featureFlags)) {
            mPersistentLogger = new PersistentLogger(
                    DropBoxManagerLoggerBackend.getInstance(context));
        }
        try {
            mSharedPreferences =
                    mContext.getSharedPreferences(SatelliteController.SATELLITE_SHARED_PREF,
                            Context.MODE_PRIVATE);
        } catch (Exception e) {
            loge("Cannot get default shared preferences: " + e);
            ploge("Cannot get default shared preferences: " + e);
        }
    }

@@ -457,7 +471,7 @@ public class DatagramReceiver extends Handler {
                    }
                }

                logd("EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE error: " + error);
                plogd("EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE error: " + error);
                if (error != SatelliteManager.SATELLITE_RESULT_SUCCESS) {
                    mDatagramController.updateReceiveStatus(request.subId,
                            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED,
@@ -485,7 +499,7 @@ public class DatagramReceiver extends Handler {
                break;

            default:
                logw("DatagramDispatcherHandler: unexpected message code: " + msg.what);
                plogw("DatagramDispatcherHandler: unexpected message code: " + msg.what);
                break;
        }
    }
@@ -558,7 +572,7 @@ public class DatagramReceiver extends Handler {
    public void pollPendingSatelliteDatagrams(int subId, @NonNull Consumer<Integer> callback) {
        if (!mDatagramController.isPollingInIdleState()) {
            // Poll request should be sent to satellite modem only when it is free.
            logd("pollPendingSatelliteDatagrams: satellite modem is busy receiving datagrams.");
            plogd("pollPendingSatelliteDatagrams: satellite modem is busy receiving datagrams.");
            callback.accept(SatelliteManager.SATELLITE_RESULT_MODEM_BUSY);
            return;
        }
@@ -570,7 +584,7 @@ public class DatagramReceiver extends Handler {
            if (isDatagramWaitForConnectedStateTimerStarted()) {
                stopDatagramWaitForConnectedStateTimer();
                if (mPendingPollSatelliteDatagramsRequest == null) {
                    loge("handleSatelliteConnectedEvent: mPendingPollSatelliteDatagramsRequest is"
                    ploge("handleSatelliteConnectedEvent: mPendingPollSatelliteDatagramsRequest is"
                            + " null");
                    return;
                }
@@ -588,7 +602,7 @@ public class DatagramReceiver extends Handler {
            @NonNull Consumer<Integer> callback) {
        if (!mDatagramController.isSendingInIdleState()) {
            // Poll request should be sent to satellite modem only when it is free.
            logd("pollPendingSatelliteDatagramsInternal: satellite modem is busy sending "
            plogd("pollPendingSatelliteDatagramsInternal: satellite modem is busy sending "
                    + "datagrams.");
            callback.accept(SatelliteManager.SATELLITE_RESULT_MODEM_BUSY);
            return;
@@ -596,7 +610,7 @@ public class DatagramReceiver extends Handler {

        if (mDatagramController.needsWaitingForSatelliteConnected(
                SatelliteManager.DATAGRAM_TYPE_UNKNOWN)) {
            logd("pollPendingSatelliteDatagramsInternal: wait for satellite connected");
            plogd("pollPendingSatelliteDatagramsInternal: wait for satellite connected");
            synchronized (mLock) {
                mPendingPollSatelliteDatagramsRequest = new DatagramReceiverHandlerRequest(
                        callback, SatelliteServiceUtils.getPhone(), subId);
@@ -644,7 +658,7 @@ public class DatagramReceiver extends Handler {
        synchronized (mLock) {
            if (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF
                    || state == SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE) {
                logd("onSatelliteModemStateChanged: cleaning up resources");
                plogd("onSatelliteModemStateChanged: cleaning up resources");
                cleanUpResources();
            } else if (state == SATELLITE_MODEM_STATE_CONNECTED) {
                handleSatelliteConnectedEvent();
@@ -657,7 +671,7 @@ public class DatagramReceiver extends Handler {
        if (isSatelliteAlignedTimerStarted()) {
            stopSatelliteAlignedTimer();
            if (mDemoPollPendingSatelliteDatagramsRequest == null) {
                loge("Satellite aligned timer was started "
                ploge("Satellite aligned timer was started "
                        + "but mDemoPollPendingSatelliteDatagramsRequest is null");
            } else {
                Consumer<Integer> callback =
@@ -755,14 +769,14 @@ public class DatagramReceiver extends Handler {
    public void setDeviceAlignedWithSatellite(boolean isAligned) {
        synchronized (mLock) {
            mIsAligned = isAligned;
            logd("setDeviceAlignedWithSatellite: " + mIsAligned);
            plogd("setDeviceAlignedWithSatellite: " + mIsAligned);
            if (isAligned && mIsDemoMode) handleEventSatelliteAligned();
        }
    }

    private void startSatelliteAlignedTimer(DatagramReceiverHandlerRequest request) {
        if (isSatelliteAlignedTimerStarted()) {
            logd("Satellite aligned timer was already started");
            plogd("Satellite aligned timer was already started");
            return;
        }
        mDemoPollPendingSatelliteDatagramsRequest = request;
@@ -781,7 +795,7 @@ public class DatagramReceiver extends Handler {
            stopSatelliteAlignedTimer();

            if (mDemoPollPendingSatelliteDatagramsRequest == null) {
                loge("handleSatelliteAlignedTimer: mDemoPollPendingSatelliteDatagramsRequest "
                ploge("handleSatelliteAlignedTimer: mDemoPollPendingSatelliteDatagramsRequest "
                        + "is null");
            } else {
                Message message = obtainMessage(
@@ -813,7 +827,7 @@ public class DatagramReceiver extends Handler {

    private void startDatagramWaitForConnectedStateTimer() {
        if (isDatagramWaitForConnectedStateTimerStarted()) {
            logd("DatagramWaitForConnectedStateTimer is already started");
            plogd("DatagramWaitForConnectedStateTimer is already started");
            return;
        }
        sendMessageDelayed(obtainMessage(
@@ -833,12 +847,12 @@ public class DatagramReceiver extends Handler {
    private void handleEventDatagramWaitForConnectedStateTimedOut() {
        synchronized (mLock) {
            if (mPendingPollSatelliteDatagramsRequest == null) {
                logw("handleEventDatagramWaitForConnectedStateTimedOut: "
                plogw("handleEventDatagramWaitForConnectedStateTimedOut: "
                        + "mPendingPollSatelliteDatagramsRequest is null");
                return;
            }

            logw("Timed out to wait for satellite connected before polling datagrams");
            plogw("Timed out to wait for satellite connected before polling datagrams");
            mDatagramController.updateReceiveStatus(mPendingPollSatelliteDatagramsRequest.subId,
                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED,
                    mDatagramController.getReceivePendingCount(),
@@ -877,4 +891,38 @@ public class DatagramReceiver extends Handler {
    private static void logw(@NonNull String log) {
        Rlog.w(TAG, log);
    }

    private boolean isSatellitePersistentLoggingEnabled(
            @NonNull Context context, @NonNull FeatureFlags featureFlags) {
        if (featureFlags.satellitePersistentLogging()) {
            return true;
        }
        try {
            return context.getResources().getBoolean(
                    R.bool.config_dropboxmanager_persistent_logging_enabled);
        } catch (RuntimeException e) {
            return false;
        }
    }

    private void plogd(@NonNull String log) {
        Rlog.d(TAG, log);
        if (mPersistentLogger != null) {
            mPersistentLogger.debug(TAG, log);
        }
    }

    private void plogw(@NonNull String log) {
        Rlog.w(TAG, log);
        if (mPersistentLogger != null) {
            mPersistentLogger.warn(TAG, log);
        }
    }

    private void ploge(@NonNull String log) {
        Rlog.e(TAG, log);
        if (mPersistentLogger != null) {
            mPersistentLogger.error(TAG, log);
        }
    }
}
+53 −13

File changed.

Preview size limit exceeded, changes collapsed.

Loading