Home | History | Annotate | Download | only in bluetooth
      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 
     17 package com.android.settings.bluetooth;
     18 
     19 import static com.google.common.truth.Truth.assertThat;
     20 import static org.mockito.Matchers.any;
     21 import static org.mockito.Matchers.anyBoolean;
     22 import static org.mockito.Matchers.anyInt;
     23 import static org.mockito.Mockito.doNothing;
     24 import static org.mockito.Mockito.doReturn;
     25 import static org.mockito.Mockito.never;
     26 import static org.mockito.Mockito.spy;
     27 import static org.mockito.Mockito.times;
     28 import static org.mockito.Mockito.verify;
     29 
     30 import android.bluetooth.BluetoothAdapter;
     31 import android.content.Context;
     32 import android.content.res.Resources;
     33 import android.support.v7.preference.PreferenceGroup;
     34 
     35 import com.android.settings.R;
     36 import com.android.settings.testutils.SettingsRobolectricTestRunner;
     37 import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
     38 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
     39 import com.android.settingslib.bluetooth.LocalBluetoothManager;
     40 import com.android.settingslib.widget.FooterPreference;
     41 
     42 import org.junit.Before;
     43 import org.junit.Test;
     44 import org.junit.runner.RunWith;
     45 import org.mockito.Answers;
     46 import org.mockito.Mock;
     47 import org.mockito.MockitoAnnotations;
     48 import org.robolectric.RuntimeEnvironment;
     49 
     50 @RunWith(SettingsRobolectricTestRunner.class)
     51 public class BluetoothPairingDetailTest {
     52 
     53     @Mock
     54     private Resources mResource;
     55     @Mock
     56     private LocalBluetoothAdapter mLocalAdapter;
     57     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     58     private LocalBluetoothManager mLocalManager;
     59     @Mock
     60     private PreferenceGroup mPreferenceGroup;
     61     private BluetoothPairingDetail mFragment;
     62     private Context mContext;
     63     private BluetoothProgressCategory mAvailableDevicesCategory;
     64     private FooterPreference mFooterPreference;
     65 
     66     @Before
     67     public void setUp() {
     68         MockitoAnnotations.initMocks(this);
     69 
     70         mContext = RuntimeEnvironment.application;
     71         mFragment = spy(new BluetoothPairingDetail());
     72         doReturn(mContext).when(mFragment).getContext();
     73         doReturn(mResource).when(mFragment).getResources();
     74 
     75         mAvailableDevicesCategory = spy(new BluetoothProgressCategory(mContext));
     76         mFooterPreference = new FooterPreference(mContext);
     77 
     78         mFragment.mLocalAdapter = mLocalAdapter;
     79         mFragment.mLocalManager = mLocalManager;
     80         mFragment.mDeviceListGroup = mPreferenceGroup;
     81         mFragment.mAlwaysDiscoverable = new AlwaysDiscoverable(mContext, mLocalAdapter);
     82     }
     83 
     84     @Test
     85     public void testInitPreferencesFromPreferenceScreen_findPreferences() {
     86         doReturn(mAvailableDevicesCategory).when(mFragment)
     87             .findPreference(BluetoothPairingDetail.KEY_AVAIL_DEVICES);
     88         doReturn(mFooterPreference).when(mFragment)
     89             .findPreference(BluetoothPairingDetail.KEY_FOOTER_PREF);
     90 
     91         mFragment.initPreferencesFromPreferenceScreen();
     92 
     93         assertThat(mFragment.mAvailableDevicesCategory).isEqualTo(mAvailableDevicesCategory);
     94         assertThat(mFragment.mFooterPreference).isEqualTo(mFooterPreference);
     95     }
     96 
     97     @Test
     98     public void testStartScanning_startScanAndRemoveDevices() {
     99         mFragment.mAvailableDevicesCategory = mAvailableDevicesCategory;
    100         mFragment.mDeviceListGroup = mAvailableDevicesCategory;
    101 
    102         mFragment.enableScanning();
    103 
    104         verify(mLocalAdapter).startScanning(true);
    105         verify(mAvailableDevicesCategory).removeAll();
    106     }
    107 
    108     @Test
    109     public void testUpdateContent_stateOn_addDevices() {
    110         mFragment.mAvailableDevicesCategory = mAvailableDevicesCategory;
    111         mFragment.mFooterPreference = mFooterPreference;
    112         doNothing().when(mFragment).addDeviceCategory(any(), anyInt(), any(), anyBoolean());
    113 
    114         mFragment.updateContent(BluetoothAdapter.STATE_ON);
    115 
    116         verify(mFragment).addDeviceCategory(mAvailableDevicesCategory,
    117                 R.string.bluetooth_preference_found_media_devices,
    118                 BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER, false);
    119         verify(mLocalAdapter).setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
    120     }
    121 
    122     @Test
    123     public void testUpdateContent_stateOff_finish() {
    124         mFragment.updateContent(BluetoothAdapter.STATE_OFF);
    125 
    126         verify(mFragment).finish();
    127     }
    128 
    129     @Test
    130     public void testUpdateBluetooth_bluetoothOff_turnOnBluetooth() {
    131         doReturn(false).when(mLocalAdapter).isEnabled();
    132 
    133         mFragment.updateBluetooth();
    134 
    135         verify(mLocalAdapter).enable();
    136     }
    137 
    138     @Test
    139     public void testUpdateBluetooth_bluetoothOn_updateState() {
    140         doReturn(true).when(mLocalAdapter).isEnabled();
    141         doNothing().when(mFragment).updateContent(anyInt());
    142 
    143         mFragment.updateBluetooth();
    144 
    145         verify(mFragment).updateContent(anyInt());
    146     }
    147 
    148     @Test
    149     public void testOnScanningStateChanged_restartScanAfterInitialScanning() {
    150         mFragment.mAvailableDevicesCategory = mAvailableDevicesCategory;
    151         mFragment.mFooterPreference = mFooterPreference;
    152         mFragment.mDeviceListGroup = mAvailableDevicesCategory;
    153         doNothing().when(mFragment).addDeviceCategory(any(), anyInt(), any(), anyBoolean());
    154 
    155         // Initial Bluetooth ON will trigger scan enable, list clear and scan start
    156         mFragment.updateContent(BluetoothAdapter.STATE_ON);
    157         verify(mFragment).enableScanning();
    158         assertThat(mAvailableDevicesCategory.getPreferenceCount()).isEqualTo(0);
    159         verify(mLocalAdapter).startScanning(true);
    160 
    161         // Subsequent scan started event will not trigger start/stop nor list clear
    162         mFragment.onScanningStateChanged(true);
    163         verify(mLocalAdapter, times(1)).startScanning(anyBoolean());
    164         verify(mAvailableDevicesCategory, times(1)).setProgress(true);
    165 
    166         // Subsequent scan finished event will trigger scan start without list clean
    167         mFragment.onScanningStateChanged(false);
    168         verify(mLocalAdapter, times(2)).startScanning(true);
    169         verify(mAvailableDevicesCategory, times(2)).setProgress(true);
    170 
    171         // Subsequent scan started event will not trigger any change
    172         mFragment.onScanningStateChanged(true);
    173         verify(mLocalAdapter, times(2)).startScanning(anyBoolean());
    174         verify(mAvailableDevicesCategory, times(3)).setProgress(true);
    175         verify(mLocalAdapter, never()).stopScanning();
    176 
    177         // Disable scanning will trigger scan stop
    178         mFragment.disableScanning();
    179         verify(mLocalAdapter, times(1)).stopScanning();
    180 
    181         // Subsequent scan start event will not trigger any change besides progress circle
    182         mFragment.onScanningStateChanged(true);
    183         verify(mAvailableDevicesCategory, times(4)).setProgress(true);
    184 
    185         // However, subsequent scan finished event won't trigger new scan start and will stop
    186         // progress circle from spinning
    187         mFragment.onScanningStateChanged(false);
    188         verify(mAvailableDevicesCategory, times(1)).setProgress(false);
    189         verify(mLocalAdapter, times(2)).startScanning(anyBoolean());
    190         verify(mLocalAdapter, times(1)).stopScanning();
    191 
    192         // Verify that clean up only happen once at initialization
    193         verify(mAvailableDevicesCategory, times(1)).removeAll();
    194     }
    195 }
    196