• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.settings.bluetooth;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 
20 import static org.mockito.Matchers.any;
21 import static org.mockito.Matchers.anyBoolean;
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.never;
24 import static org.mockito.Mockito.spy;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.when;
27 
28 import android.bluetooth.BluetoothAdapter;
29 import android.content.BroadcastReceiver;
30 import android.content.ComponentName;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.content.IntentFilter;
34 import android.os.UserManager;
35 import android.support.v7.preference.PreferenceViewHolder;
36 import android.view.View;
37 import android.widget.Switch;
38 
39 import com.android.settings.R;
40 import com.android.settings.testutils.SettingsRobolectricTestRunner;
41 import com.android.settings.testutils.shadow.SettingsShadowResources;
42 import com.android.settings.widget.SwitchBar;
43 import com.android.settings.widget.SwitchBarController;
44 import com.android.settings.widget.SwitchWidgetController;
45 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
46 import com.android.settingslib.RestrictedSwitchPreference;
47 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
48 import com.android.settingslib.bluetooth.LocalBluetoothManager;
49 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
50 
51 import org.junit.Before;
52 import org.junit.BeforeClass;
53 import org.junit.Test;
54 import org.junit.runner.RunWith;
55 import org.mockito.ArgumentCaptor;
56 import org.mockito.Mock;
57 import org.mockito.MockitoAnnotations;
58 import org.robolectric.RuntimeEnvironment;
59 import org.robolectric.annotation.Config;
60 
61 @RunWith(SettingsRobolectricTestRunner.class)
62 @Config(shadows = SettingsShadowResources.SettingsShadowTheme.class)
63 public class BluetoothEnablerTest {
64 
65     private static EnforcedAdmin sFakeEnforcedAdmin;
66     private PreferenceViewHolder mHolder;
67     private RestrictedSwitchPreference mRestrictedSwitchPreference;
68 
69     @BeforeClass
beforeClass()70     public static void beforeClass() {
71         sFakeEnforcedAdmin = new EnforcedAdmin(new ComponentName("test.package", "test.Class"), 10);
72     }
73 
74     @Mock
75     private MetricsFeatureProvider mMetricsFeatureProvider;
76     @Mock
77     private RestrictionUtils mRestrictionUtils;
78     @Mock
79     private LocalBluetoothManager mBluetoothManager;
80     @Mock
81     private LocalBluetoothAdapter mBluetoothAdapter;
82     @Mock
83     private SwitchWidgetController.OnSwitchChangeListener mCallback;
84 
85     private Context mContext;
86     private SwitchWidgetController mSwitchController;
87     private BluetoothEnabler mBluetoothEnabler;
88 
89     @Before
setUp()90     public void setUp() {
91         MockitoAnnotations.initMocks(this);
92         mContext = spy(RuntimeEnvironment.application);
93         when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mBluetoothAdapter);
94 
95         mRestrictedSwitchPreference = new RestrictedSwitchPreference(mContext);
96         mSwitchController = spy(new SwitchBarController(new SwitchBar(mContext)));
97         mBluetoothEnabler = new BluetoothEnabler(
98                 mContext,
99                 mSwitchController,
100                 mMetricsFeatureProvider,
101                 mBluetoothManager,
102                 123,
103                 mRestrictionUtils);
104         mHolder = PreferenceViewHolder.createInstanceForTests(mock(View.class));
105         mRestrictedSwitchPreference.onBindViewHolder(mHolder);
106         mBluetoothEnabler.setToggleCallback(mCallback);
107     }
108 
109     @Test
onSwitchToggled_shouldLogActionWithSuppliedEvent()110     public void onSwitchToggled_shouldLogActionWithSuppliedEvent() {
111         // WHEN the switch is toggled...
112         mBluetoothEnabler.onSwitchToggled(false);
113 
114         // THEN the corresponding metrics action is logged.
115         verify(mMetricsFeatureProvider).action(mContext, 123, false);
116     }
117 
118     @Test
onSwitchToggled_shouldTriggerCallback()119     public void onSwitchToggled_shouldTriggerCallback() {
120         // WHEN the switch is toggled...
121         mBluetoothEnabler.onSwitchToggled(false);
122 
123         // THEN the callback is triggered
124         verify(mCallback).onSwitchToggled(false);
125     }
126 
127     @Test
maybeEnforceRestrictions_noRestrictions()128     public void maybeEnforceRestrictions_noRestrictions() {
129         // GIVEN there are no restrictions set...
130         when(mRestrictionUtils.checkIfRestrictionEnforced(any(Context.class), any(String.class)))
131                 .thenReturn(null);
132 
133         // WHEN the maybeEnforceRestrictions is called...
134         // THEN false is returned to indicate there was no restriction to enforce
135         assertThat(mBluetoothEnabler.maybeEnforceRestrictions()).isFalse();
136 
137         // THEN a null EnfoceAdmin is set.
138         verify(mSwitchController).setDisabledByAdmin(null);
139         // THEN the state of the switch isn't changed.
140         verify(mSwitchController, never()).setChecked(anyBoolean());
141     }
142 
143     @Test
maybeEnforceRestrictions_disallowBluetoothRestrictionSet()144     public void maybeEnforceRestrictions_disallowBluetoothRestrictionSet() {
145         // GIVEN Bluetooth has been disallowed...
146         when(mRestrictionUtils.checkIfRestrictionEnforced(
147                 mContext, UserManager.DISALLOW_BLUETOOTH)).thenReturn(sFakeEnforcedAdmin);
148         when(mRestrictionUtils.checkIfRestrictionEnforced(
149                 mContext, UserManager.DISALLOW_CONFIG_BLUETOOTH)).thenReturn(null);
150 
151         // WHEN the maybeEnforceRestrictions is called...
152         // THEN true is returned to indicate there was a restriction to enforce.
153         assertThat(mBluetoothEnabler.maybeEnforceRestrictions()).isTrue();
154 
155         // THEN the expected EnfoceAdmin is set.
156         verify(mSwitchController).setDisabledByAdmin(sFakeEnforcedAdmin);
157 
158         // THEN the switch is unchecked.
159         verify(mSwitchController).setChecked(false);
160     }
161 
162     @Test
maybeEnforceRestrictions_disallowConfigBluetoothRestrictionSet()163     public void maybeEnforceRestrictions_disallowConfigBluetoothRestrictionSet() {
164         // GIVEN configuring Bluetooth has been disallowed...
165         when(mRestrictionUtils.checkIfRestrictionEnforced(
166                 mContext, UserManager.DISALLOW_BLUETOOTH)).thenReturn(null);
167         when(mRestrictionUtils.checkIfRestrictionEnforced(
168                 mContext, UserManager.DISALLOW_CONFIG_BLUETOOTH)).thenReturn(sFakeEnforcedAdmin);
169 
170         // WHEN the maybeEnforceRestrictions is called...
171         // THEN true is returned to indicate there was a restriction to enforce.
172         assertThat(mBluetoothEnabler.maybeEnforceRestrictions()).isTrue();
173 
174         // THEN the expected EnfoceAdmin is set.
175         verify(mSwitchController).setDisabledByAdmin(sFakeEnforcedAdmin);
176 
177         // THEN the switch is unchecked.
178         verify(mSwitchController).setChecked(false);
179     }
180 
181     @Test
maybeEnforceRestrictions_disallowBluetoothNotOverriden()182     public void maybeEnforceRestrictions_disallowBluetoothNotOverriden() {
183         // GIVEN Bluetooth has been disallowed...
184         when(mRestrictionUtils.checkIfRestrictionEnforced(
185                 mContext, UserManager.DISALLOW_BLUETOOTH)).thenReturn(sFakeEnforcedAdmin);
186         when(mRestrictionUtils.checkIfRestrictionEnforced(
187                 mContext, UserManager.DISALLOW_CONFIG_BLUETOOTH)).thenReturn(null);
188 
189         mBluetoothEnabler.resume(mContext);
190 
191         verify(mSwitchController, never()).setEnabled(true);
192     }
193 
194     @Test
startWithBluetoothOff_switchIsOff()195     public void startWithBluetoothOff_switchIsOff() {
196         when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_OFF);
197         verify(mSwitchController, never()).setChecked(anyBoolean());
198         mBluetoothEnabler.resume(mContext);
199         verify(mSwitchController, never()).setChecked(true);
200     }
201 
202     @Test
startWithBluetoothOn_switchIsOn()203     public void startWithBluetoothOn_switchIsOn() {
204         when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
205         verify(mSwitchController, never()).setChecked(anyBoolean());
206         mBluetoothEnabler.resume(mContext);
207         verify(mSwitchController, never()).setChecked(false);
208         verify(mSwitchController).setChecked(true);
209     }
210 
211     @Test
bluetoothTurnsOff_switchTurnsOff()212     public void bluetoothTurnsOff_switchTurnsOff() {
213         // Start up with bluetooth turned on. The switch should get turned on.
214         ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class);
215         when(mContext.registerReceiver(captor.capture(), any(IntentFilter.class))).thenReturn(null);
216         when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
217         verify(mSwitchController, never()).setChecked(anyBoolean());
218         mBluetoothEnabler.resume(mContext);
219         verify(mSwitchController, never()).setChecked(false);
220         verify(mSwitchController).setChecked(true);
221 
222         // Now simulate bluetooth being turned off via an event.
223         BroadcastReceiver receiver = captor.getValue();
224         Intent turningOff = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
225         turningOff.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_TURNING_OFF);
226         receiver.onReceive(mContext, turningOff);
227         Intent off = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
228         off.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF);
229         receiver.onReceive(mContext, off);
230 
231         // Make sure the switch was turned off.
232         verify(mSwitchController).setChecked(false);
233     }
234 
235     @Test
bluetoothTurnsOn_switchTurnsOn()236     public void bluetoothTurnsOn_switchTurnsOn() {
237         // Start up with bluetooth turned on. The switch should be left off.
238         ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class);
239         when(mContext.registerReceiver(captor.capture(), any(IntentFilter.class))).thenReturn(null);
240         when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_OFF);
241         verify(mSwitchController, never()).setChecked(anyBoolean());
242         mBluetoothEnabler.resume(mContext);
243         verify(mSwitchController, never()).setChecked(anyBoolean());
244 
245         // Now simulate bluetooth being turned on via an event.
246         BroadcastReceiver receiver = captor.getValue();
247         Intent turningOn = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
248         turningOn.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_TURNING_ON);
249         receiver.onReceive(mContext, turningOn);
250         Intent on = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
251         on.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON);
252         receiver.onReceive(mContext, on);
253 
254         // Make sure the switch was turned on.
255         verify(mSwitchController).setChecked(true);
256     }
257 }
258