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

Commit 381dccc7 authored by Nagendra Prasad Nagarle Basavaraju's avatar Nagendra Prasad Nagarle Basavaraju Committed by Cherrypicker Worker
Browse files

[ProxyController]Wake Lock Issue during setRadioCapability error case

-Avoid ignoring the session at onStartRadioCapabilityResponse() when
there is exception
-Avoid ignoring the session at onFinishRadioCapabilityResponse() when
there is exception

Bug: 269174024
Test: build,device & atest
Change-Id: Ia7162d9c50461600b8a8d8b9b0febbf0f6a7a52c
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:98ea73acea86fb34a7ff1e58bc59205651696f61)
Merged-In: Ia7162d9c50461600b8a8d8b9b0febbf0f6a7a52c
parent 48f703ab
Loading
Loading
Loading
Loading
+30 −14
Original line number Diff line number Diff line
@@ -47,8 +47,10 @@ public class ProxyController {
    @VisibleForTesting
    static final int EVENT_START_RC_RESPONSE                = 2;
    private static final int EVENT_APPLY_RC_RESPONSE        = 3;
    private static final int EVENT_FINISH_RC_RESPONSE       = 4;
    private static final int EVENT_TIMEOUT                  = 5;
    @VisibleForTesting
    public static final int EVENT_FINISH_RC_RESPONSE        = 4;
    @VisibleForTesting
    public static final int EVENT_TIMEOUT                   = 5;
    @VisibleForTesting
    public static final int EVENT_MULTI_SIM_CONFIG_CHANGED  = 6;

@@ -212,6 +214,7 @@ public class ProxyController {
        clearTransaction();

        // Keep a wake lock until we finish radio capability changed
        logd("Acquiring wake lock for setting radio capability");
        mWakeLock.acquire();

        return doSetRadioCapabilities(rafs);
@@ -357,19 +360,25 @@ public class ProxyController {
                }
            }
            RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result;
            if ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId)) {
            // Added exception condition  to continue to mark as transaction fail case.
            // Checking session validity during exception is not valid
            if (ar.exception == null
                    && ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId))) {
                logd("onStartRadioCapabilityResponse: Ignore session=" + mRadioCapabilitySessionId
                        + " rc=" + rc);
                return;
            }
            mRadioAccessFamilyStatusCounter--;
            int id = rc.getPhoneId();
            //rc.getPhoneId() moved to avoid Null Pointer Exception, since when exception occurs
            //its expected rc is null.
            if (ar.exception != null) {
                logd("onStartRadioCapabilityResponse: Error response session=" + rc.getSession());
                logd("onStartRadioCapabilityResponse: phoneId=" + id + " status=FAIL");
                mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
                logd("onStartRadioCapabilityResponse got exception=" + ar.exception);
                //mSetRadioAccessFamilyStatus will be set anyway to SET_RC_STATUS_FAIL
                // if either of them fail at issueFinish() method below,i.e. both phone id count
                // is set to SET_RC_STATUS_FAIL.
                mTransactionFailed = true;
            } else {
                int id = rc.getPhoneId();
                logd("onStartRadioCapabilityResponse: phoneId=" + id + " status=STARTED");
                mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_STARTED;
            }
