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

Commit 973d9769 authored by Hyunho's avatar Hyunho Committed by Hyunho Shin
Browse files

Fix a potential issue with the state machine of EuiccConnector

When the service is dies, the binder is disconnected and the state is transition to the Disconnected state.
If the service is not restarted for a period of time afterward, it will transition to the Available state.
Fixed an issue that prevented service_connected from being handled if the service is restarted in the Available state

Bug: b/270110619
Test: atest EuiccConnectorTest
Change-Id: Idef5dfb024f6c7ad82b29060d58d549d99531182
Merged-In: Idef5dfb024f6c7ad82b29060d58d549d99531182
parent ecb458d3
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -101,7 +101,8 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
     * true or onServiceDisconnected is called (and no package change has occurred which should
     * force us to reestablish the binding).
     */
    private static final int BIND_TIMEOUT_MILLIS = 30000;
    @VisibleForTesting
    static final int BIND_TIMEOUT_MILLIS = 30000;

    /**
     * Maximum amount of idle time to hold the binding while in {@link ConnectedState}. After this,
@@ -556,6 +557,11 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
                callback);
    }

    @VisibleForTesting
    public final IEuiccService getBinder() {
        return mEuiccService;
    }

    /**
     * State in which no EuiccService is available.
     *
@@ -693,6 +699,7 @@ public class EuiccConnector extends StateMachine implements ServiceConnection {
                }
                return HANDLED;
            } else if (message.what == CMD_CONNECT_TIMEOUT) {
                unbind();
                transitionTo(mAvailableState);
                return HANDLED;
            } else if (isEuiccCommand(message.what)) {
+24 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.internal.telephony.euicc;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -354,6 +355,29 @@ public class EuiccConnectorTest extends TelephonyTest {
        assertEquals(mConnector.mAvailableState, mConnector.getCurrentState());
    }

    @Test
    public void testConnectedState_serviceDisconnected() throws Exception {
        // Kick off the asynchronous command.
        prepareEuiccApp(true /* hasPermission */, true /* requiresBindPermission */,
                true /* hasPriority */);
        mConnector = new EuiccConnector(mContext, mLooper.getLooper());
        mConnector.getEid(CARD_ID, new EuiccConnector.GetEidCommandCallback() {
            @Override public void onGetEidComplete(String eid) {}
            @Override public void onEuiccServiceUnavailable() {}
        });
        mLooper.dispatchAll();
        assertEquals(mConnector.mConnectedState, mConnector.getCurrentState());
        // Now, pretend the remote process died.
        mConnector.onServiceDisconnected(null /* name */);
        mLooper.dispatchAll();
        assertEquals(mConnector.mDisconnectedState, mConnector.getCurrentState());
        // After binder timeout, should now drop back to available state.
        mLooper.moveTimeForward(EuiccConnector.BIND_TIMEOUT_MILLIS);
        mLooper.dispatchAll();
        assertEquals(mConnector.mAvailableState, mConnector.getCurrentState());
        assertNull(mConnector.getBinder());
    }

    private void prepareEuiccApp(
            boolean hasPermission, boolean requiresBindPermission, boolean hasPriority) {
        when(mPackageManager.checkPermission(