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

Commit a3b3ac55 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6564423 from 8a79096a to rvc-release

Change-Id: I4e9bba2f2c0d1a8fc374ae3d6f0813663293c2e9
parents c8004beb 8a79096a
Loading
Loading
Loading
Loading
+51 −8
Original line number Diff line number Diff line
@@ -20,10 +20,12 @@ import static android.hardware.radio.V1_0.DeviceStateType.CHARGING_STATE;
import static android.hardware.radio.V1_0.DeviceStateType.LOW_DATA_EXPECTED;
import static android.hardware.radio.V1_0.DeviceStateType.POWER_SAVE_MODE;

import android.app.UiModeManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.hardware.display.DisplayManager;
import android.hardware.radio.V1_5.IndicationFilter;
import android.net.ConnectivityManager;
@@ -69,6 +71,7 @@ public class DeviceStateMonitor extends Handler {
    protected static final String TAG = DeviceStateMonitor.class.getSimpleName();

    static final int EVENT_RIL_CONNECTED                = 0;
    static final int EVENT_CAR_MODE_CHANGED             = 1;
    @VisibleForTesting
    static final int EVENT_SCREEN_STATE_CHANGED         = 2;
    static final int EVENT_POWER_SAVE_MODE_CHANGED      = 3;
@@ -169,6 +172,13 @@ public class DeviceStateMonitor extends Handler {
     */
    private boolean mIsWifiConnected;

    /**
     * Car mode is on. True means the device is currently connected to Android Auto. This should be
     * handled by mIsScreenOn, but the Android Auto display is private and not accessible by
     * DeviceStateMonitor from DisplayMonitor.
     */
    private boolean mIsCarModeOn;

    /**
     * True indicates we should always enable the signal strength reporting from radio.
     */
@@ -238,6 +248,14 @@ public class DeviceStateMonitor extends Handler {
                    msg = obtainMessage(EVENT_TETHERING_STATE_CHANGED);
                    msg.arg1 = isTetheringOn ? 1 : 0;
                    break;
                case UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED:
                    msg = obtainMessage(EVENT_CAR_MODE_CHANGED);
                    msg.arg1 = 1; // car mode on
                    break;
                case UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED:
                    msg = obtainMessage(EVENT_CAR_MODE_CHANGED);
                    msg.arg1 = 0; // car mode off
                    break;
                default:
                    log("Unexpected broadcast intent: " + intent, false);
                    return;
@@ -261,6 +279,7 @@ public class DeviceStateMonitor extends Handler {
        mIsPowerSaveOn = isPowerSaveModeOn();
        mIsCharging = isDeviceCharging();
        mIsScreenOn = isScreenOn();
        mIsCarModeOn = isCarModeOn();
        // Assuming tethering is always off after boot up.
        mIsTetheringOn = false;
        mIsLowDataExpected = false;
@@ -270,6 +289,7 @@ public class DeviceStateMonitor extends Handler {
                + ", mIsCharging=" + mIsCharging
                + ", mIsPowerSaveOn=" + mIsPowerSaveOn
                + ", mIsLowDataExpected=" + mIsLowDataExpected
                + ", mIsCarModeOn=" + mIsCarModeOn
                + ", mIsWifiConnected=" + mIsWifiConnected
                + ", mIsAlwaysSignalStrengthReportingEnabled="
                + mIsAlwaysSignalStrengthReportingEnabled, false);
@@ -279,6 +299,8 @@ public class DeviceStateMonitor extends Handler {
        filter.addAction(BatteryManager.ACTION_CHARGING);
        filter.addAction(BatteryManager.ACTION_DISCHARGING);
        filter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
        filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED);
        filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
        mPhone.getContext().registerReceiver(mBroadcastReceiver, filter, null, mPhone);

        mPhone.mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null);
@@ -381,7 +403,8 @@ public class DeviceStateMonitor extends Handler {
        // 1. The device is charging.
        // 2. When the screen is on.
        // 3. When the tethering is on.
        return mIsCharging || mIsScreenOn || mIsTetheringOn;
        // 4. When car mode (Android Auto) is on.
        return mIsCharging || mIsScreenOn || mIsTetheringOn || mIsCarModeOn;
    }

    /**
@@ -434,14 +457,13 @@ public class DeviceStateMonitor extends Handler {
            case EVENT_POWER_SAVE_MODE_CHANGED:
            case EVENT_CHARGING_STATE_CHANGED:
            case EVENT_TETHERING_STATE_CHANGED:
            case EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH:
            case EVENT_CAR_MODE_CHANGED:
                onUpdateDeviceState(msg.what, msg.arg1 != 0);
                break;
            case EVENT_WIFI_CONNECTION_CHANGED:
                onUpdateDeviceState(msg.what, msg.arg1 != WIFI_UNAVAILABLE);
                break;
            case EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH:
                onUpdateDeviceState(msg.what, msg.arg1 != 0);
                break;
            default:
                throw new IllegalStateException("Unexpected message arrives. msg = " + msg.what);
        }
@@ -482,6 +504,10 @@ public class DeviceStateMonitor extends Handler {
                if (mIsAlwaysSignalStrengthReportingEnabled == state) return;
                mIsAlwaysSignalStrengthReportingEnabled = state;
                break;
            case EVENT_CAR_MODE_CHANGED:
                if (mIsCarModeOn == state) return;
                mIsCarModeOn = state;
                break;
            default:
                return;
        }
@@ -652,7 +678,9 @@ public class DeviceStateMonitor extends Handler {
    private boolean isPowerSaveModeOn() {
        final PowerManager pm = (PowerManager) mPhone.getContext().getSystemService(
                Context.POWER_SERVICE);
        return pm.isPowerSaveMode();
        boolean retval = pm.isPowerSaveMode();
        log("isPowerSaveModeOn=" + retval, true);
        return retval;
    }

    /**
@@ -664,12 +692,14 @@ public class DeviceStateMonitor extends Handler {
    private boolean isDeviceCharging() {
        final BatteryManager bm = (BatteryManager) mPhone.getContext().getSystemService(
                Context.BATTERY_SERVICE);
        return bm.isCharging();
        boolean retval = bm.isCharging();
        log("isDeviceCharging=" + retval, true);
        return retval;
    }

    /**
     * @return True if one the device's screen (e.g. main screen, wifi display, HDMI display, or
     *         Android auto, etc...) is on.
     * @return True if one the device's screen (e.g. main screen, wifi display, HDMI display etc...)
     * is on.
     */
    private boolean isScreenOn() {
        // Note that we don't listen to Intent.SCREEN_ON and Intent.SCREEN_OFF because they are no
@@ -696,6 +726,18 @@ public class DeviceStateMonitor extends Handler {
        return false;
    }

    /**
     * @return True if car mode (Android Auto) is on.
     */
    private boolean isCarModeOn() {
        final UiModeManager umm = (UiModeManager) mPhone.getContext().getSystemService(
                Context.UI_MODE_SERVICE);
        if (umm == null) return false;
        boolean retval = umm.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR;
        log("isCarModeOn=" + retval, true);
        return retval;
    }

    /**
     * Register for PhysicalChannelConfig notifications changed. On change, msg.obj will be an
     * AsyncResult with a boolean result. AsyncResult.result is true if notifications are enabled
@@ -744,6 +786,7 @@ public class DeviceStateMonitor extends Handler {
        ipw.println("mIsCharging=" + mIsCharging);
        ipw.println("mIsPowerSaveOn=" + mIsPowerSaveOn);
        ipw.println("mIsLowDataExpected=" + mIsLowDataExpected);
        ipw.println("mIsCarModeOn=" + mIsCarModeOn);
        ipw.println("mUnsolicitedResponseFilter=" + mUnsolicitedResponseFilter);
        ipw.println("mIsWifiConnected=" + mIsWifiConnected);
        ipw.println("mIsAlwaysSignalStrengthReportingEnabled="
+23 −14
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.internal.telephony;

import static com.android.internal.telephony.CommandException.Error.GENERIC_FAILURE;
import static com.android.internal.telephony.CommandException.Error.SIM_BUSY;
import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE;
import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ERASURE;
@@ -163,6 +165,9 @@ public class GsmCdmaPhone extends Phone {
    // keeps track of when we have triggered an emergency call due to the ril.test.emergencynumber
    // param being set and we should generate a simulated exit from the modem upon exit of ECbM.
    private boolean mIsTestingEmergencyCallbackMode = false;
    @VisibleForTesting
    public static int ENABLE_UICC_APPS_MAX_RETRIES = 3;
    private static final int REAPPLY_UICC_APPS_SETTING_RETRY_TIME_GAP_IN_MS = 5000;

    // A runnable which is used to automatically exit from Ecm after a period of time.
    private Runnable mExitEcmRunnable = new Runnable() {
@@ -3066,24 +3071,27 @@ public class GsmCdmaPhone extends Phone {
                mUiccApplicationsEnabled = (Boolean) ar.result;
            // Intentional falling through.
            case EVENT_UICC_APPS_ENABLEMENT_SETTING_CHANGED:
                reapplyUiccAppsEnablementIfNeeded();
                reapplyUiccAppsEnablementIfNeeded(ENABLE_UICC_APPS_MAX_RETRIES);
                break;

            case EVENT_REAPPLY_UICC_APPS_ENABLEMENT_DONE: {
                ar = (AsyncResult) msg.obj;
                if (ar == null || ar.exception == null) return;
                // TODO: b/146181737 don't throw exception and uncomment the retry below.
                boolean expectedValue = (boolean) ar.userObj;
                Pair<Boolean, Integer> userObject = (Pair) ar.userObj;
                if (userObject == null) return;
                boolean expectedValue = userObject.first;
                int retries = userObject.second;
                CommandException.Error error = ((CommandException) ar.exception).getCommandError();
                throw new RuntimeException("Error received when re-applying uicc application"
                loge("Error received when re-applying uicc application"
                        + " setting to " +  expectedValue + " on phone " + mPhoneId
                        + " Error code: " + error);
//                if (error == INTERNAL_ERR || error == SIM_BUSY) {
//                    // Retry for certain errors, but not for others like RADIO_NOT_AVAILABLE or
//                    // SIM_ABSENT, as they will trigger it whey they become available.
//                    postDelayed(()->reapplyUiccAppsEnablementIfNeeded(), 1000);
//                }
//                break;
                        + " Error code: " + error + " retry count left: " + retries);
                if (retries > 0 && (error == GENERIC_FAILURE || error == SIM_BUSY)) {
                    // Retry for certain errors, but not for others like RADIO_NOT_AVAILABLE or
                    // SIM_ABSENT, as they will trigger it whey they become available.
                    postDelayed(()->reapplyUiccAppsEnablementIfNeeded(retries - 1),
                            REAPPLY_UICC_APPS_SETTING_RETRY_TIME_GAP_IN_MS);
                }
                break;
            }
            default:
                super.handleMessage(msg);
@@ -3183,7 +3191,7 @@ public class GsmCdmaPhone extends Phone {
            }
        }

        reapplyUiccAppsEnablementIfNeeded();
        reapplyUiccAppsEnablementIfNeeded(ENABLE_UICC_APPS_MAX_RETRIES);
    }

    private void processIccRecordEvents(int eventCode) {
@@ -4346,7 +4354,7 @@ public class GsmCdmaPhone extends Phone {
        updateUiTtyMode(ttyMode);
    }

    private void reapplyUiccAppsEnablementIfNeeded() {
    private void reapplyUiccAppsEnablementIfNeeded(int retries) {
        UiccSlot slot = mUiccController.getUiccSlotForPhone(mPhoneId);

        // If no card is present or we don't have mUiccApplicationsEnabled yet, do nothing.
@@ -4368,7 +4376,8 @@ public class GsmCdmaPhone extends Phone {
        // configured state.
        if (expectedValue != mUiccApplicationsEnabled) {
            mCi.enableUiccApplications(expectedValue, Message.obtain(
                    this, EVENT_REAPPLY_UICC_APPS_ENABLEMENT_DONE, expectedValue));
                    this, EVENT_REAPPLY_UICC_APPS_ENABLEMENT_DONE,
                    new Pair<Boolean, Integer>(expectedValue, retries)));
        }
    }

+42 −39
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
@@ -1265,45 +1266,47 @@ public class GsmCdmaPhoneTest extends TelephonyTest {
        verify(mSST).setRadioPower(true, true, false, true);
    }

    // TODO: b/146181737 uncomment below test.
//    @Test
//    @SmallTest
//    public void testReapplyUiccApplicationEnablementRetry() throws Exception {
//        mPhoneUT.mCi = mMockCi;
//        // Set SIM to be present, with a fake iccId, and notify enablement being false.
//        doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
//        doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mUiccSlot).getCardState();
//        String iccId = "Fake iccId";
//        doReturn(iccId).when(mUiccSlot).getIccId();
//        Message.obtain(mPhoneUT, EVENT_UICC_APPS_ENABLEMENT_CHANGED,
//                new AsyncResult(null, false, null)).sendToTarget();
//        processAllMessages();
//
//        // Should try to enable uicc applications as by default hey are expected to be true.
//        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
//        verify(mMockCi).enableUiccApplications(eq(true), messageCaptor.capture());
//        clearInvocations(mMockCi);
//        // Send message back with SIM_BUSY exception. Should retry.
//        AsyncResult.forMessage(messageCaptor.getValue(), null, new CommandException(
//                CommandException.Error.SIM_BUSY));
//        messageCaptor.getValue().sendToTarget();
//        processAllMessages();
//        // There should be a retry message.
//        moveTimeForward(5000);
//        processAllMessages();
//        verify(mMockCi).enableUiccApplications(eq(true), messageCaptor.capture());
//        clearInvocations(mMockCi);
//
//        // Send message back with NOT_SUPPORTED exception. Should retry.
//        AsyncResult.forMessage(messageCaptor.getValue(), null, new CommandException(
//                CommandException.Error.REQUEST_NOT_SUPPORTED));
//        messageCaptor.getValue().sendToTarget();
//        processAllMessages();
//        // There should not be a retry message.
//        moveTimeForward(5000);
//        processAllMessages();
//        verify(mMockCi, never()).enableUiccApplications(eq(true), messageCaptor.capture());
//    }
    @Test
    @SmallTest
    public void testReapplyUiccApplicationEnablementRetry() throws Exception {
        mPhoneUT.mCi = mMockCi;
        // Set SIM to be present, with a fake iccId, and notify enablement being false.
        doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
        doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mUiccSlot).getCardState();
        String iccId = "Fake iccId";
        doReturn(iccId).when(mUiccSlot).getIccId();
        Message.obtain(mPhoneUT, EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED,
                new AsyncResult(null, false, null)).sendToTarget();
        processAllMessages();

        // Should try to enable uicc applications as by default hey are expected to be true.
        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
        verify(mMockCi).enableUiccApplications(eq(true), messageCaptor.capture());
        clearInvocations(mMockCi);
        for (int i = 0; i < GsmCdmaPhone.ENABLE_UICC_APPS_MAX_RETRIES; i++) {
            // Send message back with SIM_BUSY exception. Should retry.
            AsyncResult.forMessage(messageCaptor.getValue(), null, new CommandException(
                    CommandException.Error.SIM_BUSY));
            messageCaptor.getValue().sendToTarget();
            processAllMessages();
            // There should be a retry message.
            moveTimeForward(5000);
            processAllMessages();
            verify(mMockCi).enableUiccApplications(eq(true), messageCaptor.capture());
            clearInvocations(mMockCi);
        }

        // Reaches max retries. Should NOT retry.
        AsyncResult.forMessage(messageCaptor.getValue(), null, new CommandException(
                CommandException.Error.SIM_BUSY));
        messageCaptor.getValue().sendToTarget();
        processAllMessages();
        // There should NOT be a retry message.
        moveTimeForward(5000);
        processAllMessages();
        verify(mMockCi, never()).enableUiccApplications(eq(true), messageCaptor.capture());
        clearInvocations(mMockCi);
    }

    @Test
    @SmallTest