• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.development;
18 
19 import static com.android.settings.development.BluetoothLeAudioUiPreferenceController.VALUE_KEY;
20 import static com.android.settings.development.BluetoothLeAudioUiPreferenceController.VALUE_OFF;
21 import static com.android.settings.development.BluetoothLeAudioUiPreferenceController.VALUE_ON;
22 import static com.android.settings.development.BluetoothLeAudioUiPreferenceController.VALUE_UNSET;
23 
24 import static com.google.common.truth.Truth.assertThat;
25 
26 import static org.mockito.Mockito.spy;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 import static org.robolectric.Shadows.shadowOf;
30 
31 import android.bluetooth.BluetoothAdapter;
32 import android.bluetooth.BluetoothStatusCodes;
33 import android.content.Context;
34 import android.os.Looper;
35 import android.os.SystemProperties;
36 import android.platform.test.annotations.DisableFlags;
37 import android.platform.test.annotations.EnableFlags;
38 import android.platform.test.flag.junit.SetFlagsRule;
39 import android.provider.Settings;
40 
41 import androidx.preference.PreferenceScreen;
42 import androidx.preference.SwitchPreferenceCompat;
43 
44 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
45 import com.android.settingslib.flags.Flags;
46 
47 import org.junit.Before;
48 import org.junit.Rule;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 import org.mockito.Mock;
52 import org.mockito.junit.MockitoJUnit;
53 import org.mockito.junit.MockitoRule;
54 import org.robolectric.RobolectricTestRunner;
55 import org.robolectric.RuntimeEnvironment;
56 import org.robolectric.annotation.Config;
57 import org.robolectric.annotation.Implementation;
58 import org.robolectric.annotation.Implements;
59 import org.robolectric.shadow.api.Shadow;
60 
61 @RunWith(RobolectricTestRunner.class)
62 @Config(
63         shadows = {
64             ShadowBluetoothAdapter.class,
65             BluetoothLeAudioUiPreferenceControllerTest.ShadowBluetoothRebootDialogFragment.class
66         })
67 public class BluetoothLeAudioUiPreferenceControllerTest {
68     @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
69     @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
70     private static final String SOURCE_SYSTEM_PROP_KEY =
71             "bluetooth.profile.bap.broadcast.source.enabled";
72     private static final String ASSIST_SYSTEM_PROP_KEY =
73             "bluetooth.profile.bap.broadcast.assist.enabled";
74     @Mock private PreferenceScreen mPreferenceScreen;
75     @Mock private DevelopmentSettingsDashboardFragment mFragment;
76     @Mock private SwitchPreferenceCompat mPreference;
77     private ShadowBluetoothAdapter mShadowBluetoothAdapter;
78     private Context mContext;
79     private BluetoothLeAudioUiPreferenceController mController;
80 
81     @Before
setup()82     public void setup() {
83         mContext = RuntimeEnvironment.getApplication();
84         SystemProperties.set(SOURCE_SYSTEM_PROP_KEY, "true");
85         SystemProperties.set(ASSIST_SYSTEM_PROP_KEY, "true");
86         // Reset value
87         Settings.Global.putInt(mContext.getContentResolver(), VALUE_KEY, VALUE_UNSET);
88         mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
89         mShadowBluetoothAdapter.setEnabled(true);
90         mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
91                 BluetoothStatusCodes.FEATURE_SUPPORTED);
92         mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
93                 BluetoothStatusCodes.FEATURE_SUPPORTED);
94         mController = spy(new BluetoothLeAudioUiPreferenceController(mContext, mFragment));
95         when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
96                 .thenReturn(mPreference);
97         mController.displayPreference(mPreferenceScreen);
98     }
99 
100     @Test
101     @DisableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION)
isAvailable_flagOff_returnFalse()102     public void isAvailable_flagOff_returnFalse() {
103         assertThat(mController.isAvailable()).isFalse();
104     }
105 
106     @Test
107     @EnableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION)
isAvailable_flagOn_returnFalse()108     public void isAvailable_flagOn_returnFalse() {
109         assertThat(mController.isAvailable()).isTrue();
110     }
111 
112     @Test
113     @EnableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION)
isAvailable_flagOn_propertyOff_returnFalse()114     public void isAvailable_flagOn_propertyOff_returnFalse() {
115         SystemProperties.set(SOURCE_SYSTEM_PROP_KEY, "false");
116         assertThat(mController.isAvailable()).isFalse();
117     }
118 
119     @Test
120     @EnableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION)
updateState_settingEnabled_checked()121     public void updateState_settingEnabled_checked() {
122         Settings.Global.putInt(mContext.getContentResolver(), VALUE_KEY, VALUE_ON);
123         mController.updateState(mPreference);
124         shadowOf(Looper.getMainLooper()).idle();
125 
126         verify(mPreference).setChecked(true);
127     }
128 
129     @Test
130     @EnableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION)
updateState_settingDisabled_notChecked()131     public void updateState_settingDisabled_notChecked() {
132         Settings.Global.putInt(mContext.getContentResolver(), VALUE_KEY, VALUE_OFF);
133         mController.updateState(mPreference);
134         shadowOf(Looper.getMainLooper()).idle();
135 
136         verify(mPreference).setChecked(false);
137     }
138 
139     @Test
140     @EnableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION)
updateState_featureSupported_enabled()141     public void updateState_featureSupported_enabled() {
142         mController.updateState(mPreference);
143         shadowOf(Looper.getMainLooper()).idle();
144 
145         verify(mPreference).setEnabled(true);
146     }
147 
148     @Test
149     @EnableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION)
updateState_featureUnsupported_disabled()150     public void updateState_featureUnsupported_disabled() {
151         mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
152                 BluetoothStatusCodes.FEATURE_NOT_SUPPORTED);
153         mController.updateState(mPreference);
154         shadowOf(Looper.getMainLooper()).idle();
155 
156         verify(mPreference).setEnabled(false);
157     }
158 
159     @Test
160     @EnableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION)
onRebootDialogConfirmed_noChange_doNothing()161     public void onRebootDialogConfirmed_noChange_doNothing() {
162         mController.onRebootDialogConfirmed();
163 
164         int result = Settings.Global.getInt(mContext.getContentResolver(), VALUE_KEY, VALUE_UNSET);
165         assertThat(result).isEqualTo(VALUE_UNSET);
166     }
167 
168     @Test
169     @EnableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION)
onRebootDialogConfirmed_hasChange_turnOn()170     public void onRebootDialogConfirmed_hasChange_turnOn() {
171         mController.onPreferenceChange(mPreference, true);
172         mController.onRebootDialogConfirmed();
173 
174         int result = Settings.Global.getInt(mContext.getContentResolver(), VALUE_KEY, VALUE_UNSET);
175         assertThat(result).isEqualTo(VALUE_ON);
176     }
177 
178     @Test
179     @EnableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION)
onRebootDialogCanceled_hasChange_doNothing()180     public void onRebootDialogCanceled_hasChange_doNothing() {
181         mController.onPreferenceChange(mPreference, true);
182         mController.onRebootDialogCanceled();
183 
184         int result = Settings.Global.getInt(mContext.getContentResolver(), VALUE_KEY, VALUE_UNSET);
185         assertThat(result).isEqualTo(VALUE_UNSET);
186     }
187 
188     @Test
189     @EnableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION)
onBroadcastDisabled_currentValueOn_turnOff()190     public void onBroadcastDisabled_currentValueOn_turnOff() {
191         Settings.Global.putInt(mContext.getContentResolver(), VALUE_KEY, VALUE_ON);
192         mController.updateState(mPreference);
193         shadowOf(Looper.getMainLooper()).idle();
194         mController.onBroadcastDisabled();
195 
196         int result = Settings.Global.getInt(mContext.getContentResolver(), VALUE_KEY, VALUE_UNSET);
197         assertThat(result).isEqualTo(VALUE_OFF);
198     }
199 
200     @Test
201     @EnableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION)
onBroadcastDisabled_currentValueUnset_doNothing()202     public void onBroadcastDisabled_currentValueUnset_doNothing() {
203         mController.updateState(mPreference);
204         mController.onBroadcastDisabled();
205         shadowOf(Looper.getMainLooper()).idle();
206 
207         int result = Settings.Global.getInt(mContext.getContentResolver(), VALUE_KEY, VALUE_UNSET);
208         assertThat(result).isEqualTo(VALUE_UNSET);
209     }
210 
211     @Implements(BluetoothRebootDialog.class)
212     public static class ShadowBluetoothRebootDialogFragment {
213 
214         /** Shadow implementation of BluetoothRebootDialog#show */
215         @Implementation
show(DevelopmentSettingsDashboardFragment host)216         public static void show(DevelopmentSettingsDashboardFragment host) {
217             // Do nothing.
218         }
219     }
220 }
221