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

Commit 817ab3f1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Enforce calls to KUM are done on main thread"

parents b93899a4 ba46d1ca
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ public class CarrierTextController {
    private static final String TAG = "CarrierTextController";

    private final boolean mIsEmergencyCallCapable;
    private final Handler mMainHandler;
    private boolean mTelephonyCapable;
    private boolean mShowMissingSim;
    private boolean mShowAirplaneMode;
@@ -169,6 +170,7 @@ public class CarrierTextController {
        mSimSlotsNumber = ((TelephonyManager) context.getSystemService(
                Context.TELEPHONY_SERVICE)).getMaxPhoneCount();
        mSimErrorState = new boolean[mSimSlotsNumber];
        mMainHandler = Dependency.get(Dependency.MAIN_HANDLER);
    }

    /**
@@ -227,7 +229,12 @@ public class CarrierTextController {
            if (whitelistIpcs(() -> ConnectivityManager.from(mContext).isNetworkSupported(
                    ConnectivityManager.TYPE_MOBILE))) {
                mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
                // Keyguard update monitor expects callbacks from main thread
                mMainHandler.post(() -> {
                    if (mKeyguardUpdateMonitor != null) {
                        mKeyguardUpdateMonitor.registerCallback(mCallback);
                    }
                });
                mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
                telephonyManager.listen(mPhoneStateListener,
                        LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
@@ -238,8 +245,13 @@ public class CarrierTextController {
            }
        } else {
            mCarrierTextCallback = null;
            if (mKeyguardUpdateMonitor != null) {
                // Keyguard update monitor expects callbacks from main thread
                mMainHandler.post(() -> {
                    if (mKeyguardUpdateMonitor != null) {
                        mKeyguardUpdateMonitor.removeCallback(mCallback);
                    }
                });
                mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
            }
            telephonyManager.listen(mPhoneStateListener, LISTEN_NONE);
@@ -364,10 +376,9 @@ public class CarrierTextController {

    @VisibleForTesting
    protected void postToCallback(CarrierTextCallbackInfo info) {
        Handler handler = Dependency.get(Dependency.MAIN_HANDLER);
        final CarrierTextCallback callback = mCarrierTextCallback;
        if (callback != null) {
            handler.post(() -> callback.updateCarrierInfo(info));
            mMainHandler.post(() -> callback.updateCarrierInfo(info));
        }
    }

+43 −21
Original line number Diff line number Diff line
@@ -26,20 +26,24 @@ import static junit.framework.TestCase.assertFalse;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Process;
import android.provider.Settings;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
@@ -62,6 +66,7 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;

import java.util.ArrayList;
import java.util.HashMap;
@@ -105,6 +110,14 @@ public class CarrierTextControllerTest extends SysuiTestCase {
    private CarrierTextController mCarrierTextController;
    private TestableLooper mTestableLooper;

    private Void checkMainThread(InvocationOnMock inv) {
        Looper mainLooper = Dependency.get(Dependency.MAIN_HANDLER).getLooper();
        if (!mainLooper.isCurrentThread()) {
            fail("This call should be done from the main thread");
        }
        return null;
    }

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
@@ -112,6 +125,7 @@ public class CarrierTextControllerTest extends SysuiTestCase {

        mContext.addMockSystemService(WifiManager.class, mWifiManager);
        mContext.addMockSystemService(ConnectivityManager.class, mConnectivityManager);
        when(mConnectivityManager.isNetworkSupported(anyInt())).thenReturn(true);
        mContext.addMockSystemService(TelephonyManager.class, mTelephonyManager);
        mContext.addMockSystemService(SubscriptionManager.class, mSubscriptionManager);
        mContext.getOrCreateTestableResources().addOverride(
@@ -121,16 +135,40 @@ public class CarrierTextControllerTest extends SysuiTestCase {
        mDependency.injectMockDependency(WakefulnessLifecycle.class);
        mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
                new Handler(mTestableLooper.getLooper()));
        mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
        mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);

        doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
                .registerCallback(any(KeyguardUpdateMonitorCallback.class));
        doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
                .removeCallback(any(KeyguardUpdateMonitorCallback.class));

        mCarrierTextCallbackInfo = new CarrierTextController.CarrierTextCallbackInfo("",
                new CharSequence[]{}, false, new int[]{});
        when(mTelephonyManager.getMaxPhoneCount()).thenReturn(3);

        mCarrierTextController = new TestCarrierTextController(mContext, SEPARATOR, true, true,
                mKeyguardUpdateMonitor);
        // This should not start listening on any of the real dependencies
        mCarrierTextController = new CarrierTextController(mContext, SEPARATOR, true, true);
        // This should not start listening on any of the real dependencies but will test that
        // callbacks in mKeyguardUpdateMonitor are done in the mTestableLooper thread
        mCarrierTextController.setListening(mCarrierTextCallback);
    }

    @Test
    public void testKeyguardUpdateMonitorCalledInMainThread() throws Exception {
        // This test will run on the main looper (which is not the same as the looper set as MAIN
        // for CarrierTextCallback. This will fail if calls to mKeyguardUpdateMonitor are not done
        // through the looper set in the set up
        HandlerThread thread = new HandlerThread("testThread",
                Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();
        TestableLooper testableLooper = new TestableLooper(thread.getLooper());
        Handler h = new Handler(testableLooper.getLooper());
        h.post(() -> {
            mCarrierTextController.setListening(null);
            mCarrierTextController.setListening(mCarrierTextCallback);
        });
        testableLooper.processAllMessages();
        mTestableLooper.processAllMessages();
        thread.quitSafely();
    }

    @Test
@@ -466,20 +504,4 @@ public class CarrierTextControllerTest extends SysuiTestCase {
        assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER,
                captor.getValue().carrierText);
    }

    public static class TestCarrierTextController extends CarrierTextController {
        private KeyguardUpdateMonitor mKUM;

        public TestCarrierTextController(Context context, CharSequence separator,
                boolean showAirplaneMode, boolean showMissingSim, KeyguardUpdateMonitor kum) {
            super(context, separator, showAirplaneMode, showMissingSim);
            mKUM = kum;
        }

        @Override
        public void setListening(CarrierTextCallback callback) {
            super.setListening(callback);
            mKeyguardUpdateMonitor = mKUM;
        }
    }
}