@@ -481,13 +490,20 @@ public class ProxyController {
     * @param msg obj field isa RadioCapability
     */
    void onFinishRadioCapabilityResponse(Message msg) {
        synchronized (mSetRadioAccessFamilyStatus) {
            AsyncResult ar = (AsyncResult)  msg.obj;
            RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result;
        if ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId)) {
            logd("onFinishRadioCapabilityResponse: Ignore session=" + mRadioCapabilitySessionId
                    + " rc=" + rc);
            // Added exception condition on finish to continue to revert if exception occurred.
            // Checking session validity during exception is not valid
            if (ar.exception == null
                    && ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId))) {
                logd("onFinishRadioCapabilityResponse: Ignore session="
                        + mRadioCapabilitySessionId + " rc=" + rc);
                return;
            }
        synchronized (mSetRadioAccessFamilyStatus) {
            if (ar.exception != null) {
                logd("onFinishRadioCapabilityResponse got exception=" + ar.exception);
            }
            logd(" onFinishRadioCapabilityResponse mRadioAccessFamilyStatusCounter="
                    + mRadioAccessFamilyStatusCounter);
            mRadioAccessFamilyStatusCounter--;
@@ -575,7 +591,6 @@ public class ProxyController {
            clearTransaction();
        } else {
            intent = new Intent(TelephonyIntents.ACTION_SET_RADIO_CAPABILITY_FAILED);

            // now revert.
            mTransactionFailed = false;
            RadioAccessFamily[] rafs = new RadioAccessFamily[mPhones.length];
@@ -602,6 +617,7 @@ public class ProxyController {
            }

            if (isWakeLockHeld()) {
                logd("clearTransaction:checking wakelock held and releasing");
                mWakeLock.release();
            }
        }
+133 −3
Original line number Diff line number Diff line
@@ -19,10 +19,13 @@ package com.android.internal.telephony;
import static android.telephony.RadioAccessFamily.RAF_GSM;
import static android.telephony.RadioAccessFamily.RAF_LTE;

import static com.android.internal.telephony.ProxyController.EVENT_FINISH_RC_RESPONSE;
import static com.android.internal.telephony.ProxyController.EVENT_MULTI_SIM_CONFIG_CHANGED;
import static com.android.internal.telephony.ProxyController.EVENT_START_RC_RESPONSE;
import static com.android.internal.telephony.ProxyController.EVENT_TIMEOUT;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
@@ -97,12 +100,139 @@ public class ProxyControllerTest extends TelephonyTest {
        rafs[1] = new RadioAccessFamily(1, RAF_GSM | RAF_LTE);
        mProxyController.setRadioCapability(rafs);

        Message.obtain(mProxyController.mHandler, EVENT_START_RC_RESPONSE,
                new AsyncResult(null, null,
        Message.obtain(
                        mProxyController.mHandler,
                        EVENT_START_RC_RESPONSE,
                        new AsyncResult(
                                null,
                                null,
                                new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED)))
                .sendToTarget();
        processAllMessages();

        assertFalse(mProxyController.isWakeLockHeld());
    }

    @Test
    @SmallTest
    public void testWithNonPermanentExceptionOnRCResponse_WithExceptionOnFinishResponse()
            throws Exception {
        int activeModemCount = 2;
        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone, mPhone2});
        doReturn(activeModemCount).when(mTelephonyManager).getPhoneCount();
        doReturn(RAF_GSM | RAF_LTE).when(mPhone).getRadioAccessFamily();
        doReturn(RAF_GSM).when(mPhone2).getRadioAccessFamily();

        Message.obtain(mProxyController.mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED).sendToTarget();
        processAllMessages();
        verify(mPhone2).registerForRadioCapabilityChanged(any(), anyInt(), any());

        RadioAccessFamily[] rafs = new RadioAccessFamily[activeModemCount];
        rafs[0] = new RadioAccessFamily(0, RAF_GSM);
        rafs[1] = new RadioAccessFamily(1, RAF_GSM | RAF_LTE);
        mProxyController.setRadioCapability(rafs);

        Message.obtain(
                        mProxyController.mHandler,
                        EVENT_START_RC_RESPONSE,
                        new AsyncResult(
                                null,
                                null,
                                new CommandException(CommandException.Error.RADIO_NOT_AVAILABLE)))
                .sendToTarget();
        processAllMessages();
        assertTrue(mProxyController.isWakeLockHeld());
        onFinishResponseWithException();
    }

    @Test
    @SmallTest
    public void testWithNonPermanentExceptionOnRCResponse_WithoutExceptionOnFinishResponse()
            throws Exception {
        int activeModemCount = 2;
        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone, mPhone2});
        doReturn(activeModemCount).when(mTelephonyManager).getPhoneCount();
        doReturn(RAF_GSM | RAF_LTE).when(mPhone).getRadioAccessFamily();
        doReturn(RAF_GSM).when(mPhone2).getRadioAccessFamily();

        Message.obtain(mProxyController.mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED).sendToTarget();
        processAllMessages();
        verify(mPhone2).registerForRadioCapabilityChanged(any(), anyInt(), any());

        RadioAccessFamily[] rafs = new RadioAccessFamily[activeModemCount];
        rafs[0] = new RadioAccessFamily(0, RAF_GSM);
        rafs[1] = new RadioAccessFamily(1, RAF_GSM | RAF_LTE);
        mProxyController.setRadioCapability(rafs);

        Message.obtain(
                        mProxyController.mHandler,
                        EVENT_START_RC_RESPONSE,
                        new AsyncResult(null, null, null))
                .sendToTarget();
        processAllMessages();
        assertTrue(mProxyController.isWakeLockHeld());
        onFinishResponseWithoutException();
    }

    @Test
    @SmallTest
    public void testOnRCResponseTimeout_WithExceptionOnFinishResponse() throws Exception {
        int activeModemCount = 2;
        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone, mPhone2});
        doReturn(activeModemCount).when(mTelephonyManager).getPhoneCount();
        doReturn(RAF_GSM | RAF_LTE).when(mPhone).getRadioAccessFamily();
        doReturn(RAF_GSM).when(mPhone2).getRadioAccessFamily();

        Message.obtain(mProxyController.mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED).sendToTarget();
        processAllMessages();
        verify(mPhone2).registerForRadioCapabilityChanged(any(), anyInt(), any());

        RadioAccessFamily[] rafs = new RadioAccessFamily[activeModemCount];
        rafs[0] = new RadioAccessFamily(0, RAF_GSM);
        rafs[1] = new RadioAccessFamily(1, RAF_GSM | RAF_LTE);
        mProxyController.setRadioCapability(rafs);

        Message.obtain(
                        mProxyController.mHandler,
                        EVENT_TIMEOUT,
                        new AsyncResult(
                                null,
                                null,
                                new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED)))
                .sendToTarget();
        processAllMessages();
        onFinishResponseWithException();
    }

    private void onFinishResponseWithException() throws Exception {
        replaceInstance(
                ProxyController.class, "mRadioAccessFamilyStatusCounter", mProxyController, 1);
        replaceInstance(ProxyController.class, "mTransactionFailed", mProxyController, true);
        Message.obtain(
                        mProxyController.mHandler,
                        EVENT_FINISH_RC_RESPONSE,
                        new AsyncResult(
                                null,
                                null,
                                new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED)))
                .sendToTarget();
        processAllMessages();
        assertTrue(mProxyController.isWakeLockHeld());
    }

    private void onFinishResponseWithoutException() throws Exception {
        replaceInstance(
                ProxyController.class, "mRadioAccessFamilyStatusCounter", mProxyController, 1);
        replaceInstance(ProxyController.class, "mTransactionFailed", mProxyController, false);
        replaceInstance(
                ProxyController.class, "mRadioCapabilitySessionId", mProxyController, 123456);
        Message.obtain(
                        mProxyController.mHandler,
                        EVENT_FINISH_RC_RESPONSE,
                        new AsyncResult(
                                null, new RadioCapability(0, 123456, 0, 0, "test_modem", 0), null))
                .sendToTarget();
        processAllMessages();
        assertFalse(mProxyController.isWakeLockHeld());
    }
}