Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package android.telephony.cts;
     17 
     18 import static androidx.test.InstrumentationRegistry.getContext;
     19 
     20 import static com.google.common.truth.Truth.assertThat;
     21 
     22 import static org.junit.Assert.assertEquals;
     23 import static org.junit.Assert.assertFalse;
     24 import static org.junit.Assert.assertTrue;
     25 
     26 import android.content.Context;
     27 import android.os.Looper;
     28 import android.telephony.CellInfo;
     29 import android.telephony.CellLocation;
     30 import android.telephony.PhoneStateListener;
     31 import android.telephony.PreciseCallState;
     32 import android.telephony.PreciseDataConnectionState;
     33 import android.telephony.ServiceState;
     34 import android.telephony.SignalStrength;
     35 import android.telephony.TelephonyManager;
     36 import android.net.ConnectivityManager;
     37 import android.telephony.ims.ImsReasonInfo;
     38 import android.util.Log;
     39 
     40 import com.android.compatibility.common.util.ShellIdentityUtils;
     41 import com.android.compatibility.common.util.TestThread;
     42 
     43 import java.util.Arrays;
     44 import java.util.List;
     45 import java.util.concurrent.Executor;
     46 
     47 import org.junit.After;
     48 import org.junit.Before;
     49 import org.junit.Test;
     50 
     51 public class PhoneStateListenerTest {
     52 
     53     public static final long WAIT_TIME = 1000;
     54 
     55     private boolean mOnActiveDataSubscriptionIdChanged;
     56     private boolean mOnCallForwardingIndicatorChangedCalled;
     57     private boolean mOnCallStateChangedCalled;
     58     private boolean mOnCellLocationChangedCalled;
     59     private boolean mOnUserMobileDataStateChanged;
     60     private boolean mOnDataActivityCalled;
     61     private boolean mOnDataConnectionStateChangedCalled;
     62     private boolean mOnDataConnectionStateChangedWithNetworkTypeCalled;
     63     private boolean mOnMessageWaitingIndicatorChangedCalled;
     64     private boolean mOnCellInfoChangedCalled;
     65     private boolean mOnServiceStateChangedCalled;
     66     private boolean mOnSignalStrengthChangedCalled;
     67     private boolean mOnPreciseCallStateChangedCalled;
     68     private boolean mOnCallDisconnectCauseChangedCalled;
     69     private boolean mOnImsCallDisconnectCauseChangedCalled;
     70     private boolean mOnPreciseDataConnectionStateChanged;
     71     private boolean mOnRadioPowerStateChangedCalled;
     72     private boolean mVoiceActivationStateChangedCalled;
     73     private boolean mSrvccStateChangedCalled;
     74     @TelephonyManager.RadioPowerState private int mRadioPowerState;
     75     @TelephonyManager.SimActivationState private int mVoiceActivationState;
     76     private PreciseDataConnectionState mPreciseDataConnectionState;
     77     private PreciseCallState mPreciseCallState;
     78     private SignalStrength mSignalStrength;
     79     private TelephonyManager mTelephonyManager;
     80     private PhoneStateListener mListener;
     81     private final Object mLock = new Object();
     82     private static final String TAG = "android.telephony.cts.PhoneStateListenerTest";
     83     private static ConnectivityManager mCm;
     84     private static final List<Integer> DATA_CONNECTION_STATE = Arrays.asList(
     85             TelephonyManager.DATA_CONNECTED,
     86             TelephonyManager.DATA_DISCONNECTED,
     87             TelephonyManager.DATA_CONNECTING,
     88             TelephonyManager.DATA_UNKNOWN,
     89             TelephonyManager.DATA_SUSPENDED
     90     );
     91     private static final List<Integer> PRECISE_CALL_STATE = Arrays.asList(
     92             PreciseCallState.PRECISE_CALL_STATE_ACTIVE,
     93             PreciseCallState.PRECISE_CALL_STATE_ALERTING,
     94             PreciseCallState.PRECISE_CALL_STATE_DIALING,
     95             PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED,
     96             PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING,
     97             PreciseCallState.PRECISE_CALL_STATE_HOLDING,
     98             PreciseCallState.PRECISE_CALL_STATE_IDLE,
     99             PreciseCallState.PRECISE_CALL_STATE_INCOMING,
    100             PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
    101             PreciseCallState.PRECISE_CALL_STATE_WAITING
    102     );
    103     private Executor mSimpleExecutor = new Executor() {
    104         @Override
    105         public void execute(Runnable r) {
    106             r.run();
    107         }
    108     };
    109 
    110     @Before
    111     public void setUp() throws Exception {
    112         mTelephonyManager =
    113                 (TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);
    114         mCm = (ConnectivityManager)getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    115     }
    116 
    117     @After
    118     public void tearDown() throws Exception {
    119         if (mListener != null) {
    120             // unregister the listener
    121             mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
    122         }
    123     }
    124 
    125     @Test
    126     public void testPhoneStateListener() {
    127         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    128             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    129             return;
    130         }
    131 
    132         Looper.prepare();
    133         new PhoneStateListener();
    134     }
    135 
    136     /*
    137      * The tests below rely on the framework to immediately call the installed listener upon
    138      * registration. There is no simple way to emulate state changes for testing the listeners.
    139      */
    140 
    141     @Test
    142     public void testOnServiceStateChanged() throws Throwable {
    143         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    144             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    145             return;
    146         }
    147 
    148         TestThread t = new TestThread(new Runnable() {
    149             public void run() {
    150                 Looper.prepare();
    151 
    152                 mListener = new PhoneStateListener() {
    153                     @Override
    154                     public void onServiceStateChanged(ServiceState serviceState) {
    155                         synchronized(mLock) {
    156                             mOnServiceStateChangedCalled = true;
    157                             mLock.notify();
    158                         }
    159                     }
    160                 };
    161                 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
    162 
    163                 Looper.loop();
    164             }
    165         });
    166 
    167         assertFalse(mOnServiceStateChangedCalled);
    168         t.start();
    169 
    170         synchronized (mLock) {
    171             if (!mOnServiceStateChangedCalled){
    172                 mLock.wait(WAIT_TIME);
    173             }
    174         }
    175         t.checkException();
    176         assertTrue(mOnServiceStateChangedCalled);
    177     }
    178 
    179     @Test
    180     public void testOnUnRegisterFollowedByRegister() throws Throwable {
    181         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    182             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    183             return;
    184         }
    185 
    186         TestThread t = new TestThread(new Runnable() {
    187             public void run() {
    188                 Looper.prepare();
    189 
    190                 mListener = new PhoneStateListener() {
    191                     @Override
    192                     public void onServiceStateChanged(ServiceState serviceState) {
    193                         synchronized(mLock) {
    194                             mOnServiceStateChangedCalled = true;
    195                             mLock.notify();
    196                         }
    197                     }
    198                 };
    199                 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
    200 
    201                 Looper.loop();
    202             }
    203         });
    204 
    205         assertFalse(mOnServiceStateChangedCalled);
    206         t.start();
    207 
    208         synchronized (mLock) {
    209             if (!mOnServiceStateChangedCalled){
    210                 mLock.wait(WAIT_TIME);
    211             }
    212         }
    213         t.checkException();
    214         assertTrue(mOnServiceStateChangedCalled);
    215 
    216         // reset and un-register
    217         mOnServiceStateChangedCalled = false;
    218         if (mListener != null) {
    219             // un-register the listener
    220             mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
    221         }
    222         synchronized (mLock) {
    223             if (!mOnServiceStateChangedCalled){
    224                 mLock.wait(WAIT_TIME);
    225             }
    226         }
    227         assertFalse(mOnServiceStateChangedCalled);
    228 
    229         // re-register the listener
    230         mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
    231         synchronized (mLock) {
    232             if (!mOnServiceStateChangedCalled){
    233                 mLock.wait(WAIT_TIME);
    234             }
    235         }
    236         t.checkException();
    237         assertTrue(mOnServiceStateChangedCalled);
    238     }
    239 
    240     @Test
    241     public void testOnSignalStrengthChanged() throws Throwable {
    242         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    243             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    244             return;
    245         }
    246 
    247         TestThread t = new TestThread(new Runnable() {
    248             public void run() {
    249                 Looper.prepare();
    250 
    251                 mListener = new PhoneStateListener() {
    252                     @Override
    253                     public void onSignalStrengthChanged(int asu) {
    254                         synchronized(mLock) {
    255                             mOnSignalStrengthChangedCalled = true;
    256                             mLock.notify();
    257                         }
    258                     }
    259                 };
    260                 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTH);
    261 
    262                 Looper.loop();
    263             }
    264         });
    265 
    266         assertFalse(mOnSignalStrengthChangedCalled);
    267         t.start();
    268 
    269         synchronized (mLock) {
    270             if (!mOnSignalStrengthChangedCalled){
    271                 mLock.wait(WAIT_TIME);
    272             }
    273         }
    274         t.checkException();
    275         assertTrue(mOnSignalStrengthChangedCalled);
    276     }
    277 
    278     @Test
    279     public void testOnSignalStrengthsChanged() throws Throwable {
    280         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    281             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    282             return;
    283         }
    284 
    285         TestThread t = new TestThread(new Runnable() {
    286             public void run() {
    287                 Looper.prepare();
    288 
    289                 mListener = new PhoneStateListener() {
    290                     @Override
    291                     public void onSignalStrengthsChanged(SignalStrength signalStrength) {
    292                         synchronized(mLock) {
    293                             mSignalStrength = signalStrength;
    294                             mLock.notify();
    295                         }
    296                     }
    297                 };
    298                 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
    299 
    300                 Looper.loop();
    301             }
    302         });
    303 
    304         assertTrue(mSignalStrength == null);
    305         t.start();
    306 
    307         synchronized (mLock) {
    308             if (mSignalStrength == null) {
    309                 mLock.wait(WAIT_TIME);
    310             }
    311         }
    312         t.checkException();
    313         assertTrue(mSignalStrength != null);
    314 
    315         // Call SignalStrength methods to make sure they do not throw any exceptions
    316         mSignalStrength.getCdmaDbm();
    317         mSignalStrength.getCdmaEcio();
    318         mSignalStrength.getEvdoDbm();
    319         mSignalStrength.getEvdoEcio();
    320         mSignalStrength.getEvdoSnr();
    321         mSignalStrength.getGsmBitErrorRate();
    322         mSignalStrength.getGsmSignalStrength();
    323         mSignalStrength.isGsm();
    324         mSignalStrength.getLevel();
    325     }
    326 
    327     @Test
    328     public void testOnMessageWaitingIndicatorChanged() throws Throwable {
    329         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    330             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    331             return;
    332         }
    333 
    334         TestThread t = new TestThread(new Runnable() {
    335             public void run() {
    336                 Looper.prepare();
    337 
    338                 mListener = new PhoneStateListener() {
    339                     @Override
    340                     public void onMessageWaitingIndicatorChanged(boolean mwi) {
    341                         synchronized(mLock) {
    342                             mOnMessageWaitingIndicatorChangedCalled = true;
    343                             mLock.notify();
    344                         }
    345                     }
    346                 };
    347                 mTelephonyManager.listen(
    348                         mListener, PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR);
    349 
    350                 Looper.loop();
    351             }
    352         });
    353 
    354         assertFalse(mOnMessageWaitingIndicatorChangedCalled);
    355         t.start();
    356 
    357         synchronized (mLock) {
    358             if (!mOnMessageWaitingIndicatorChangedCalled){
    359                 mLock.wait(WAIT_TIME);
    360             }
    361         }
    362         t.checkException();
    363         assertTrue(mOnMessageWaitingIndicatorChangedCalled);
    364     }
    365 
    366     /*
    367      * The tests below rely on the framework to immediately call the installed listener upon
    368      * registration. There is no simple way to emulate state changes for testing the listeners.
    369      */
    370     @Test
    371     public void testOnPreciseCallStateChanged() throws Throwable {
    372         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    373             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    374             return;
    375         }
    376 
    377         TestThread t = new TestThread(new Runnable() {
    378             public void run() {
    379                 Looper.prepare();
    380 
    381                 mListener = new PhoneStateListener() {
    382                     @Override
    383                     public void onPreciseCallStateChanged(PreciseCallState preciseCallState) {
    384                         synchronized (mLock) {
    385                             mOnPreciseCallStateChangedCalled = true;
    386                             mPreciseCallState = preciseCallState;
    387                             mLock.notify();
    388                         }
    389                     }
    390                 };
    391                 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
    392                         (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_PRECISE_CALL_STATE));
    393                 Looper.loop();
    394             }
    395         });
    396 
    397         assertThat(mOnPreciseCallStateChangedCalled).isFalse();
    398         t.start();
    399 
    400         synchronized (mLock) {
    401             if (!mOnPreciseCallStateChangedCalled) {
    402                 mLock.wait(WAIT_TIME);
    403             }
    404         }
    405         t.checkException();
    406         Log.d(TAG, "testOnPreciseCallStateChanged: " + mOnPreciseCallStateChangedCalled);
    407         assertThat(mOnPreciseCallStateChangedCalled).isTrue();
    408         assertThat(mPreciseCallState.getForegroundCallState()).isIn(PRECISE_CALL_STATE);
    409         assertThat(mPreciseCallState.getBackgroundCallState()).isIn(PRECISE_CALL_STATE);
    410         assertThat(mPreciseCallState.getRingingCallState()).isIn(PRECISE_CALL_STATE);
    411     }
    412 
    413     /*
    414      * The tests below rely on the framework to immediately call the installed listener upon
    415      * registration. There is no simple way to emulate state changes for testing the listeners.
    416      */
    417     @Test
    418     public void testOnCallDisconnectCauseChanged() throws Throwable {
    419         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    420             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    421             return;
    422         }
    423 
    424         TestThread t = new TestThread(new Runnable() {
    425             public void run() {
    426                 Looper.prepare();
    427 
    428                 mListener = new PhoneStateListener() {
    429                     @Override
    430                     public void onCallDisconnectCauseChanged(int disconnectCause,
    431                                                              int preciseDisconnectCause) {
    432                         synchronized (mLock) {
    433                             mOnCallDisconnectCauseChangedCalled = true;
    434                             mLock.notify();
    435                         }
    436                     }
    437                 };
    438                 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
    439                             (tm) -> tm.listen(mListener,
    440                                     PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES));
    441                 Looper.loop();
    442             }
    443         });
    444 
    445         assertThat(mOnCallDisconnectCauseChangedCalled).isFalse();
    446         t.start();
    447 
    448         synchronized (mLock) {
    449             if (!mOnCallDisconnectCauseChangedCalled){
    450                 mLock.wait(WAIT_TIME);
    451             }
    452         }
    453         t.checkException();
    454         assertThat(mOnCallDisconnectCauseChangedCalled).isTrue();
    455     }
    456 
    457     /*
    458      * The tests below rely on the framework to immediately call the installed listener upon
    459      * registration. There is no simple way to emulate state changes for testing the listeners.
    460      */
    461     @Test
    462     public void testOnImsCallDisconnectCauseChanged() throws Throwable {
    463         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    464             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    465             return;
    466         }
    467 
    468         TestThread t = new TestThread(new Runnable() {
    469             public void run() {
    470                 Looper.prepare();
    471 
    472                 mListener = new PhoneStateListener() {
    473                     @Override
    474                     public void onImsCallDisconnectCauseChanged(ImsReasonInfo imsReason) {
    475                         synchronized (mLock) {
    476                             mOnImsCallDisconnectCauseChangedCalled = true;
    477                             mLock.notify();
    478                         }
    479                     }
    480                 };
    481                 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
    482                         (tm) -> tm.listen(mListener,
    483                                 PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES));
    484                 Looper.loop();
    485             }
    486         });
    487 
    488         assertThat(mOnImsCallDisconnectCauseChangedCalled).isFalse();
    489         t.start();
    490 
    491         synchronized (mLock) {
    492             if (!mOnImsCallDisconnectCauseChangedCalled){
    493                 mLock.wait(WAIT_TIME);
    494             }
    495         }
    496         t.checkException();
    497         assertThat(mOnImsCallDisconnectCauseChangedCalled).isTrue();
    498     }
    499 
    500     @Test
    501     public void testOnPhoneStateListenerExecutorWithSrvccChanged() throws Throwable {
    502         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    503             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    504             return;
    505         }
    506         TestThread t = new TestThread(new Runnable() {
    507             public void run() {
    508                 Looper.prepare();
    509 
    510                 mListener = new PhoneStateListener(mSimpleExecutor) {
    511                     @Override
    512                     public void onSrvccStateChanged(int state) {
    513                         synchronized (mLock) {
    514                             mSrvccStateChangedCalled = true;
    515                             mLock.notify();
    516                         }
    517                     }
    518                 };
    519                 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
    520                         (tm) -> tm.listen(mListener,
    521                                 PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED));
    522                 Looper.loop();
    523             }
    524         });
    525 
    526         assertThat(mSrvccStateChangedCalled).isFalse();
    527         t.start();
    528 
    529         synchronized (mLock) {
    530             if (!mSrvccStateChangedCalled){
    531                 mLock.wait(WAIT_TIME);
    532             }
    533         }
    534         assertThat(mSrvccStateChangedCalled).isTrue();
    535         t.checkException();
    536         Log.d(TAG, "testOnPhoneStateListenerExecutorWithSrvccChanged");
    537     }
    538 
    539     /*
    540     * The tests below rely on the framework to immediately call the installed listener upon
    541     * registration. There is no simple way to emulate state changes for testing the listeners.
    542     */
    543     @Test
    544     public void testOnRadioPowerStateChanged() throws Throwable {
    545         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    546             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    547             return;
    548         }
    549         TestThread t = new TestThread(new Runnable() {
    550             public void run() {
    551                 Looper.prepare();
    552 
    553                 mListener = new PhoneStateListener() {
    554                     @Override
    555                     public void onRadioPowerStateChanged(int state) {
    556                         synchronized(mLock) {
    557                             mRadioPowerState = state;
    558                             mOnRadioPowerStateChangedCalled = true;
    559                             mLock.notify();
    560                         }
    561                     }
    562                 };
    563                 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
    564                         (tm) -> tm.listen(mListener,
    565                                 PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED));
    566                 Looper.loop();
    567             }
    568         });
    569         assertThat(mOnRadioPowerStateChangedCalled).isFalse();
    570         t.start();
    571 
    572         synchronized (mLock) {
    573             if (!mOnRadioPowerStateChangedCalled){
    574                 mLock.wait(WAIT_TIME);
    575             }
    576         }
    577         t.checkException();
    578         Log.d(TAG, "testOnRadioPowerStateChanged: " + mRadioPowerState);
    579         assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(mRadioPowerState);
    580     }
    581 
    582     /*
    583      * The tests below rely on the framework to immediately call the installed listener upon
    584      * registration. There is no simple way to emulate state changes for testing the listeners.
    585      */
    586     @Test
    587     public void testOnVoiceActivationStateChanged() throws Throwable {
    588         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    589             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    590             return;
    591         }
    592         TestThread t = new TestThread(new Runnable() {
    593             public void run() {
    594                 Looper.prepare();
    595 
    596                 mListener = new PhoneStateListener() {
    597                     @Override
    598                     public void onVoiceActivationStateChanged(int state) {
    599                         synchronized(mLock) {
    600                             mVoiceActivationState = state;
    601                             mVoiceActivationStateChangedCalled = true;
    602                             mLock.notify();
    603                         }
    604                     }
    605                 };
    606                 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
    607                         (tm) -> tm.listen(mListener,
    608                                 PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE));
    609                 Looper.loop();
    610             }
    611         });
    612         assertThat(mVoiceActivationStateChangedCalled).isFalse();
    613         t.start();
    614 
    615         synchronized (mLock) {
    616             if (!mVoiceActivationStateChangedCalled){
    617                 mLock.wait(WAIT_TIME);
    618             }
    619         }
    620         t.checkException();
    621         Log.d(TAG, "onVoiceActivationStateChanged: " + mVoiceActivationState);
    622         int state = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
    623                 (tm) -> tm.getVoiceActivationState());
    624         assertEquals(state, mVoiceActivationState);
    625     }
    626 
    627     /*
    628     * The tests below rely on the framework to immediately call the installed listener upon
    629     * registration. There is no simple way to emulate state changes for testing the listeners.
    630     */
    631     @Test
    632     public void testOnPreciseDataConnectionStateChanged() throws Throwable {
    633         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    634             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    635             return;
    636         }
    637 
    638         TestThread t = new TestThread(new Runnable() {
    639             public void run() {
    640                 Looper.prepare();
    641 
    642                 mListener = new PhoneStateListener() {
    643                     @Override
    644                     public void onPreciseDataConnectionStateChanged(
    645                             PreciseDataConnectionState state) {
    646                         synchronized(mLock) {
    647                             mOnPreciseDataConnectionStateChanged = true;
    648                             mPreciseDataConnectionState = state;
    649                             mLock.notify();
    650                         }
    651                     }
    652                 };
    653                 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
    654                         (tm) -> tm.listen(mListener,
    655                                 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE));
    656                 Looper.loop();
    657             }
    658         });
    659 
    660         assertThat(mOnCallDisconnectCauseChangedCalled).isFalse();
    661         t.start();
    662 
    663         synchronized (mLock) {
    664             if (!mOnPreciseDataConnectionStateChanged){
    665                 mLock.wait(WAIT_TIME);
    666             }
    667         }
    668         t.checkException();
    669         assertThat(mOnPreciseDataConnectionStateChanged).isTrue();
    670         assertThat(mPreciseDataConnectionState.getDataConnectionState())
    671                 .isIn(DATA_CONNECTION_STATE);
    672         // basic test to verify there is no exception thrown.
    673         mPreciseDataConnectionState.getDataConnectionApnTypeBitMask();
    674         mPreciseDataConnectionState.getDataConnectionApn();
    675         mPreciseDataConnectionState.getDataConnectionFailCause();
    676     }
    677 
    678     @Test
    679     public void testOnCallForwardingIndicatorChanged() throws Throwable {
    680         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    681             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    682             return;
    683         }
    684 
    685         TestThread t = new TestThread(new Runnable() {
    686             @Override
    687             public void run() {
    688                 Looper.prepare();
    689 
    690                 mListener = new PhoneStateListener() {
    691                     @Override
    692                     public void onCallForwardingIndicatorChanged(boolean cfi) {
    693                         synchronized(mLock) {
    694                             mOnCallForwardingIndicatorChangedCalled = true;
    695                             mLock.notify();
    696                         }
    697                     }
    698                 };
    699                 mTelephonyManager.listen(
    700                         mListener, PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
    701 
    702                 Looper.loop();
    703             }
    704         });
    705 
    706         assertFalse(mOnCallForwardingIndicatorChangedCalled);
    707         t.start();
    708 
    709         synchronized (mLock) {
    710             if (!mOnCallForwardingIndicatorChangedCalled){
    711                 mLock.wait(WAIT_TIME);
    712             }
    713         }
    714         t.checkException();
    715         assertTrue(mOnCallForwardingIndicatorChangedCalled);
    716     }
    717 
    718     @Test
    719     public void testOnCellLocationChanged() throws Throwable {
    720         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    721             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    722             return;
    723         }
    724 
    725         TelephonyManagerTest.grantLocationPermissions();
    726 
    727         TestThread t = new TestThread(new Runnable() {
    728             public void run() {
    729                 Looper.prepare();
    730 
    731                 mListener = new PhoneStateListener() {
    732                     @Override
    733                     public void onCellLocationChanged(CellLocation location) {
    734                         synchronized(mLock) {
    735                             mOnCellLocationChangedCalled = true;
    736                             mLock.notify();
    737                         }
    738                     }
    739                 };
    740                 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
    741 
    742                 Looper.loop();
    743             }
    744         });
    745 
    746         assertFalse(mOnCellLocationChangedCalled);
    747         t.start();
    748 
    749         synchronized (mLock) {
    750             if (!mOnCellLocationChangedCalled){
    751                 mLock.wait(WAIT_TIME);
    752             }
    753         }
    754         t.checkException();
    755         assertTrue(mOnCellLocationChangedCalled);
    756     }
    757 
    758     @Test
    759     public void testOnCallStateChanged() throws Throwable {
    760         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    761             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    762             return;
    763         }
    764 
    765         TestThread t = new TestThread(new Runnable() {
    766             public void run() {
    767                 Looper.prepare();
    768 
    769                 mListener = new PhoneStateListener() {
    770                     @Override
    771                     public void onCallStateChanged(int state, String incomingNumber) {
    772                         synchronized(mLock) {
    773                             mOnCallStateChangedCalled = true;
    774                             mLock.notify();
    775                         }
    776                     }
    777                 };
    778                 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);
    779 
    780                 Looper.loop();
    781             }
    782         });
    783 
    784         assertFalse(mOnCallStateChangedCalled);
    785         t.start();
    786 
    787         synchronized (mLock) {
    788             if (!mOnCallStateChangedCalled){
    789                 mLock.wait(WAIT_TIME);
    790             }
    791         }
    792         t.checkException();
    793         assertTrue(mOnCallStateChangedCalled);
    794     }
    795 
    796     @Test
    797     public void testOnDataConnectionStateChanged() throws Throwable {
    798         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    799             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    800             return;
    801         }
    802 
    803         TestThread t = new TestThread(new Runnable() {
    804             public void run() {
    805                 Looper.prepare();
    806 
    807                 mListener = new PhoneStateListener() {
    808                     @Override
    809                     public void onDataConnectionStateChanged(int state) {
    810                         synchronized(mLock) {
    811                             mOnDataConnectionStateChangedCalled = true;
    812                             if (mOnDataConnectionStateChangedCalled
    813                                     && mOnDataConnectionStateChangedWithNetworkTypeCalled) {
    814                                 mLock.notify();
    815                             }
    816                         }
    817                     }
    818                     @Override
    819                     public void onDataConnectionStateChanged(int state, int networkType) {
    820                         synchronized(mLock) {
    821                             mOnDataConnectionStateChangedWithNetworkTypeCalled = true;
    822                             if (mOnDataConnectionStateChangedCalled
    823                                     && mOnDataConnectionStateChangedWithNetworkTypeCalled) {
    824                                 mLock.notify();
    825                             }
    826                         }
    827                     }
    828                 };
    829                 mTelephonyManager.listen(
    830                         mListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
    831 
    832                 Looper.loop();
    833             }
    834         });
    835 
    836         assertFalse(mOnDataConnectionStateChangedCalled);
    837         assertFalse(mOnDataConnectionStateChangedWithNetworkTypeCalled);
    838         t.start();
    839 
    840         synchronized (mLock) {
    841             if (!mOnDataConnectionStateChangedCalled ||
    842                     !mOnDataConnectionStateChangedWithNetworkTypeCalled){
    843                 mLock.wait(WAIT_TIME);
    844             }
    845         }
    846         t.checkException();
    847         assertTrue(mOnDataConnectionStateChangedCalled);
    848         assertTrue(mOnDataConnectionStateChangedWithNetworkTypeCalled);
    849     }
    850 
    851     @Test
    852     public void testOnDataActivity() throws Throwable {
    853         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    854             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    855             return;
    856         }
    857 
    858         TestThread t = new TestThread(new Runnable() {
    859             public void run() {
    860                 Looper.prepare();
    861 
    862                 mListener = new PhoneStateListener() {
    863                     @Override
    864                     public void onDataActivity(int direction) {
    865                         synchronized(mLock) {
    866                             mOnDataActivityCalled = true;
    867                             mLock.notify();
    868                         }
    869                     }
    870                 };
    871                 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_DATA_ACTIVITY);
    872 
    873                 Looper.loop();
    874             }
    875         });
    876 
    877         assertFalse(mOnDataActivityCalled);
    878         t.start();
    879 
    880         synchronized (mLock) {
    881             if (!mOnDataActivityCalled){
    882                 mLock.wait(WAIT_TIME);
    883             }
    884         }
    885         t.checkException();
    886         assertTrue(mOnDataActivityCalled);
    887     }
    888 
    889     @Test
    890     public void testOnCellInfoChanged() throws Throwable {
    891         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    892             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    893             return;
    894         }
    895 
    896         TelephonyManagerTest.grantLocationPermissions();
    897 
    898         TestThread t = new TestThread(new Runnable() {
    899             public void run() {
    900                 Looper.prepare();
    901 
    902                 mListener = new PhoneStateListener() {
    903                     @Override
    904                     public void onCellInfoChanged(List<CellInfo> cellInfo) {
    905                         synchronized(mLock) {
    906                             mOnCellInfoChangedCalled = true;
    907                             mLock.notify();
    908                         }
    909                     }
    910                 };
    911                 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_INFO);
    912 
    913                 Looper.loop();
    914             }
    915         });
    916 
    917         assertFalse(mOnDataActivityCalled);
    918         t.start();
    919 
    920         synchronized (mLock) {
    921             if (!mOnCellInfoChangedCalled){
    922                 mLock.wait(WAIT_TIME);
    923             }
    924         }
    925         t.checkException();
    926         assertTrue(mOnCellInfoChangedCalled);
    927     }
    928 
    929     @Test
    930     public void testOnUserMobileDataStateChanged() throws Throwable {
    931         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    932             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    933             return;
    934         }
    935 
    936         TestThread t = new TestThread(new Runnable() {
    937             public void run() {
    938                 Looper.prepare();
    939 
    940                 mListener = new PhoneStateListener() {
    941                     @Override
    942                     public void onUserMobileDataStateChanged(boolean state) {
    943                         synchronized(mLock) {
    944                             mOnUserMobileDataStateChanged = true;
    945                             mLock.notify();
    946                         }
    947                     }
    948                 };
    949                 mTelephonyManager.listen(
    950                         mListener, PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE);
    951 
    952                 Looper.loop();
    953             }
    954         });
    955 
    956         assertFalse(mOnUserMobileDataStateChanged);
    957         t.start();
    958 
    959         synchronized (mLock) {
    960             if (!mOnUserMobileDataStateChanged){
    961                 mLock.wait(WAIT_TIME);
    962             }
    963         }
    964         t.checkException();
    965         assertTrue(mOnUserMobileDataStateChanged);
    966     }
    967 
    968     @Test
    969     public void testOnActiveDataSubscriptionIdChanged() throws Throwable {
    970         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
    971             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
    972             return;
    973         }
    974 
    975         TestThread t = new TestThread(new Runnable() {
    976             public void run() {
    977                 Looper.prepare();
    978 
    979                 mListener = new PhoneStateListener() {
    980                     @Override
    981                     public void onActiveDataSubscriptionIdChanged(int subId) {
    982                         synchronized(mLock) {
    983                             mOnActiveDataSubscriptionIdChanged = true;
    984                             mLock.notify();
    985                         }
    986                     }
    987                 };
    988                 mTelephonyManager.listen(
    989                         mListener, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
    990 
    991                 Looper.loop();
    992             }
    993         });
    994 
    995         assertFalse(mOnActiveDataSubscriptionIdChanged);
    996         t.start();
    997 
    998         synchronized (mLock) {
    999             if (!mOnActiveDataSubscriptionIdChanged){
   1000                 mLock.wait(WAIT_TIME);
   1001             }
   1002         }
   1003         t.checkException();
   1004         assertTrue(mOnActiveDataSubscriptionIdChanged);
   1005     }
   1006 }
   1007