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 org.mockito.Mockito.spy;
19 import static org.mockito.Mockito.when;
20 
21 import android.bluetooth.BluetoothAdapter;
22 import android.bluetooth.BluetoothClass;
23 import android.bluetooth.BluetoothDevice;
24 import android.bluetooth.BluetoothManager;
25 import android.content.Context;
26 
27 import androidx.fragment.app.FragmentActivity;
28 import androidx.lifecycle.LifecycleOwner;
29 import androidx.preference.PreferenceManager;
30 import androidx.preference.PreferenceScreen;
31 
32 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
33 import com.android.settingslib.core.lifecycle.Lifecycle;
34 
35 import org.junit.Before;
36 import org.junit.runner.RunWith;
37 import org.mockito.Mock;
38 import org.mockito.MockitoAnnotations;
39 import org.robolectric.RobolectricTestRunner;
40 import org.robolectric.RuntimeEnvironment;
41 import org.robolectric.annotation.Config;
42 
43 @RunWith(RobolectricTestRunner.class)
44 @Config(shadows = {
45         com.android.settings.testutils.shadow.ShadowFragment.class,
46         com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal.class,
47 })
48 public abstract class BluetoothDetailsControllerTestBase {
49 
50     protected Context mContext;
51     private LifecycleOwner mLifecycleOwner;
52     protected Lifecycle mLifecycle;
53     protected DeviceConfig mDeviceConfig;
54     protected BluetoothDevice mDevice;
55     protected BluetoothManager mBluetoothManager;
56     protected BluetoothAdapter mBluetoothAdapter;
57     protected PreferenceScreen mScreen;
58     protected PreferenceManager mPreferenceManager;
59 
60     @Mock
61     protected BluetoothDeviceDetailsFragment mFragment;
62     @Mock
63     protected CachedBluetoothDevice mCachedDevice;
64     @Mock
65     protected FragmentActivity mActivity;
66     @Mock
67     protected BluetoothClass mBluetoothDeviceClass;
68 
69     @Before
setUp()70     public void setUp() {
71         MockitoAnnotations.initMocks(this);
72         mContext = RuntimeEnvironment.application;
73         mPreferenceManager = new PreferenceManager(mContext);
74         mScreen = mPreferenceManager.createPreferenceScreen(mContext);
75         mDeviceConfig = makeDefaultDeviceConfig();
76         when(mFragment.getActivity()).thenReturn(mActivity);
77         when(mActivity.getApplicationContext()).thenReturn(mContext);
78         when(mFragment.getContext()).thenReturn(mContext);
79         when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
80         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
81         mLifecycleOwner = () -> mLifecycle;
82         mLifecycle = spy(new Lifecycle(mLifecycleOwner));
83         mBluetoothManager = mContext.getSystemService(BluetoothManager.class);
84         mBluetoothAdapter = mBluetoothManager.getAdapter();
85     }
86 
87     protected static class DeviceConfig {
88 
89         private String name;
90         private String address;
91         private int majorDeviceClass;
92         private boolean connected;
93         private String connectionSummary;
94 
setName(String newValue)95         DeviceConfig setName(String newValue) {
96             this.name = newValue;
97             return this;
98         }
99 
setAddress(String newValue)100         DeviceConfig setAddress(String newValue) {
101             this.address = newValue;
102             return this;
103         }
104 
setMajorDeviceClass(int newValue)105         DeviceConfig setMajorDeviceClass(int newValue) {
106             this.majorDeviceClass = newValue;
107             return this;
108         }
109 
setConnected(boolean newValue)110         DeviceConfig setConnected(boolean newValue) {
111             this.connected = newValue;
112             return this;
113         }
114 
setConnectionSummary(String connectionSummary)115         DeviceConfig setConnectionSummary(String connectionSummary) {
116             this.connectionSummary = connectionSummary;
117             return this;
118         }
119 
getName()120         String getName() {
121             return name;
122         }
123 
getAddress()124         String getAddress() {
125             return address;
126         }
127 
getMajorDeviceClass()128         int getMajorDeviceClass() {
129             return majorDeviceClass;
130         }
131 
isConnected()132         boolean isConnected() {
133             return connected;
134         }
135 
getConnectionSummary()136         String getConnectionSummary() {
137             return connectionSummary;
138         }
139     }
140 
makeDefaultDeviceConfig()141     DeviceConfig makeDefaultDeviceConfig() {
142         return new DeviceConfig()
143                 .setName("Mock Device")
144                 .setAddress("B4:B0:34:B5:3B:1B")
145                 .setMajorDeviceClass(BluetoothClass.Device.Major.AUDIO_VIDEO)
146                 .setConnected(true)
147                 .setConnectionSummary(
148                         mContext.getString(com.android.settingslib.R.string.bluetooth_connected));
149     }
150 
151     /**
152      * Sets up the device mock to return various state based on a test config.
153      */
setupDevice(DeviceConfig config)154     void setupDevice(DeviceConfig config) {
155         when(mCachedDevice.getName()).thenReturn(config.getName());
156         when(mBluetoothDeviceClass.getMajorDeviceClass()).thenReturn(config.getMajorDeviceClass());
157         when(mCachedDevice.isConnected()).thenReturn(config.isConnected());
158         when(mCachedDevice.getConnectionSummary()).thenReturn(config.getConnectionSummary());
159 
160         mDevice = mBluetoothAdapter.getRemoteDevice(config.getAddress());
161         when(mCachedDevice.getDevice()).thenReturn(mDevice);
162         when(mCachedDevice.getAddress()).thenReturn(config.getAddress());
163         when(mCachedDevice.getIdentityAddress()).thenReturn(config.getAddress());
164     }
165 
166     /**
167      * Convenience method to call displayPreference and onResume.
168      */
showScreen(BluetoothDetailsController controller)169     void showScreen(BluetoothDetailsController controller) {
170         controller.displayPreference(mScreen);
171         controller.onResume();
172     }
173 }
174 
175