Loading src/java/com/android/internal/telephony/GsmCdmaPhone.java +23 −14 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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); Loading Loading @@ -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) { Loading Loading @@ -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. Loading @@ -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))); } } } } Loading tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java +42 −39 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading
src/java/com/android/internal/telephony/GsmCdmaPhone.java +23 −14 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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); Loading Loading @@ -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) { Loading Loading @@ -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. Loading @@ -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))); } } } } Loading
tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java +42 −39 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading