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

Commit 6d1a5706 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 11869550 from 65fea8f2 to 24Q3-release

Change-Id: I1b04e2be7b33fbfb6bfc6097042b96f36ab88234
parents 06de232b 65fea8f2
Loading
Loading
Loading
Loading
+68 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCC

import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
import android.os.Looper;
import android.os.SystemProperties;
@@ -69,6 +70,8 @@ public class DatagramController {
    public static final int TIMEOUT_TYPE_WAIT_FOR_DATAGRAM_SENDING_RESPONSE = 3;
    /** This type is used by CTS to override the time to datagram delay in demo mode */
    public static final int TIMEOUT_TYPE_DATAGRAM_DELAY_IN_DEMO_MODE = 4;
    /** This type is used by CTS to override wait for device alignment in demo datagram boolean */
    public static final int BOOLEAN_TYPE_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_DATAGRAM = 1;
    private static final String ALLOW_MOCK_MODEM_PROPERTY = "persist.radio.allow_mock_modem";
    private static final boolean DEBUG = !"user".equals(Build.TYPE);

@@ -101,6 +104,7 @@ public class DatagramController {
    private long mAlignTimeoutDuration = SATELLITE_ALIGN_TIMEOUT;
    private long mDatagramWaitTimeForConnectedState;
    private long mModemImageSwitchingDuration;
    private boolean mWaitForDeviceAlignmentInDemoDatagram;
    @GuardedBy("mLock")
    @SatelliteManager.SatelliteModemState
    private int mSatelltieModemState = SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN;
@@ -155,6 +159,8 @@ public class DatagramController {

        mDatagramWaitTimeForConnectedState = getDatagramWaitForConnectedStateTimeoutMillis();
        mModemImageSwitchingDuration = getSatelliteModemImageSwitchingDurationMillis();
        mWaitForDeviceAlignmentInDemoDatagram =
                getWaitForDeviceAlignmentInDemoDatagramFromResources();
        mDemoModeDatagramList = new ArrayList<>();
    }

@@ -492,6 +498,36 @@ public class DatagramController {
        return true;
    }

    /**
     * This API can be used by only CTS to override the boolean configs used by the
     * DatagramController module.
     *
     * @param enable Whether to enable or disable boolean config.
     * @return {@code true} if the boolean config is set successfully, {@code false} otherwise.
     */
    boolean setDatagramControllerBooleanConfig(
            boolean reset, int booleanType, boolean enable) {
        if (!isMockModemAllowed()) {
            loge("Updating boolean config is not allowed");
            return false;
        }

        logd("setDatagramControllerTimeoutDuration: booleanType=" + booleanType
                + ", reset=" + reset + ", enable=" + enable);
        if (booleanType == BOOLEAN_TYPE_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_DATAGRAM) {
            if (reset) {
                mWaitForDeviceAlignmentInDemoDatagram =
                        getWaitForDeviceAlignmentInDemoDatagramFromResources();
            } else {
                mWaitForDeviceAlignmentInDemoDatagram = enable;
            }
        } else {
            loge("Invalid boolean type " + booleanType);
            return false;
        }
        return true;
    }

    private boolean isMockModemAllowed() {
        return (DEBUG || SystemProperties.getBoolean(ALLOW_MOCK_MODEM_PROPERTY, false));
    }
@@ -546,6 +582,38 @@ public class DatagramController {
        }
    }

    /**
     * Get whether to wait for device alignment with satellite before sending datagrams.
     *
     * @param isAligned if the device is aligned with satellite or not
     * @return {@code true} if device is not aligned to satellite,
     * and it is required to wait for alignment else {@code false}
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public boolean waitForAligningToSatellite(boolean isAligned) {
        if (isAligned) {
            return false;
        }

        return getWaitForDeviceAlignmentInDemoDatagram();
    }

    private boolean getWaitForDeviceAlignmentInDemoDatagram() {
        return mWaitForDeviceAlignmentInDemoDatagram;
    }

    private boolean getWaitForDeviceAlignmentInDemoDatagramFromResources() {
        boolean waitForDeviceAlignmentInDemoDatagram = false;
        try {
            waitForDeviceAlignmentInDemoDatagram = mContext.getResources().getBoolean(
                    R.bool.config_wait_for_device_alignment_in_demo_datagram);
        } catch (Resources.NotFoundException ex) {
            loge("getWaitForDeviceAlignmentInDemoDatagram: ex=" + ex);
        }

        return waitForDeviceAlignmentInDemoDatagram;
    }

    private static void logd(@NonNull String log) {
        Rlog.d(TAG, log);
    }
+1 −1
Original line number Diff line number Diff line
@@ -239,7 +239,7 @@ public class DatagramDispatcher extends Handler {
                    if (mIsDemoMode && (error == SatelliteManager.SATELLITE_RESULT_SUCCESS)) {
                        if (argument.skipCheckingSatelliteAligned) {
                            logd("Satellite was already aligned. No need to check alignment again");
                        } else if (!mIsAligned) {
                        } else if (mDatagramController.waitForAligningToSatellite(mIsAligned)) {
                            logd("Satellite is not aligned in demo mode, wait for the alignment.");
                            startSatelliteAlignedTimer(request);
                            break;
+1 −1
Original line number Diff line number Diff line
@@ -620,7 +620,7 @@ public class DatagramReceiver extends Handler {
            DatagramReceiverHandlerRequest request = new DatagramReceiverHandlerRequest(
                    callback, phone, subId);
            synchronized (mLock) {
                if (mIsAligned) {
                if (!mDatagramController.waitForAligningToSatellite(mIsAligned)) {
                    Message msg = obtainMessage(EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE,
                            request);
                    AsyncResult.forMessage(msg, null, null);
+329 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony.satellite;

import android.annotation.NonNull;
import android.content.Context;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.telephony.IIntegerConsumer;
import android.telephony.satellite.stub.ISatelliteListener;
import android.telephony.satellite.stub.NtnSignalStrength;
import android.telephony.satellite.stub.SatelliteModemState;
import android.telephony.satellite.stub.SatelliteResult;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;

public class DemoSimulator extends StateMachine {
    private static final String TAG = "DemoSimulator";
    private static final boolean DBG = true;

    private static final int EVENT_SATELLITE_MODE_ON = 1;
    private static final int EVENT_SATELLITE_MODE_OFF = 2;
    private static final int EVENT_DEVICE_ALIGNED_WITH_SATELLITE = 3;
    protected static final int EVENT_DEVICE_ALIGNED = 4;
    protected static final int EVENT_DEVICE_NOT_ALIGNED = 5;

    @NonNull private static DemoSimulator sInstance;

    @NonNull private final Context mContext;
    @NonNull private final SatelliteController mSatelliteController;
    @NonNull private final PowerOffState mPowerOffState = new PowerOffState();
    @NonNull private final NotConnectedState mNotConnectedState = new NotConnectedState();
    @NonNull private final ConnectedState mConnectedState = new ConnectedState();
    @NonNull private final Object mLock = new Object();
    @GuardedBy("mLock")
    private boolean mIsAligned = false;
    private ISatelliteListener mISatelliteListener;

    /**
     * @return The singleton instance of DemoSimulator.
     */
    public static DemoSimulator getInstance() {
        if (sInstance == null) {
            Log.e(TAG, "DemoSimulator was not yet initialized.");
        }
        return sInstance;
    }

    /**
     * Create the DemoSimulator singleton instance.
     *
     * @param context The Context for the DemoSimulator.
     * @return The singleton instance of DemoSimulator.
     */
    public static DemoSimulator make(@NonNull Context context,
            @NonNull SatelliteController satelliteController) {
        if (sInstance == null) {
            sInstance = new DemoSimulator(context, Looper.getMainLooper(), satelliteController);
        }
        return sInstance;
    }

    /**
     * Create a DemoSimulator.
     *
     * @param context The Context for the DemoSimulator.
     * @param looper The looper associated with the handler of this class.
     */
    protected DemoSimulator(@NonNull Context context, @NonNull Looper looper,
            @NonNull SatelliteController satelliteController) {
        super(TAG, looper);

        mContext = context;
        mSatelliteController = satelliteController;
        addState(mPowerOffState);
        addState(mNotConnectedState);
        addState(mConnectedState);
        setInitialState(mPowerOffState);
        start();
    }

    private class PowerOffState extends State {
        @Override
        public void enter() {
            logd("Entering PowerOffState");
        }

        @Override
        public void exit() {
            logd("Exiting PowerOffState");
        }

        @Override
        public boolean processMessage(Message msg) {
            if (DBG) log("PowerOffState: processing " + getWhatToString(msg.what));
            switch (msg.what) {
                case EVENT_SATELLITE_MODE_ON:
                    transitionTo(mNotConnectedState);
                    break;
            }
            // Ignore all unexpected events.
            return HANDLED;
        }
    }

    private class NotConnectedState extends State {
        @Override
        public void enter() {
            logd("Entering NotConnectedState");

            try {
                NtnSignalStrength ntnSignalStrength = new NtnSignalStrength();
                ntnSignalStrength.signalStrengthLevel = 0;
                mISatelliteListener.onSatelliteModemStateChanged(
                        SatelliteModemState.SATELLITE_MODEM_STATE_NOT_CONNECTED);
                mISatelliteListener.onNtnSignalStrengthChanged(ntnSignalStrength);

                synchronized (mLock) {
                    if (mIsAligned) {
                        handleEventDeviceAlignedWithSatellite(true);
                    }
                }
            } catch (RemoteException e) {
                loge("NotConnectedState: RemoteException " + e);
            }
        }

        @Override
        public void exit() {
            logd("Exiting NotConnectedState");
        }

        @Override
        public boolean processMessage(Message msg) {
            if (DBG) log("NotConnectedState: processing " + getWhatToString(msg.what));
            switch (msg.what) {
                case EVENT_SATELLITE_MODE_OFF:
                    transitionTo(mPowerOffState);
                    break;
                case EVENT_DEVICE_ALIGNED_WITH_SATELLITE:
                    handleEventDeviceAlignedWithSatellite((boolean) msg.obj);
                    break;
                case EVENT_DEVICE_ALIGNED:
                    transitionTo(mConnectedState);
                    break;
            }
            // Ignore all unexpected events.
            return HANDLED;
        }

        private void handleEventDeviceAlignedWithSatellite(boolean isAligned) {
            if (isAligned && !hasMessages(EVENT_DEVICE_ALIGNED)) {
                long durationMillis = mSatelliteController.getDemoPointingAlignedDurationMillis();
                logd("NotConnectedState: handleEventAlignedWithSatellite isAligned=true."
                        + " Send delayed EVENT_DEVICE_ALIGNED message in"
                        + " durationMillis=" + durationMillis);
                sendMessageDelayed(EVENT_DEVICE_ALIGNED, durationMillis);
            } else if (!isAligned && hasMessages(EVENT_DEVICE_ALIGNED)) {
                logd("NotConnectedState: handleEventAlignedWithSatellite isAligned=false."
                        + " Remove EVENT_DEVICE_ALIGNED message.");
                removeMessages(EVENT_DEVICE_ALIGNED);
            }
        }
    }

    private class ConnectedState extends State {
        @Override
        public void enter() {
            logd("Entering ConnectedState");

            try {
                NtnSignalStrength ntnSignalStrength = new NtnSignalStrength();
                ntnSignalStrength.signalStrengthLevel = 2;
                mISatelliteListener.onSatelliteModemStateChanged(
                        SatelliteModemState.SATELLITE_MODEM_STATE_CONNECTED);
                mISatelliteListener.onNtnSignalStrengthChanged(ntnSignalStrength);

                synchronized (mLock) {
                    if (!mIsAligned) {
                        handleEventDeviceAlignedWithSatellite(false);
                    }
                }
            } catch (RemoteException e) {
                loge("ConnectedState: RemoteException " + e);
            }
        }

        @Override
        public void exit() {
            logd("Exiting ConnectedState");
        }

        @Override
        public boolean processMessage(Message msg) {
            if (DBG) log("ConnectedState: processing " + getWhatToString(msg.what));
            switch (msg.what) {
                case EVENT_SATELLITE_MODE_OFF:
                    transitionTo(mPowerOffState);
                    break;
                case EVENT_DEVICE_ALIGNED_WITH_SATELLITE:
                    handleEventDeviceAlignedWithSatellite((boolean) msg.obj);
                    break;
                case EVENT_DEVICE_NOT_ALIGNED:
                    transitionTo(mNotConnectedState);
                    break;
            }
            // Ignore all unexpected events.
            return HANDLED;
        }

        private void handleEventDeviceAlignedWithSatellite(boolean isAligned) {
            if (!isAligned && !hasMessages(EVENT_DEVICE_NOT_ALIGNED)) {
                long durationMillis =
                        mSatelliteController.getDemoPointingNotAlignedDurationMillis();
                logd("ConnectedState: handleEventAlignedWithSatellite isAligned=false."
                        + " Send delayed EVENT_DEVICE_NOT_ALIGNED message"
                        + " in durationMillis=" + durationMillis);
                sendMessageDelayed(EVENT_DEVICE_NOT_ALIGNED, durationMillis);
            } else if (isAligned && hasMessages(EVENT_DEVICE_NOT_ALIGNED)) {
                logd("ConnectedState: handleEventAlignedWithSatellite isAligned=true."
                        + " Remove EVENT_DEVICE_NOT_ALIGNED message.");
                removeMessages(EVENT_DEVICE_NOT_ALIGNED);
            }
        }
    }

    /**
     * @return the string for msg.what
     */
    @Override
    protected String getWhatToString(int what) {
        String whatString;
        switch (what) {
            case EVENT_SATELLITE_MODE_ON:
                whatString = "EVENT_SATELLITE_MODE_ON";
                break;
            case EVENT_SATELLITE_MODE_OFF:
                whatString = "EVENT_SATELLITE_MODE_OFF";
                break;
            case EVENT_DEVICE_ALIGNED_WITH_SATELLITE:
                whatString = "EVENT_DEVICE_ALIGNED_WITH_SATELLITE";
                break;
            case EVENT_DEVICE_ALIGNED:
                whatString = "EVENT_DEVICE_ALIGNED";
                break;
            case EVENT_DEVICE_NOT_ALIGNED:
                whatString = "EVENT_DEVICE_NOT_ALIGNED";
                break;
            default:
                whatString = "UNKNOWN EVENT " + what;
        }
        return whatString;
    }

    /**
     * Register the callback interface with satellite service.
     *
     * @param listener The callback interface to handle satellite service indications.
     */
    public void setSatelliteListener(@NonNull ISatelliteListener listener) {
        mISatelliteListener = listener;
    }

    /**
     * Allow cellular modem scanning while satellite mode is on.
     *
     * @param enabled  {@code true} to enable cellular modem while satellite mode is on
     *                             and {@code false} to disable
     * @param errorCallback The callback to receive the error code result of the operation.
     */
    public void enableCellularModemWhileSatelliteModeIsOn(boolean enabled,
            @NonNull IIntegerConsumer errorCallback) {
        try {
            errorCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS);
        } catch (RemoteException e) {
            loge("enableCellularModemWhileSatelliteModeIsOn: RemoteException " + e);
        }
    }

    /**
     * This function is used by {@link SatelliteSessionController} to notify {@link DemoSimulator}
     * that satellite mode is ON.
     */
    public void onSatelliteModeOn() {
        if (mSatelliteController.isDemoModeEnabled()) {
            sendMessage(EVENT_SATELLITE_MODE_ON);
        }
    }

    /**
     * This function is used by {@link SatelliteSessionController} to notify {@link DemoSimulator}
     * that satellite mode is OFF.
     */
    public void onSatelliteModeOff() {
        sendMessage(EVENT_SATELLITE_MODE_OFF);
    }

    /**
     * Set whether the device is aligned with the satellite.
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public void setDeviceAlignedWithSatellite(boolean isAligned) {
        synchronized (mLock) {
            if (mSatelliteController.isDemoModeEnabled()) {
                mIsAligned = isAligned;
                sendMessage(EVENT_DEVICE_ALIGNED_WITH_SATELLITE, isAligned);
            }
        }
    }
}
+78 −0
Original line number Diff line number Diff line
@@ -164,6 +164,10 @@ public class SatelliteController extends Handler {
     * to enable satellite.
     */
    public static final int TIMEOUT_TYPE_WAIT_FOR_SATELLITE_ENABLING_RESPONSE = 1;
    /** This is used by CTS to override demo pointing aligned duration. */
    public static final int TIMEOUT_TYPE_DEMO_POINTING_ALIGNED_DURATION_MILLIS = 2;
    /** This is used by CTS to override demo pointing not aligned duration. */
    public static final int TIMEOUT_TYPE_DEMO_POINTING_NOT_ALIGNED_DURATION_MILLIS = 3;

    /** Key used to read/write OEM-enabled satellite provision status in shared preferences. */
    private static final String OEM_ENABLED_SATELLITE_PROVISION_STATUS_KEY =
