Home | History | Annotate | Download | only in hfp
      1 /*
      2  * Copyright 2018 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 com.android.bluetooth.hfp;
     17 
     18 import static org.mockito.ArgumentMatchers.any;
     19 import static org.mockito.Mockito.*;
     20 
     21 import android.bluetooth.BluetoothAdapter;
     22 import android.bluetooth.BluetoothDevice;
     23 import android.content.Context;
     24 import android.os.HandlerThread;
     25 import android.os.IBinder;
     26 import android.os.ServiceManager;
     27 import android.support.test.filters.MediumTest;
     28 import android.support.test.runner.AndroidJUnit4;
     29 import android.telephony.PhoneStateListener;
     30 import android.telephony.SubscriptionManager;
     31 import android.telephony.TelephonyManager;
     32 
     33 import com.android.bluetooth.TestUtils;
     34 import com.android.internal.telephony.ISub;
     35 
     36 import org.junit.After;
     37 import org.junit.Before;
     38 import org.junit.Test;
     39 import org.junit.runner.RunWith;
     40 import org.mockito.Mock;
     41 import org.mockito.MockitoAnnotations;
     42 
     43 import java.util.HashMap;
     44 
     45 /**
     46  * Unit test to verify various methods in {@link HeadsetPhoneState}
     47  */
     48 @MediumTest
     49 @RunWith(AndroidJUnit4.class)
     50 public class HeadsetPhoneStateTest {
     51     @Mock private ISub mISub;
     52     @Mock private IBinder mISubBinder;
     53     @Mock private HeadsetService mHeadsetService;
     54     @Mock private TelephonyManager mTelephonyManager;
     55     @Mock private SubscriptionManager mSubscriptionManager;
     56     private HeadsetPhoneState mHeadsetPhoneState;
     57     private BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
     58     private HandlerThread mHandlerThread;
     59     private HashMap<String, IBinder> mServiceManagerMockedServices = new HashMap<>();
     60     private Object mServiceManagerOriginalServices;
     61 
     62     @Before
     63     public void setUp() throws Exception {
     64         MockitoAnnotations.initMocks(this);
     65         // Mock SubscriptionManager.getDefaultSubscriptionId() to return a valid value
     66         when(mISub.getDefaultSubId()).thenReturn(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
     67         when(mISubBinder.queryLocalInterface(anyString())).thenReturn(mISub);
     68         mServiceManagerMockedServices.put("isub", mISubBinder);
     69         mServiceManagerOriginalServices =
     70                 TestUtils.replaceField(ServiceManager.class, "sCache", null,
     71                         mServiceManagerMockedServices);
     72         // Stub other methods
     73         when(mHeadsetService.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(
     74                 mTelephonyManager);
     75         when(mHeadsetService.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)).thenReturn(
     76                 mSubscriptionManager);
     77         mHandlerThread = new HandlerThread("HeadsetStateMachineTestHandlerThread");
     78         mHandlerThread.start();
     79         when(mHeadsetService.getStateMachinesThreadLooper()).thenReturn(mHandlerThread.getLooper());
     80         mHeadsetPhoneState = new HeadsetPhoneState(mHeadsetService);
     81     }
     82 
     83     @After
     84     public void tearDown() throws Exception {
     85         mHeadsetPhoneState.cleanup();
     86         mHandlerThread.quit();
     87         if (mServiceManagerOriginalServices != null) {
     88             TestUtils.replaceField(ServiceManager.class, "sCache", null,
     89                     mServiceManagerOriginalServices);
     90             mServiceManagerOriginalServices = null;
     91         }
     92 
     93     }
     94 
     95     /**
     96      * Verify that {@link PhoneStateListener#LISTEN_NONE} should result in no subscription
     97      */
     98     @Test
     99     public void testListenForPhoneState_NoneResultsNoListen() {
    100         BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1);
    101         mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_NONE);
    102         verifyZeroInteractions(mTelephonyManager);
    103     }
    104 
    105     /**
    106      * Verify that {@link PhoneStateListener#LISTEN_SERVICE_STATE} should result in corresponding
    107      * subscription
    108      */
    109     @Test
    110     public void testListenForPhoneState_ServiceOnly() {
    111         BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1);
    112         mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE);
    113         verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE));
    114         verifyNoMoreInteractions(mTelephonyManager);
    115     }
    116 
    117     /**
    118      * Verify that {@link PhoneStateListener#LISTEN_SERVICE_STATE} and
    119      * {@link PhoneStateListener#LISTEN_SIGNAL_STRENGTHS} should result in corresponding
    120      * subscription
    121      */
    122     @Test
    123     public void testListenForPhoneState_ServiceAndSignalStrength() {
    124         BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1);
    125         mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE
    126                 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
    127         verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE
    128                 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS));
    129         verify(mTelephonyManager).setRadioIndicationUpdateMode(
    130                 TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH,
    131                 TelephonyManager.INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF);
    132         verifyNoMoreInteractions(mTelephonyManager);
    133     }
    134 
    135     /**
    136      * Verify that partially turnning off {@link PhoneStateListener#LISTEN_SIGNAL_STRENGTHS} update
    137      * should only unsubscribe signal strength update
    138      */
    139     @Test
    140     public void testListenForPhoneState_ServiceAndSignalStrengthUpdateTurnOffSignalStrengh() {
    141         BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1);
    142         mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE
    143                 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
    144         verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE
    145                 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS));
    146         verify(mTelephonyManager).setRadioIndicationUpdateMode(
    147                 TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH,
    148                 TelephonyManager.INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF);
    149         mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE);
    150         verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
    151         verify(mTelephonyManager).setRadioIndicationUpdateMode(
    152                 TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH,
    153                 TelephonyManager.INDICATION_UPDATE_MODE_NORMAL);
    154         verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE));
    155         verifyNoMoreInteractions(mTelephonyManager);
    156     }
    157 
    158     /**
    159      * Verify that completely disabling all updates should unsubscribe from everything
    160      */
    161     @Test
    162     public void testListenForPhoneState_ServiceAndSignalStrengthUpdateTurnOffAll() {
    163         BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1);
    164         mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE
    165                 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
    166         verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE
    167                 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS));
    168         verify(mTelephonyManager).setRadioIndicationUpdateMode(
    169                 TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH,
    170                 TelephonyManager.INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF);
    171         mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_NONE);
    172         verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
    173         verify(mTelephonyManager).setRadioIndicationUpdateMode(
    174                 TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH,
    175                 TelephonyManager.INDICATION_UPDATE_MODE_NORMAL);
    176         verifyNoMoreInteractions(mTelephonyManager);
    177     }
    178 
    179     /**
    180      * Verify that when multiple devices tries to subscribe to the same indicator, the same
    181      * subscription is not triggered twice. Also, when one of the device is unsubsidised from an
    182      * indicator, the other device still remain subscribed.
    183      */
    184     @Test
    185     public void testListenForPhoneState_MultiDevice_AllUpAllDown() {
    186         BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1);
    187         BluetoothDevice device2 = TestUtils.getTestDevice(mAdapter, 2);
    188         // Enabling updates from first device should trigger subscription
    189         mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE
    190                 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
    191         verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE
    192                 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS));
    193         verify(mTelephonyManager).setRadioIndicationUpdateMode(
    194                 TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH,
    195                 TelephonyManager.INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF);
    196         verifyNoMoreInteractions(mTelephonyManager);
    197         // Enabling updates from second device should not trigger the same subscription
    198         mHeadsetPhoneState.listenForPhoneState(device2, PhoneStateListener.LISTEN_SERVICE_STATE
    199                 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
    200         verifyNoMoreInteractions(mTelephonyManager);
    201         // Disabling updates from first device should not cancel subscription
    202         mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_NONE);
    203         verifyNoMoreInteractions(mTelephonyManager);
    204         // Disabling updates from second device should cancel subscription
    205         mHeadsetPhoneState.listenForPhoneState(device2, PhoneStateListener.LISTEN_NONE);
    206         verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
    207         verify(mTelephonyManager).setRadioIndicationUpdateMode(
    208                 TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH,
    209                 TelephonyManager.INDICATION_UPDATE_MODE_NORMAL);
    210         verifyNoMoreInteractions(mTelephonyManager);
    211     }
    212 
    213     /**
    214      * Verity that two device each partially subscribe to an indicator result in subscription to
    215      * both indicators. Also unsubscribing from one indicator from one device will not cause
    216      * unrelated indicator from other device from being unsubscribed.
    217      */
    218     @Test
    219     public void testListenForPhoneState_MultiDevice_PartialUpPartialDown() {
    220         BluetoothDevice device1 = TestUtils.getTestDevice(mAdapter, 1);
    221         BluetoothDevice device2 = TestUtils.getTestDevice(mAdapter, 2);
    222         // Partially enabling updates from first device should trigger partial subscription
    223         mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_SERVICE_STATE);
    224         verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE));
    225         verifyNoMoreInteractions(mTelephonyManager);
    226         // Partially enabling updates from second device should trigger partial subscription
    227         mHeadsetPhoneState.listenForPhoneState(device2, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
    228         verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
    229         verify(mTelephonyManager).setRadioIndicationUpdateMode(
    230                 TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH,
    231                 TelephonyManager.INDICATION_UPDATE_MODE_NORMAL);
    232         verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SERVICE_STATE
    233                 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS));
    234         verify(mTelephonyManager).setRadioIndicationUpdateMode(
    235                 TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH,
    236                 TelephonyManager.INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF);
    237         verifyNoMoreInteractions(mTelephonyManager);
    238         // Partially disabling updates from first device should not cancel all subscription
    239         mHeadsetPhoneState.listenForPhoneState(device1, PhoneStateListener.LISTEN_NONE);
    240         verify(mTelephonyManager, times(2)).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
    241         verify(mTelephonyManager, times(2)).setRadioIndicationUpdateMode(
    242                 TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH,
    243                 TelephonyManager.INDICATION_UPDATE_MODE_NORMAL);
    244         verify(mTelephonyManager).listen(any(), eq(PhoneStateListener.LISTEN_SIGNAL_STRENGTHS));
    245         verify(mTelephonyManager, times(2)).setRadioIndicationUpdateMode(
    246                 TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH,
    247                 TelephonyManager.INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF);
    248         verifyNoMoreInteractions(mTelephonyManager);
    249         // Partially disabling updates from second device should cancel subscription
    250         mHeadsetPhoneState.listenForPhoneState(device2, PhoneStateListener.LISTEN_NONE);
    251         verify(mTelephonyManager, times(3)).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
    252         verify(mTelephonyManager, times(3)).setRadioIndicationUpdateMode(
    253                 TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH,
    254                 TelephonyManager.INDICATION_UPDATE_MODE_NORMAL);
    255         verifyNoMoreInteractions(mTelephonyManager);
    256     }
    257 }
    258