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

Commit a5b7aac5 authored by Xiangyu/Malcolm Chen's avatar Xiangyu/Malcolm Chen Committed by Android (Google) Code Review
Browse files

Merge "Gracefully handle ENABLE_UICC_APPLICATIONS failure." into rvc-dev

parents e866eed4 5a17f851
Loading
Loading
Loading
Loading
+23 −14
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.internal.telephony;
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_DISABLE;
import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ERASURE;
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
    // 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.
    // param being set and we should generate a simulated exit from the modem upon exit of ECbM.
    private boolean mIsTestingEmergencyCallbackMode = false;
    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.
    // A runnable which is used to automatically exit from Ecm after a period of time.
    private Runnable mExitEcmRunnable = new Runnable() {
    private Runnable mExitEcmRunnable = new Runnable() {
@@ -3066,24 +3071,27 @@ public class GsmCdmaPhone extends Phone {
                mUiccApplicationsEnabled = (Boolean) ar.result;
                mUiccApplicationsEnabled = (Boolean) ar.result;
            // Intentional falling through.
            // Intentional falling through.
            case EVENT_UICC_APPS_ENABLEMENT_SETTING_CHANGED:
            case EVENT_UICC_APPS_ENABLEMENT_SETTING_CHANGED:
                reapplyUiccAppsEnablementIfNeeded();
                reapplyUiccAppsEnablementIfNeeded(ENABLE_UICC_APPS_MAX_RETRIES);
                break;
                break;


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


        reapplyUiccAppsEnablementIfNeeded();
        reapplyUiccAppsEnablementIfNeeded(ENABLE_UICC_APPS_MAX_RETRIES);
    }
    }


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


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


        // If no card is present or we don't have mUiccApplicationsEnabled yet, do nothing.
        // 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.
        // configured state.
        if (expectedValue != mUiccApplicationsEnabled) {
        if (expectedValue != mUiccApplicationsEnabled) {
            mCi.enableUiccApplications(expectedValue, Message.obtain(
            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 Original line 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.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.eq;
@@ -1265,45 +1266,47 @@ public class GsmCdmaPhoneTest extends TelephonyTest {
        verify(mSST).setRadioPower(true, true, false, true);
        verify(mSST).setRadioPower(true, true, false, true);
    }
    }


    // TODO: b/146181737 uncomment below test.
    @Test
//    @Test
    @SmallTest
//    @SmallTest
    public void testReapplyUiccApplicationEnablementRetry() throws Exception {
//    public void testReapplyUiccApplicationEnablementRetry() throws Exception {
        mPhoneUT.mCi = mMockCi;
//        mPhoneUT.mCi = mMockCi;
        // Set SIM to be present, with a fake iccId, and notify enablement being false.
//        // Set SIM to be present, with a fake iccId, and notify enablement being false.
        doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
//        doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
        doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mUiccSlot).getCardState();
//        doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mUiccSlot).getCardState();
        String iccId = "Fake iccId";
//        String iccId = "Fake iccId";
        doReturn(iccId).when(mUiccSlot).getIccId();
//        doReturn(iccId).when(mUiccSlot).getIccId();
        Message.obtain(mPhoneUT, EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED,
//        Message.obtain(mPhoneUT, EVENT_UICC_APPS_ENABLEMENT_CHANGED,
                new AsyncResult(null, false, null)).sendToTarget();
//                new AsyncResult(null, false, null)).sendToTarget();
        processAllMessages();
//        processAllMessages();

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

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


    @Test
    @Test
    @SmallTest
    @SmallTest