@@ -408,6 +412,8 @@ public class SatelliteController extends Handler {
    private final SparseArray<List<String>> mMergedPlmnListPerCarrier = new SparseArray<>();
    private static AtomicLong sNextSatelliteEnableRequestId = new AtomicLong(0);
    private long mWaitTimeForSatelliteEnablingResponse;
    private long mDemoPointingAlignedDurationMillis;
    private long mDemoPointingNotAlignedDurationMillis;

    /** Key used to read/write satellite system notification done in shared preferences. */
    private static final String SATELLITE_SYSTEM_NOTIFICATION_DONE_KEY =
@@ -537,6 +543,9 @@ public class SatelliteController extends Handler {
                null);
        loadSatelliteSharedPreferences();
        mWaitTimeForSatelliteEnablingResponse = getWaitForSatelliteEnablingResponseTimeoutMillis();
        mDemoPointingAlignedDurationMillis = getDemoPointingAlignedDurationMillisFromResources();
        mDemoPointingNotAlignedDurationMillis =
                getDemoPointingNotAlignedDurationMillisFromResources();
    }

    /**
@@ -2055,6 +2064,8 @@ public class SatelliteController extends Handler {
            logd("setDeviceAlignedWithSatellite: oemEnabledSatelliteFlag is disabled");
            return;
        }

        DemoSimulator.getInstance().setDeviceAlignedWithSatellite(isAligned);
        mDatagramController.setDeviceAlignedWithSatellite(isAligned);
    }

@@ -2384,6 +2395,25 @@ public class SatelliteController extends Handler {
                reset, timeoutType, timeoutMillis);
    }

    /**
     * This API can be used by only CTS to override the boolean configs used by the
     * DatagramController module.
     *
     * @param enable Whether to enable or disable boolean config.
     * @return {@code true} if the boolean config is set successfully, {@code false} otherwise.
     */
    public boolean setDatagramControllerBooleanConfig(
            boolean reset, int booleanType, boolean enable) {
        if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
            logd("setDatagramControllerBooleanConfig: oemEnabledSatelliteFlag is disabled");
            return false;
        }
        logd("setDatagramControllerBooleanConfig: reset=" + reset + ", booleanType="
                + booleanType + ", enable=" + enable);
        return mDatagramController.setDatagramControllerBooleanConfig(
                reset, booleanType, enable);
    }

    /**
     * This API can be used by only CTS to override timeout durations used by SatelliteController
     * module.
@@ -2411,6 +2441,20 @@ public class SatelliteController extends Handler {
                mWaitTimeForSatelliteEnablingResponse = timeoutMillis;
            }
            logd("mWaitTimeForSatelliteEnablingResponse=" + mWaitTimeForSatelliteEnablingResponse);
        } else if (timeoutType == TIMEOUT_TYPE_DEMO_POINTING_ALIGNED_DURATION_MILLIS) {
            if (reset) {
                mDemoPointingAlignedDurationMillis =
                        getDemoPointingAlignedDurationMillisFromResources();
            } else {
                mDemoPointingAlignedDurationMillis = timeoutMillis;
            }
        } else if (timeoutType == TIMEOUT_TYPE_DEMO_POINTING_NOT_ALIGNED_DURATION_MILLIS) {
            if (reset) {
                mDemoPointingNotAlignedDurationMillis =
                        getDemoPointingNotAlignedDurationMillisFromResources();
            } else {
                mDemoPointingNotAlignedDurationMillis = timeoutMillis;
            }
        } else {
            logw("Invalid timeoutType=" + timeoutType);
            return false;
@@ -4618,6 +4662,40 @@ public class SatelliteController extends Handler {
        }
    }

    private long getDemoPointingAlignedDurationMillisFromResources() {
        long durationMillis = 15000L;
        try {
            durationMillis = mContext.getResources().getInteger(
                    R.integer.config_demo_pointing_aligned_duration_millis);
        } catch (Resources.NotFoundException ex) {
            loge("getPointingAlignedDurationMillis: ex=" + ex);
        }

        return durationMillis;
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public long getDemoPointingAlignedDurationMillis() {
        return mDemoPointingAlignedDurationMillis;
    }

    private long getDemoPointingNotAlignedDurationMillisFromResources() {
        long durationMillis = 30000L;
        try {
            durationMillis = mContext.getResources().getInteger(
                    R.integer.config_demo_pointing_not_aligned_duration_millis);
        } catch (Resources.NotFoundException ex) {
            loge("getPointingNotAlignedDurationMillis: ex=" + ex);
        }

        return durationMillis;
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public long getDemoPointingNotAlignedDurationMillis() {
        return mDemoPointingNotAlignedDurationMillis;
    }

    private static void logd(@NonNull String log) {
        Rlog.d(TAG, log);
    }
Loading