• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
setUp()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
tearDown()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
testListenForPhoneState_NoneResultsNoListen()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
testListenForPhoneState_ServiceOnly()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
testListenForPhoneState_ServiceAndSignalStrength()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
testListenForPhoneState_ServiceAndSignalStrengthUpdateTurnOffSignalStrengh()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
testListenForPhoneState_ServiceAndSignalStrengthUpdateTurnOffAll()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
testListenForPhoneState_MultiDevice_AllUpAllDown()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
testListenForPhoneState_MultiDevice_PartialUpPartialDown()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