From b00cef308e3d2860b86eb87de4323f5ade840087 Mon Sep 17 00:00:00 2001 From: Beverly Date: Mon, 2 Jul 2018 16:46:11 -0400 Subject: [PATCH 1/6] Use Settings.Secure values, not Global values The following Settings are being moved to Settings.Secure from Settings.Global since they are settings that exist per user - CHARGING_SOUNDS_ENABLED - CHARGING_VIBRATION_ENABLED - ZEN_DURATION - SHOW_ZEN_UPGRADE_NOTIFICATION - SHOW_ZEN_SETTINGS_SUGGESTION - ZEN_SETTINGS_UPDATE - ZEN_SETTINGS_SUGGESTION_VIEWED Bug: 110926544 Test: make ROBOTEST_FILTER=ZenModeDurationPreferenceControllerTest RunSettingsRoboTests Change-Id: I3e3d6f6653b81a121fbda7d2f9f1b75651f536b7 --- .../AbstractZenModePreferenceController.java | 6 +++--- .../ChargingSoundPreferenceController.java | 6 +++--- .../settings/notification/SettingPref.java | 8 ++++++++ .../settings/notification/ZenModeBackend.java | 4 ++-- .../ZenModeButtonPreferenceController.java | 4 ++-- .../notification/ZenOnboardingActivity.java | 20 +++++++++---------- ...ChargingSoundPreferenceControllerTest.java | 11 +++++----- ...nModeDurationPreferenceControllerTest.java | 10 +++++----- .../ZenOnboardingActivityTest.java | 12 +++++------ 9 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/com/android/settings/notification/AbstractZenModePreferenceController.java b/src/com/android/settings/notification/AbstractZenModePreferenceController.java index 5d92279ca5a..791e28c3cf1 100644 --- a/src/com/android/settings/notification/AbstractZenModePreferenceController.java +++ b/src/com/android/settings/notification/AbstractZenModePreferenceController.java @@ -117,7 +117,7 @@ abstract public class AbstractZenModePreferenceController extends } protected int getZenDuration() { - return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.ZEN_DURATION, + return Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ZEN_DURATION, 0); } @@ -125,8 +125,8 @@ abstract public class AbstractZenModePreferenceController extends private final Uri ZEN_MODE_URI = Settings.Global.getUriFor(Settings.Global.ZEN_MODE); private final Uri ZEN_MODE_CONFIG_ETAG_URI = Settings.Global.getUriFor( Settings.Global.ZEN_MODE_CONFIG_ETAG); - private final Uri ZEN_MODE_DURATION_URI = Settings.Global.getUriFor( - Settings.Global.ZEN_DURATION); + private final Uri ZEN_MODE_DURATION_URI = Settings.Secure.getUriFor( + Settings.Secure.ZEN_DURATION); private final Preference mPreference; diff --git a/src/com/android/settings/notification/ChargingSoundPreferenceController.java b/src/com/android/settings/notification/ChargingSoundPreferenceController.java index fccde6a56e3..c7cd232a031 100644 --- a/src/com/android/settings/notification/ChargingSoundPreferenceController.java +++ b/src/com/android/settings/notification/ChargingSoundPreferenceController.java @@ -16,10 +16,10 @@ package com.android.settings.notification; -import static com.android.settings.notification.SettingPref.TYPE_GLOBAL; +import static com.android.settings.notification.SettingPref.TYPE_SECURE; import android.content.Context; -import android.provider.Settings.Global; +import android.provider.Settings.Secure; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; @@ -33,7 +33,7 @@ public class ChargingSoundPreferenceController extends SettingPrefController { Lifecycle lifecycle) { super(context, parent, lifecycle); mPreference = new SettingPref( - TYPE_GLOBAL, KEY_CHARGING_SOUNDS, Global.CHARGING_SOUNDS_ENABLED, DEFAULT_ON); + TYPE_SECURE, KEY_CHARGING_SOUNDS, Secure.CHARGING_SOUNDS_ENABLED, DEFAULT_ON); } @Override diff --git a/src/com/android/settings/notification/SettingPref.java b/src/com/android/settings/notification/SettingPref.java index a651e6ac655..f7152fa19a3 100644 --- a/src/com/android/settings/notification/SettingPref.java +++ b/src/com/android/settings/notification/SettingPref.java @@ -21,6 +21,7 @@ import android.content.Context; import android.content.res.Resources; import android.net.Uri; import android.provider.Settings.Global; +import android.provider.Settings.Secure; import android.provider.Settings.System; import com.android.settings.SettingsPreferenceFragment; @@ -34,6 +35,7 @@ import androidx.preference.TwoStatePreference; public class SettingPref { public static final int TYPE_GLOBAL = 1; public static final int TYPE_SYSTEM = 2; + public static final int TYPE_SECURE = 3; protected final int mType; private final String mKey; @@ -132,6 +134,8 @@ public class SettingPref { return Global.getUriFor(setting); case TYPE_SYSTEM: return System.getUriFor(setting); + case TYPE_SECURE: + return Secure.getUriFor(setting); } throw new IllegalArgumentException(); } @@ -142,6 +146,8 @@ public class SettingPref { return Global.putInt(cr, setting, value); case TYPE_SYSTEM: return System.putInt(cr, setting, value); + case TYPE_SECURE: + return Secure.putInt(cr, setting, value); } throw new IllegalArgumentException(); } @@ -152,6 +158,8 @@ public class SettingPref { return Global.getInt(cr, setting, def); case TYPE_SYSTEM: return System.getInt(cr, setting, def); + case TYPE_SECURE: + return Secure.getInt(cr, setting, def); } throw new IllegalArgumentException(); } diff --git a/src/com/android/settings/notification/ZenModeBackend.java b/src/com/android/settings/notification/ZenModeBackend.java index 8242e3e9883..d63bed47637 100644 --- a/src/com/android/settings/notification/ZenModeBackend.java +++ b/src/com/android/settings/notification/ZenModeBackend.java @@ -136,8 +136,8 @@ public class ZenModeBackend { } protected void saveVisualEffectsPolicy(int category, boolean suppress) { - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.ZEN_SETTINGS_UPDATED, 1); + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ZEN_SETTINGS_UPDATED, 1); int suppressedEffects = getNewSuppressedEffects(suppress, category); savePolicy(mPolicy.priorityCategories, mPolicy.priorityCallSenders, diff --git a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java index ac9aaba632d..03e63e3a648 100644 --- a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java +++ b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java @@ -97,14 +97,14 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference private void updateZenButtonOnClickListener() { int zenDuration = getZenDuration(); switch (zenDuration) { - case Settings.Global.ZEN_DURATION_PROMPT: + case Settings.Secure.ZEN_DURATION_PROMPT: mZenButtonOn.setOnClickListener(v -> { mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_ZEN_TOGGLE_DND_BUTTON, false); new SettingsEnableZenModeDialog().show(mFragment, TAG); }); break; - case Settings.Global.ZEN_DURATION_FOREVER: + case Settings.Secure.ZEN_DURATION_FOREVER: mZenButtonOn.setOnClickListener(v -> { mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_ZEN_TOGGLE_DND_BUTTON, false); diff --git a/src/com/android/settings/notification/ZenOnboardingActivity.java b/src/com/android/settings/notification/ZenOnboardingActivity.java index 99bc1723c1e..3f12358f8ef 100644 --- a/src/com/android/settings/notification/ZenOnboardingActivity.java +++ b/src/com/android/settings/notification/ZenOnboardingActivity.java @@ -62,8 +62,8 @@ public class ZenOnboardingActivity extends Activity { setMetricsLogger(new MetricsLogger()); Context context = getApplicationContext(); - Settings.Global.putInt(context.getContentResolver(), - Settings.Global.ZEN_SETTINGS_SUGGESTION_VIEWED, 1); + Settings.Secure.putInt(context.getContentResolver(), + Settings.Secure.ZEN_SETTINGS_SUGGESTION_VIEWED, 1); setupUI(); } @@ -135,8 +135,8 @@ public class ZenOnboardingActivity extends Activity { mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_KEEP_CURRENT_SETTINGS); } - Settings.Global.putInt(getApplicationContext().getContentResolver(), - Settings.Global.ZEN_SETTINGS_UPDATED, 1); + Settings.Secure.putInt(getApplicationContext().getContentResolver(), + Settings.Secure.ZEN_SETTINGS_UPDATED, 1); finishAndRemoveTask(); } @@ -160,11 +160,11 @@ public class ZenOnboardingActivity extends Activity { NotificationManager nm = context.getSystemService(NotificationManager.class); if (NotificationManager.Policy.areAllVisualEffectsSuppressed( nm.getNotificationPolicy().suppressedVisualEffects)) { - Settings.Global.putInt(context.getContentResolver(), - Settings.Global.ZEN_SETTINGS_UPDATED, 1); + Settings.Secure.putInt(context.getContentResolver(), + Settings.Secure.ZEN_SETTINGS_UPDATED, 1); } - return Settings.Global.getInt(context.getContentResolver(), - Settings.Global.ZEN_SETTINGS_UPDATED, 0) != 0; + return Settings.Secure.getInt(context.getContentResolver(), + Settings.Secure.ZEN_SETTINGS_UPDATED, 0) != 0; } private static boolean showSuggestion(Context context) { @@ -173,8 +173,8 @@ public class ZenOnboardingActivity extends Activity { // SHOW_ZEN_SETTINGS_SUGGESTION is also true when: // - automatic rule has started DND and user has not seen the first use dialog - return Settings.Global.getInt(context.getContentResolver(), - Settings.Global.SHOW_ZEN_SETTINGS_SUGGESTION, 0) != 0; + return Settings.Secure.getInt(context.getContentResolver(), + Settings.Secure.SHOW_ZEN_SETTINGS_SUGGESTION, 0) != 0; } diff --git a/tests/robotests/src/com/android/settings/notification/ChargingSoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ChargingSoundPreferenceControllerTest.java index d54ef6fc3cc..2796049154c 100644 --- a/tests/robotests/src/com/android/settings/notification/ChargingSoundPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/ChargingSoundPreferenceControllerTest.java @@ -17,13 +17,14 @@ package com.android.settings.notification; import static com.google.common.truth.Truth.assertThat; + import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.ContentResolver; import android.content.Context; -import android.provider.Settings.Global; +import android.provider.Settings.Secure; import com.android.settings.testutils.SettingsRobolectricTestRunner; @@ -80,7 +81,7 @@ public class ChargingSoundPreferenceControllerTest { @Test public void displayPreference_chargingSoundEnabled_shouldCheckedPreference() { - Global.putInt(mContentResolver, Global.CHARGING_SOUNDS_ENABLED, 1); + Secure.putInt(mContentResolver, Secure.CHARGING_SOUNDS_ENABLED, 1); mController.displayPreference(mScreen); @@ -89,7 +90,7 @@ public class ChargingSoundPreferenceControllerTest { @Test public void displayPreference_chargingSoundDisabled_shouldUncheckedPreference() { - Global.putInt(mContentResolver, Global.CHARGING_SOUNDS_ENABLED, 0); + Secure.putInt(mContentResolver, Secure.CHARGING_SOUNDS_ENABLED, 0); mController.displayPreference(mScreen); @@ -102,7 +103,7 @@ public class ChargingSoundPreferenceControllerTest { mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, true); - assertThat(Global.getInt(mContentResolver, Global.CHARGING_SOUNDS_ENABLED, 1)) + assertThat(Secure.getInt(mContentResolver, Secure.CHARGING_SOUNDS_ENABLED, 1)) .isEqualTo(1); } @@ -112,7 +113,7 @@ public class ChargingSoundPreferenceControllerTest { mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, false); - assertThat(Global.getInt(mContentResolver, Global.CHARGING_SOUNDS_ENABLED, 1)) + assertThat(Secure.getInt(mContentResolver, Secure.CHARGING_SOUNDS_ENABLED, 1)) .isEqualTo(0); } } diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeDurationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeDurationPreferenceControllerTest.java index b748bcb9a9d..bbb2142882f 100644 --- a/tests/robotests/src/com/android/settings/notification/ZenModeDurationPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/ZenModeDurationPreferenceControllerTest.java @@ -78,8 +78,8 @@ public class ZenModeDurationPreferenceControllerTest { @Test public void updateState_DurationForever() { - Settings.Global.putInt(mContentResolver, Settings.Global.ZEN_DURATION, - Settings.Global.ZEN_DURATION_FOREVER); + Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION, + Settings.Secure.ZEN_DURATION_FOREVER); final Preference mockPref = mock(Preference.class); mController.updateState(mockPref); @@ -88,8 +88,8 @@ public class ZenModeDurationPreferenceControllerTest { @Test public void updateState_DurationPrompt() { - Settings.Global.putInt(mContentResolver, Settings.Global.ZEN_DURATION, - Settings.Global.ZEN_DURATION_PROMPT); + Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION, + Settings.Secure.ZEN_DURATION_PROMPT); final Preference mockPref = mock(Preference.class); mController.updateState(mockPref); @@ -100,7 +100,7 @@ public class ZenModeDurationPreferenceControllerTest { @Test public void updateState_DurationCustom() { int zenDuration = 45; - Settings.Global.putInt(mContentResolver, Settings.Global.ZEN_DURATION, + Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION, zenDuration); final Preference mockPref = mock(Preference.class); mController.updateState(mockPref); diff --git a/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java b/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java index 58468334c19..5b031aacc78 100644 --- a/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java +++ b/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java @@ -177,16 +177,16 @@ public class ZenOnboardingActivityTest { setShowSettingsSuggestion(true); setWithinTimeThreshold(true); assertThat(isSuggestionComplete(mContext)).isTrue(); - assertThat(Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.ZEN_SETTINGS_UPDATED, -1)).isEqualTo(1); + assertThat(Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.ZEN_SETTINGS_UPDATED, -1)).isEqualTo(1); } private void setZenUpdated(boolean updated) { int zenUpdated = updated ? 1 : 0; - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.ZEN_SETTINGS_UPDATED, zenUpdated); + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ZEN_SETTINGS_UPDATED, zenUpdated); } private void setWithinTimeThreshold(boolean withinTime) { @@ -208,8 +208,8 @@ public class ZenOnboardingActivityTest { showZenSuggestion = 1; } - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.SHOW_ZEN_SETTINGS_SUGGESTION, showZenSuggestion); + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.SHOW_ZEN_SETTINGS_SUGGESTION, showZenSuggestion); } private SharedPreferences getSharedPreferences() { From 53a12ee7b8a0d83113491aa13b133dce723b78e7 Mon Sep 17 00:00:00 2001 From: timhypeng Date: Thu, 14 Jun 2018 13:54:05 +0800 Subject: [PATCH 2/6] Add Hearing Aid UI into Settings-Accessibility App - dynamically show/hide preference by HearingAid profile is supported or not - add AccessibilityHearingAidPreferenceController to handle hearingAid preference - add HearingAidDialogFragment to handle dialog behavior Bug: 109948484 Test: make -j50 RunSettingsRoboTests Change-Id: Ic55dde475dc40311f7e652f4a86d342597f09f0e --- res/values/strings.xml | 2 + res/xml/accessibility_settings.xml | 5 + ...ibilityHearingAidPreferenceController.java | 217 ++++++++++++++++++ .../accessibility/AccessibilitySettings.java | 21 ++ .../HearingAidDialogFragment.java | 65 ++++++ ...ityHearingAidPreferenceControllerTest.java | 212 +++++++++++++++++ 6 files changed, 522 insertions(+) create mode 100644 src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java create mode 100644 src/com/android/settings/accessibility/HearingAidDialogFragment.java create mode 100644 tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 06f4123fe39..3198f9855f4 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4574,6 +4574,8 @@ Use captions + + Continue Hearing aids diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml index 9dda18f7abf..e36f578748e 100644 --- a/res/xml/accessibility_settings.xml +++ b/res/xml/accessibility_settings.xml @@ -113,6 +113,11 @@ android:summary="@string/accessibility_toggle_master_mono_summary" android:persistent="false"/> + + deviceList = mLocalBluetoothManager.getProfileManager() + .getHearingAidProfile().getConnectedDevices(); + final Iterator it = deviceList.iterator(); + if (it.hasNext()) { + BluetoothDevice obj = (BluetoothDevice)it.next(); + return mLocalBluetoothManager.getCachedDeviceManager().findDevice(obj); + } + return null; + } + + private boolean isHearingAidProfileSupported() { + final LocalBluetoothAdapter localAdapter = mLocalBluetoothManager.getBluetoothAdapter(); + final List supportedList = localAdapter.getSupportedProfiles(); + if (supportedList.contains(BluetoothProfile.HEARING_AID)) { + return true; + } + return false; + } + + private LocalBluetoothManager getLocalBluetoothManager() { + final FutureTask localBtManagerFutureTask = new FutureTask<>( + // Avoid StrictMode ThreadPolicy violation + () -> com.android.settings.bluetooth.Utils.getLocalBtManager(mContext)); + try { + localBtManagerFutureTask.run(); + return localBtManagerFutureTask.get(); + } catch (InterruptedException | ExecutionException e) { + Log.w(TAG, "Error getting LocalBluetoothManager.", e); + return null; + } + } + + @VisibleForTesting(otherwise = VisibleForTesting.NONE) + void setPreference(Preference preference) { + mHearingAidPreference = preference; + } + + @VisibleForTesting + void launchBluetoothDeviceDetailSetting(final CachedBluetoothDevice device) { + if (device == null) { + return; + } + final Bundle args = new Bundle(); + args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS, + device.getDevice().getAddress()); + + new SubSettingLauncher(mContext) + .setDestination(BluetoothDeviceDetailsFragment.class.getName()) + .setArguments(args) + .setTitleRes(R.string.device_details_title) + .setSourceMetricsCategory(MetricsProto.MetricsEvent.ACCESSIBILITY) + .launch(); + } + + @VisibleForTesting + void launchHearingAidInstructionDialog() { + HearingAidDialogFragment fragment = HearingAidDialogFragment.newInstance(); + fragment.show(mFragmentManager, HearingAidDialogFragment.class.toString()); + } +} \ No newline at end of file diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java index 22cff3eb7e4..d1b1ad41b70 100644 --- a/src/com/android/settings/accessibility/AccessibilitySettings.java +++ b/src/com/android/settings/accessibility/AccessibilitySettings.java @@ -110,6 +110,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements "select_long_press_timeout_preference"; private static final String ACCESSIBILITY_SHORTCUT_PREFERENCE = "accessibility_shortcut_preference"; + private static final String HEARING_AID_PREFERENCE = + "hearing_aid_preference"; private static final String CAPTIONING_PREFERENCE_SCREEN = "captioning_preference_screen"; private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN = @@ -221,9 +223,11 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements private Preference mAutoclickPreferenceScreen; private Preference mAccessibilityShortcutPreferenceScreen; private Preference mDisplayDaltonizerPreferenceScreen; + private Preference mHearingAidPreference; private Preference mVibrationPreferenceScreen; private SwitchPreference mToggleInversionPreference; private ColorInversionPreferenceController mInversionPreferenceController; + private AccessibilityHearingAidPreferenceController mHearingAidPreferenceController; private int mLongPressTimeoutDefault; @@ -275,6 +279,15 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements .getSystemService(Context.DEVICE_POLICY_SERVICE)); } + @Override + public void onAttach(Context context) { + super.onAttach(context); + mHearingAidPreferenceController = new AccessibilityHearingAidPreferenceController + (context, HEARING_AID_PREFERENCE); + mHearingAidPreferenceController.setFragmentManager(getFragmentManager()); + getLifecycle().addObserver(mHearingAidPreferenceController); + } + @Override public void onResume() { super.onResume(); @@ -335,6 +348,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements } else if (mToggleMasterMonoPreference == preference) { handleToggleMasterMonoPreferenceClick(); return true; + } else if (mHearingAidPreferenceController.handlePreferenceTreeClick(preference)) { + return true; } return super.onPreferenceTreeClick(preference); } @@ -452,6 +467,10 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements } } + // Hearing Aid. + mHearingAidPreference = findPreference(HEARING_AID_PREFERENCE); + mHearingAidPreferenceController.displayPreference(getPreferenceScreen()); + // Captioning. mCaptioningPreferenceScreen = findPreference(CAPTIONING_PREFERENCE_SCREEN); @@ -686,6 +705,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements updateVibrationSummary(mVibrationPreferenceScreen); + mHearingAidPreferenceController.updateState(mHearingAidPreference); + updateFeatureSummary(Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, mCaptioningPreferenceScreen); updateFeatureSummary(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, diff --git a/src/com/android/settings/accessibility/HearingAidDialogFragment.java b/src/com/android/settings/accessibility/HearingAidDialogFragment.java new file mode 100644 index 00000000000..0380ed3881f --- /dev/null +++ b/src/com/android/settings/accessibility/HearingAidDialogFragment.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.accessibility; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.os.Bundle; + +import com.android.internal.logging.nano.MetricsProto; +import com.android.settings.R; +import com.android.settings.bluetooth.BluetoothPairingDetail; +import com.android.settings.core.SubSettingLauncher; +import com.android.settings.core.instrumentation.InstrumentedDialogFragment; + +public class HearingAidDialogFragment extends InstrumentedDialogFragment { + public static HearingAidDialogFragment newInstance() { + HearingAidDialogFragment frag = new HearingAidDialogFragment(); + return frag; + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + return new AlertDialog.Builder(getActivity()) + .setTitle(R.string.accessibility_hearingaid_pair_instructions_first_message) + .setMessage(R.string.accessibility_hearingaid_pair_instructions_second_message) + .setPositiveButton(R.string.accessibility_hearingaid_instruction_continue_button, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + launchBluetoothAddDeviceSetting(); + } + }) + .setNegativeButton(android.R.string.cancel, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { } + }) + .create(); + } + + @Override + public int getMetricsCategory() { + return MetricsProto.MetricsEvent.DIALOG_ACCESSIBILITY_HEARINGAID; + } + + private void launchBluetoothAddDeviceSetting() { + new SubSettingLauncher(getActivity()) + .setDestination(BluetoothPairingDetail.class.getName()) + .setSourceMetricsCategory(MetricsProto.MetricsEvent.ACCESSIBILITY) + .launch(); + } +} diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java new file mode 100644 index 00000000000..8957f8547ed --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java @@ -0,0 +1,212 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.settings.accessibility; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHearingAid; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; + +import androidx.preference.Preference; + +import com.android.settings.R; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.ShadowBluetoothUtils; +import com.android.settingslib.bluetooth.CachedBluetoothDevice; +import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; +import com.android.settingslib.bluetooth.HearingAidProfile; +import com.android.settingslib.bluetooth.LocalBluetoothAdapter; +import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.util.ArrayList; +import java.util.List; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = {ShadowBluetoothUtils.class}) +public class AccessibilityHearingAidPreferenceControllerTest { + private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1"; + private static final String TEST_DEVICE_NAME = "TEST_HEARING_AID_BT_DEVICE_NAME"; + private static final String HEARING_AID_PREFERENCE = "hearing_aid_preference"; + + private BluetoothAdapter mBluetoothAdapter; + private BluetoothManager mBluetoothManager; + private BluetoothDevice mBluetoothDevice; + private Context mContext; + private Preference mHearingAidPreference; + private List mProfileSupportedList; + private AccessibilityHearingAidPreferenceController mPreferenceController; + + @Mock + private CachedBluetoothDevice mCachedBluetoothDevice; + @Mock + private CachedBluetoothDeviceManager mCachedDeviceManager; + @Mock + private LocalBluetoothAdapter mLocalBluetoothAdapter; + @Mock + private LocalBluetoothManager mLocalBluetoothManager; + @Mock + private LocalBluetoothProfileManager mLocalBluetoothProfileManager; + @Mock + private HearingAidProfile mHearingAidProfile; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application); + setupBluetoothEnvironment(); + setupHearingAidEnvironment(); + mHearingAidPreference = new Preference(mContext); + mHearingAidPreference.setKey(HEARING_AID_PREFERENCE); + mPreferenceController = new AccessibilityHearingAidPreferenceController(mContext, + HEARING_AID_PREFERENCE); + mPreferenceController.setPreference(mHearingAidPreference); + mHearingAidPreference.setSummary(""); + } + + @Test + public void onHearingAidStateChanged_connected_updateHearingAidSummary() { + when(mHearingAidProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList()); + mPreferenceController.onResume(); + Intent intent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED); + intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHearingAid.STATE_CONNECTED); + sendIntent(intent); + + assertThat(mHearingAidPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME); + } + + @Test + public void onHearingAidStateChanged_disconnected_updateHearingAidSummary() { + mPreferenceController.onResume(); + Intent intent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED); + intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHearingAid.STATE_DISCONNECTED); + sendIntent(intent); + + assertThat(mHearingAidPreference.getSummary()).isEqualTo( + mContext.getText(R.string.accessibility_hearingaid_not_connected_summary)); + } + + @Test + public void onBluetoothStateChanged_bluetoothOff_updateHearingAidSummary() { + mPreferenceController.onResume(); + Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED); + intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF); + sendIntent(intent); + + assertThat(mHearingAidPreference.getSummary()).isEqualTo( + mContext.getText(R.string.accessibility_hearingaid_not_connected_summary)); + } + + @Test + public void handleHearingAidPreferenceClick_noHearingAid_launchHearingAidInstructionDialog() { + mPreferenceController = spy(new AccessibilityHearingAidPreferenceController(mContext, + HEARING_AID_PREFERENCE)); + mPreferenceController.setPreference(mHearingAidPreference); + doNothing().when(mPreferenceController).launchHearingAidInstructionDialog(); + mPreferenceController.handlePreferenceTreeClick(mHearingAidPreference); + + verify(mPreferenceController).launchHearingAidInstructionDialog(); + } + + @Test + public void handleHearingAidPreferenceClick_withHearingAid_launchBluetoothDeviceDetailSetting() + { + mPreferenceController = spy(new AccessibilityHearingAidPreferenceController(mContext, + HEARING_AID_PREFERENCE)); + mPreferenceController.setPreference(mHearingAidPreference); + when(mHearingAidProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList()); + when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice); + mPreferenceController.handlePreferenceTreeClick(mHearingAidPreference); + + verify(mPreferenceController).launchBluetoothDeviceDetailSetting(mCachedBluetoothDevice); + } + + @Test + public void onNotSupportHearingAidProfile_doNotDoReceiverOperation() { + //clear bluetooth supported profile + mProfileSupportedList.clear(); + mPreferenceController = new AccessibilityHearingAidPreferenceController(mContext, HEARING_AID_PREFERENCE); + mPreferenceController.setPreference(mHearingAidPreference); + //not call registerReceiver() + mPreferenceController.onResume(); + verify(mContext, never()).registerReceiver((BroadcastReceiver) any(), (IntentFilter) any()); + + //not call unregisterReceiver() + mPreferenceController.onPause(); + verify(mContext, never()).unregisterReceiver((BroadcastReceiver) any()); + } + + private void setupBluetoothEnvironment() { + ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager; + mLocalBluetoothManager = ShadowBluetoothUtils.getLocalBtManager(mContext); + mBluetoothManager = new BluetoothManager(mContext); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + when(mLocalBluetoothManager.getBluetoothAdapter()).thenReturn(mLocalBluetoothAdapter); + when(mLocalBluetoothAdapter.isEnabled()).thenReturn(true); + when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager); + when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager); + when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); + } + + private void setupHearingAidEnvironment() { + mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS); + mProfileSupportedList = new ArrayList(); + mProfileSupportedList.add(BluetoothProfile.HEARING_AID); + when(mLocalBluetoothAdapter.getSupportedProfiles()).thenReturn(mProfileSupportedList); + when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice); + when(mCachedBluetoothDevice.getName()).thenReturn(TEST_DEVICE_NAME); + when(mCachedBluetoothDevice.isConnectedHearingAidDevice()).thenReturn(true); + } + + private void sendIntent(Intent intent) { + ArgumentCaptor broadcastReceiverCaptor = + ArgumentCaptor.forClass(BroadcastReceiver.class); + verify(mContext).registerReceiver( + broadcastReceiverCaptor.capture(), (IntentFilter) any()); + BroadcastReceiver br = broadcastReceiverCaptor.getValue(); + br.onReceive(mContext, intent); + } + + private List generateHearingAidDeviceList() { + final List deviceList = new ArrayList<>(1); + deviceList.add(mBluetoothDevice); + return deviceList; + } +} From 0f828239d482be426ba953989b629d16bc6c8cae Mon Sep 17 00:00:00 2001 From: tmfang Date: Tue, 31 Jul 2018 11:12:16 +0800 Subject: [PATCH 3/6] Remove UsbModeChooserActivity in AndroidManifest UsbModeChooserActivity was removed since b/70848054, So, we also removed it in AndroidManifest.xml. Change-Id: I42a3330eec46ac957beeb384ef7d0c130f2f82e3 Fixes: 111968651 Test: robo --- AndroidManifest.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index a275be0b753..d4015ce8aa1 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1945,13 +1945,6 @@ - - - Date: Thu, 26 Jul 2018 11:22:01 +0800 Subject: [PATCH 4/6] Use BluetoothAdapter instead of LocalBluetoothAdapter LocalBluetoothAdapter only has a few APIs that is not supported by BluetoothAdapter, and lots of LocalBluetoothAdapter function pass parameter to BluetoothAdapter directly. Do the refactor in Settings, use BluetoothAdapter instead of LocalBluetoothAdapter. Bug: 111769754 Test: make -j42 RunSettingsRoboTests Change-Id: I88e5a8377b5d1106c7679e6a8c3fd1ca1a80ea6f --- .../bluetooth/AlwaysDiscoverable.java | 20 ++--- ...uetoothDeviceNamePreferenceController.java | 24 ++---- ...toothDeviceRenamePreferenceController.java | 11 +-- .../BluetoothDiscoverableEnabler.java | 23 +++--- .../settings/bluetooth/BluetoothEnabler.java | 33 ++++---- .../bluetooth/BluetoothPairingDetail.java | 12 +-- .../bluetooth/BluetoothSliceBuilder.java | 11 +-- .../bluetooth/BluetoothSummaryUpdater.java | 6 +- .../BluetoothSwitchPreferenceController.java | 18 +---- .../DeviceListPreferenceFragment.java | 31 +++++--- .../bluetooth/DevicePickerFragment.java | 2 +- .../bluetooth/LocalBluetoothPreferences.java | 4 +- .../LocalDeviceNameDialogFragment.java | 13 ++-- .../bluetooth/RequestPermissionActivity.java | 30 ++++--- .../RequestPermissionHelperActivity.java | 22 +++--- ...iscoverableFooterPreferenceController.java | 11 ++- .../DeviceNamePreferenceController.java | 22 ++---- .../aboutphone/MyDeviceInfoFragment.java | 3 - .../widget/SettingsAppWidgetProvider.java | 27 +++---- .../bluetooth/AlwaysDiscoverableTest.java | 35 +++++---- ...othDeviceNamePreferenceControllerTest.java | 10 +-- ...hDeviceRenamePreferenceControllerTest.java | 20 +++-- .../bluetooth/BluetoothEnablerTest.java | 22 +++--- .../bluetooth/BluetoothPairingDetailTest.java | 42 +++++----- .../bluetooth/BluetoothSliceBuilderTest.java | 11 +-- .../BluetoothSummaryUpdaterTest.java | 78 +++++++++++-------- ...uetoothSwitchPreferenceControllerTest.java | 4 +- .../DeviceListPreferenceFragmentTest.java | 49 ++++++------ .../LocalDeviceNameDialogFragmentTest.java | 7 -- ...verableFooterPreferenceControllerTest.java | 11 +-- .../DeviceNamePreferenceControllerTest.java | 23 +++--- .../shadow/ShadowBluetoothAdapter.java | 33 ++++++++ 32 files changed, 327 insertions(+), 341 deletions(-) diff --git a/src/com/android/settings/bluetooth/AlwaysDiscoverable.java b/src/com/android/settings/bluetooth/AlwaysDiscoverable.java index b89706d2e65..7b948719721 100644 --- a/src/com/android/settings/bluetooth/AlwaysDiscoverable.java +++ b/src/com/android/settings/bluetooth/AlwaysDiscoverable.java @@ -22,8 +22,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; - import androidx.annotation.VisibleForTesting; /** Helper class, intended to be used by an Activity, to keep the local Bluetooth adapter in @@ -35,15 +33,15 @@ public class AlwaysDiscoverable extends BroadcastReceiver { private static final String TAG = "AlwaysDiscoverable"; private Context mContext; - private LocalBluetoothAdapter mLocalAdapter; + private BluetoothAdapter mBluetoothAdapter; private IntentFilter mIntentFilter; @VisibleForTesting boolean mStarted; - public AlwaysDiscoverable(Context context, LocalBluetoothAdapter localAdapter) { + public AlwaysDiscoverable(Context context) { mContext = context; - mLocalAdapter = localAdapter; + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); } @@ -56,8 +54,9 @@ public class AlwaysDiscoverable extends BroadcastReceiver { } mContext.registerReceiver(this, mIntentFilter); mStarted = true; - if (mLocalAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { - mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); + if (mBluetoothAdapter.getScanMode() + != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { + mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); } } @@ -67,7 +66,7 @@ public class AlwaysDiscoverable extends BroadcastReceiver { } mContext.unregisterReceiver(this); mStarted = false; - mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE); + mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE); } @Override @@ -76,8 +75,9 @@ public class AlwaysDiscoverable extends BroadcastReceiver { if (action != BluetoothAdapter.ACTION_SCAN_MODE_CHANGED) { return; } - if (mLocalAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { - mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); + if (mBluetoothAdapter.getScanMode() + != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { + mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); } } } diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java index 5b653352102..b9154f50a1d 100644 --- a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java +++ b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java @@ -27,8 +27,6 @@ import android.util.Log; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; -import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; @@ -46,8 +44,7 @@ public class BluetoothDeviceNamePreferenceController extends BasePreferenceContr @VisibleForTesting Preference mPreference; - private LocalBluetoothManager mLocalManager; - protected LocalBluetoothAdapter mLocalAdapter; + protected BluetoothAdapter mBluetoothAdapter; /** * Constructor exclusively used for Slice. @@ -55,19 +52,11 @@ public class BluetoothDeviceNamePreferenceController extends BasePreferenceContr public BluetoothDeviceNamePreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); - mLocalManager = Utils.getLocalBtManager(context); - if (mLocalManager == null) { + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (mBluetoothAdapter == null) { Log.e(TAG, "Bluetooth is not supported on this device"); return; } - mLocalAdapter = mLocalManager.getBluetoothAdapter(); - } - - @VisibleForTesting - BluetoothDeviceNamePreferenceController(Context context, LocalBluetoothAdapter localAdapter, - String preferenceKey) { - super(context, preferenceKey); - mLocalAdapter = localAdapter; } @Override @@ -91,7 +80,7 @@ public class BluetoothDeviceNamePreferenceController extends BasePreferenceContr @Override public int getAvailabilityStatus() { - return mLocalAdapter != null ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + return mBluetoothAdapter != null ? AVAILABLE : UNSUPPORTED_ON_DEVICE; } @Override @@ -138,7 +127,7 @@ public class BluetoothDeviceNamePreferenceController extends BasePreferenceContr } protected String getDeviceName() { - return mLocalAdapter.getName(); + return mBluetoothAdapter.getName(); } /** @@ -152,7 +141,8 @@ public class BluetoothDeviceNamePreferenceController extends BasePreferenceContr final String action = intent.getAction(); if (TextUtils.equals(action, BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) { - if (mPreference != null && mLocalAdapter != null && mLocalAdapter.isEnabled()) { + if (mPreference != null && mBluetoothAdapter != null + && mBluetoothAdapter.isEnabled()) { updatePreferenceState(mPreference); } } else if (TextUtils.equals(action, BluetoothAdapter.ACTION_STATE_CHANGED)) { diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java index 0fb2f87744d..24fcf6ae1e4 100644 --- a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java +++ b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java @@ -16,12 +16,12 @@ package com.android.settings.bluetooth; +import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.text.TextUtils; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.overlay.FeatureFactory; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import androidx.annotation.VisibleForTesting; @@ -42,13 +42,6 @@ public class BluetoothDeviceRenamePreferenceController extends mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); } - @VisibleForTesting - BluetoothDeviceRenamePreferenceController(Context context, LocalBluetoothAdapter localAdapter, - String preferenceKey) { - super(context, localAdapter, preferenceKey); - mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); - } - /** * Set the {@link Fragment} that used to show {@link LocalDeviceNameDialogFragment} * in {@code handlePreferenceTreeClick} @@ -61,7 +54,7 @@ public class BluetoothDeviceRenamePreferenceController extends @Override protected void updatePreferenceState(final Preference preference) { preference.setSummary(getSummary()); - preference.setVisible(mLocalAdapter != null && mLocalAdapter.isEnabled()); + preference.setVisible(mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()); } @Override diff --git a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java index 3db30053b6d..aec6d2d99af 100755 --- a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java +++ b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java @@ -28,7 +28,6 @@ import android.util.Log; import com.android.settings.R; import com.android.settingslib.bluetooth.BluetoothDiscoverableTimeoutReceiver; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import androidx.preference.Preference; @@ -64,7 +63,7 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceClick private final Handler mUiHandler; private final Preference mDiscoveryPreference; - private final LocalBluetoothAdapter mLocalAdapter; + private final BluetoothAdapter mBluetoothAdapter; private final SharedPreferences mSharedPreferences; @@ -92,17 +91,16 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceClick } }; - BluetoothDiscoverableEnabler(LocalBluetoothAdapter adapter, - Preference discoveryPreference) { + BluetoothDiscoverableEnabler(Preference discoveryPreference) { mUiHandler = new Handler(); - mLocalAdapter = adapter; + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); mDiscoveryPreference = discoveryPreference; mSharedPreferences = discoveryPreference.getSharedPreferences(); discoveryPreference.setPersistent(false); } public void resume(Context context) { - if (mLocalAdapter == null) { + if (mBluetoothAdapter == null) { return; } @@ -113,11 +111,11 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceClick IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); mContext.registerReceiver(mReceiver, filter); mDiscoveryPreference.setOnPreferenceClickListener(this); - handleModeChanged(mLocalAdapter.getScanMode()); + handleModeChanged(mBluetoothAdapter.getScanMode()); } public void pause() { - if (mLocalAdapter == null) { + if (mBluetoothAdapter == null) { return; } @@ -139,7 +137,8 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceClick long endTimestamp = System.currentTimeMillis() + timeout * 1000L; LocalBluetoothPreferences.persistDiscoverableEndTimestamp(mContext, endTimestamp); - mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout); + mBluetoothAdapter + .setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout); updateCountdownSummary(); Log.d(TAG, "setEnabled(): enabled = " + enable + "timeout = " + timeout); @@ -151,7 +150,7 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceClick } } else { - mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE); + mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE); BluetoothDiscoverableTimeoutReceiver.cancelDiscoverableAlarm(mContext); } } @@ -250,7 +249,7 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceClick void setNumberOfPairedDevices(int pairedDevices) { mNumberOfPairedDevices = pairedDevices; - handleModeChanged(mLocalAdapter.getScanMode()); + handleModeChanged(mBluetoothAdapter.getScanMode()); } void handleModeChanged(int mode) { @@ -273,7 +272,7 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceClick } private void updateCountdownSummary() { - int mode = mLocalAdapter.getScanMode(); + int mode = mBluetoothAdapter.getScanMode(); if (mode != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { return; } diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java index 98a4b9c7a68..9c00a50d4df 100644 --- a/src/com/android/settings/bluetooth/BluetoothEnabler.java +++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java @@ -29,8 +29,6 @@ import com.android.settings.R; import com.android.settings.widget.SwitchWidgetController; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.WirelessUtils; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; -import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import androidx.annotation.VisibleForTesting; @@ -45,7 +43,7 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh private final MetricsFeatureProvider mMetricsFeatureProvider; private Context mContext; private boolean mValidListener; - private final LocalBluetoothAdapter mLocalAdapter; + private final BluetoothAdapter mBluetoothAdapter; private final IntentFilter mIntentFilter; private final RestrictionUtils mRestrictionUtils; private SwitchWidgetController.OnSwitchChangeListener mCallback; @@ -65,15 +63,14 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh }; public BluetoothEnabler(Context context, SwitchWidgetController switchController, - MetricsFeatureProvider metricsFeatureProvider, LocalBluetoothManager manager, - int metricsEvent) { - this(context, switchController, metricsFeatureProvider, manager, metricsEvent, + MetricsFeatureProvider metricsFeatureProvider, int metricsEvent) { + this(context, switchController, metricsFeatureProvider, metricsEvent, new RestrictionUtils()); } public BluetoothEnabler(Context context, SwitchWidgetController switchController, - MetricsFeatureProvider metricsFeatureProvider, LocalBluetoothManager manager, - int metricsEvent, RestrictionUtils restrictionUtils) { + MetricsFeatureProvider metricsFeatureProvider, int metricsEvent, + RestrictionUtils restrictionUtils) { mContext = context; mMetricsFeatureProvider = metricsFeatureProvider; mSwitchController = switchController; @@ -81,12 +78,10 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh mValidListener = false; mMetricsEvent = metricsEvent; - if (manager == null) { + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (mBluetoothAdapter == null) { // Bluetooth is not supported - mLocalAdapter = null; mSwitchController.setEnabled(false); - } else { - mLocalAdapter = manager.getBluetoothAdapter(); } mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); mRestrictionUtils = restrictionUtils; @@ -107,14 +102,14 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh final boolean restricted = maybeEnforceRestrictions(); - if (mLocalAdapter == null) { + if (mBluetoothAdapter == null) { mSwitchController.setEnabled(false); return; } // Bluetooth state is not sticky, so set it manually if (!restricted) { - handleStateChanged(mLocalAdapter.getBluetoothState()); + handleStateChanged(mBluetoothAdapter.getState()); } mSwitchController.startListening(); @@ -123,7 +118,7 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh } public void pause() { - if (mLocalAdapter == null) { + if (mBluetoothAdapter == null) { return; } if (mValidListener) { @@ -188,8 +183,8 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh mMetricsFeatureProvider.action(mContext, mMetricsEvent, isChecked); - if (mLocalAdapter != null) { - boolean status = mLocalAdapter.setBluetoothEnabled(isChecked); + if (mBluetoothAdapter != null) { + boolean status = setBluetoothEnabled(isChecked); // If we cannot toggle it ON then reset the UI assets: // a) The switch should be OFF but it should still be togglable (enabled = True) // b) The switch bar should have OFF text. @@ -249,4 +244,8 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh mCallback.onSwitchToggled(isChecked); } } + + private boolean setBluetoothEnabled(boolean isEnabled) { + return isEnabled ? mBluetoothAdapter.enable() : mBluetoothAdapter.disable(); + } } diff --git a/src/com/android/settings/bluetooth/BluetoothPairingDetail.java b/src/com/android/settings/bluetooth/BluetoothPairingDetail.java index af2711c4a5b..905327d54a8 100644 --- a/src/com/android/settings/bluetooth/BluetoothPairingDetail.java +++ b/src/com/android/settings/bluetooth/BluetoothPairingDetail.java @@ -63,7 +63,7 @@ public class BluetoothPairingDetail extends DeviceListPreferenceFragment impleme public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mInitialScanStarted = false; - mAlwaysDiscoverable = new AlwaysDiscoverable(getContext(), mLocalAdapter); + mAlwaysDiscoverable = new AlwaysDiscoverable(getContext()); } @Override @@ -74,7 +74,7 @@ public class BluetoothPairingDetail extends DeviceListPreferenceFragment impleme return; } updateBluetooth(); - mAvailableDevicesCategory.setProgress(mLocalAdapter.isDiscovering()); + mAvailableDevicesCategory.setProgress(mBluetoothAdapter.isDiscovering()); } @Override @@ -85,11 +85,11 @@ public class BluetoothPairingDetail extends DeviceListPreferenceFragment impleme @VisibleForTesting void updateBluetooth() { - if (mLocalAdapter.isEnabled()) { - updateContent(mLocalAdapter.getBluetoothState()); + if (mBluetoothAdapter.isEnabled()) { + updateContent(mBluetoothAdapter.getState()); } else { // Turn on bluetooth if it is disabled - mLocalAdapter.enable(); + mBluetoothAdapter.enable(); } } @@ -148,7 +148,7 @@ public class BluetoothPairingDetail extends DeviceListPreferenceFragment impleme switch (bluetoothState) { case BluetoothAdapter.STATE_ON: mDevicePreferenceMap.clear(); - mLocalAdapter.setBluetoothEnabled(true); + mBluetoothAdapter.enable(); addDeviceCategory(mAvailableDevicesCategory, R.string.bluetooth_preference_found_media_devices, diff --git a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java index 7d5ae2bb50c..7a569947b4f 100644 --- a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java +++ b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java @@ -33,8 +33,6 @@ import com.android.settings.SubSettings; import com.android.settings.connecteddevice.BluetoothDashboardFragment; import com.android.settings.slices.SliceBroadcastReceiver; import com.android.settings.slices.SliceBuilderUtils; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; -import com.android.settingslib.bluetooth.LocalBluetoothManager; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; @@ -119,10 +117,13 @@ public class BluetoothSliceBuilder { */ public static void handleUriChange(Context context, Intent intent) { final boolean newBluetoothState = intent.getBooleanExtra(EXTRA_TOGGLE_STATE, false); - final LocalBluetoothAdapter adapter = LocalBluetoothManager.getInstance(context, - null /* callback */).getBluetoothAdapter(); + final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); - adapter.setBluetoothEnabled(newBluetoothState); + if (newBluetoothState) { + adapter.enable(); + } else { + adapter.disable(); + } // Do not notifyChange on Uri. The service takes longer to update the current value than it // does for the Slice to check the current value again. Let {@link SliceBroadcastRelay} // handle it. diff --git a/src/com/android/settings/bluetooth/BluetoothSummaryUpdater.java b/src/com/android/settings/bluetooth/BluetoothSummaryUpdater.java index 08aee5f1c8c..03fffa47f06 100644 --- a/src/com/android/settings/bluetooth/BluetoothSummaryUpdater.java +++ b/src/com/android/settings/bluetooth/BluetoothSummaryUpdater.java @@ -25,7 +25,6 @@ import com.android.settings.R; import com.android.settings.widget.SummaryUpdater; import com.android.settingslib.bluetooth.BluetoothCallback; import com.android.settingslib.bluetooth.CachedBluetoothDevice; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.bluetooth.LocalBluetoothManager; import java.util.Set; @@ -39,15 +38,14 @@ import androidx.annotation.VisibleForTesting; public final class BluetoothSummaryUpdater extends SummaryUpdater implements BluetoothCallback { private static final String TAG = "BluetoothSummaryUpdater"; + private final BluetoothAdapter mBluetoothAdapter; private final LocalBluetoothManager mBluetoothManager; - private final LocalBluetoothAdapter mBluetoothAdapter; public BluetoothSummaryUpdater(Context context, OnSummaryChangeListener listener, LocalBluetoothManager bluetoothManager) { super(context, listener); mBluetoothManager = bluetoothManager; - mBluetoothAdapter = mBluetoothManager != null - ? mBluetoothManager.getBluetoothAdapter() : null; + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } @Override diff --git a/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java index c6658e199d8..d828302876e 100644 --- a/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java +++ b/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java @@ -26,8 +26,6 @@ import com.android.settings.location.ScanningSettings; import com.android.settings.overlay.FeatureFactory; import com.android.settings.utils.AnnotationSpan; import com.android.settings.widget.SwitchWidgetController; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; -import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; @@ -43,10 +41,6 @@ public class BluetoothSwitchPreferenceController implements LifecycleObserver, OnStart, OnStop, SwitchWidgetController.OnSwitchChangeListener, View.OnClickListener { - @VisibleForTesting - LocalBluetoothAdapter mBluetoothAdapter; - - private LocalBluetoothManager mBluetoothManager; private BluetoothEnabler mBluetoothEnabler; private RestrictionUtils mRestrictionUtils; private SwitchWidgetController mSwitch; @@ -56,15 +50,12 @@ public class BluetoothSwitchPreferenceController public BluetoothSwitchPreferenceController(Context context, SwitchWidgetController switchController, FooterPreference footerPreference) { - this(context, Utils.getLocalBtManager(context), new RestrictionUtils(), switchController, - footerPreference); + this(context, new RestrictionUtils(), switchController, footerPreference); } @VisibleForTesting - public BluetoothSwitchPreferenceController(Context context, - LocalBluetoothManager bluetoothManager, RestrictionUtils restrictionUtils, + public BluetoothSwitchPreferenceController(Context context, RestrictionUtils restrictionUtils, SwitchWidgetController switchController, FooterPreference footerPreference) { - mBluetoothManager = bluetoothManager; mRestrictionUtils = restrictionUtils; mSwitch = switchController; mContext = context; @@ -73,12 +64,9 @@ public class BluetoothSwitchPreferenceController mSwitch.setupView(); updateText(mSwitch.isChecked()); - if (mBluetoothManager != null) { - mBluetoothAdapter = mBluetoothManager.getBluetoothAdapter(); - } mBluetoothEnabler = new BluetoothEnabler(context, switchController, - FeatureFactory.getFactory(context).getMetricsFeatureProvider(), mBluetoothManager, + FeatureFactory.getFactory(context).getMetricsFeatureProvider(), MetricsEvent.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE, mRestrictionUtils); mBluetoothEnabler.setToggleCallback(this); diff --git a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java index 7c7e271e90f..7c4224e8d0f 100644 --- a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java +++ b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java @@ -28,7 +28,6 @@ import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settingslib.bluetooth.BluetoothCallback; import com.android.settingslib.bluetooth.BluetoothDeviceFilter; import com.android.settingslib.bluetooth.CachedBluetoothDevice; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.bluetooth.LocalBluetoothManager; import java.util.Collection; @@ -64,7 +63,7 @@ public abstract class DeviceListPreferenceFragment extends BluetoothDevice mSelectedDevice; - LocalBluetoothAdapter mLocalAdapter; + BluetoothAdapter mBluetoothAdapter; LocalBluetoothManager mLocalManager; @VisibleForTesting @@ -97,7 +96,7 @@ public abstract class DeviceListPreferenceFragment extends Log.e(TAG, "Bluetooth is not supported on this device"); return; } - mLocalAdapter = mLocalManager.getBluetoothAdapter(); + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); mShowDevicesWithoutNames = SystemProperties.getBoolean( BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_PROPERTY, false); @@ -146,7 +145,7 @@ public abstract class DeviceListPreferenceFragment extends @Override public boolean onPreferenceTreeClick(Preference preference) { if (KEY_BT_SCAN.equals(preference.getKey())) { - mLocalAdapter.startScanning(true); + startScanning(); return true; } @@ -172,7 +171,7 @@ public abstract class DeviceListPreferenceFragment extends } // Prevent updates while the list shows one of the state messages - if (mLocalAdapter.getBluetoothState() != BluetoothAdapter.STATE_ON) return; + if (mBluetoothAdapter.getState() != BluetoothAdapter.STATE_ON) return; if (mFilter.matches(cachedDevice.getDevice())) { createDevicePreference(cachedDevice); @@ -214,7 +213,7 @@ public abstract class DeviceListPreferenceFragment extends myDevicePreference.setTitle(getString( R.string.bluetooth_footer_mac_message, - bidiFormatter.unicodeWrap(mLocalAdapter.getAddress()))); + bidiFormatter.unicodeWrap(mBluetoothAdapter.getAddress()))); } @Override @@ -227,21 +226,21 @@ public abstract class DeviceListPreferenceFragment extends @VisibleForTesting void enableScanning() { - // LocalBluetoothAdapter already handles repeated scan requests - mLocalAdapter.startScanning(true); + // BluetoothAdapter already handles repeated scan requests + startScanning(); mScanEnabled = true; } @VisibleForTesting void disableScanning() { - mLocalAdapter.stopScanning(); + stopScanning(); mScanEnabled = false; } @Override public void onScanningStateChanged(boolean started) { if (!started && mScanEnabled) { - mLocalAdapter.startScanning(true); + startScanning(); } } @@ -287,4 +286,16 @@ public abstract class DeviceListPreferenceFragment extends public boolean shouldShowDevicesWithoutNames() { return mShowDevicesWithoutNames; } + + void startScanning() { + if (!mBluetoothAdapter.isDiscovering()) { + mBluetoothAdapter.startDiscovery(); + } + } + + void stopScanning() { + if (mBluetoothAdapter.isDiscovering()) { + mBluetoothAdapter.cancelDiscovery(); + } + } } diff --git a/src/com/android/settings/bluetooth/DevicePickerFragment.java b/src/com/android/settings/bluetooth/DevicePickerFragment.java index 5d404d71289..097fba7ac81 100644 --- a/src/com/android/settings/bluetooth/DevicePickerFragment.java +++ b/src/com/android/settings/bluetooth/DevicePickerFragment.java @@ -94,7 +94,7 @@ public final class DevicePickerFragment extends DeviceListPreferenceFragment { mSelectedDevice = null; if (mScanAllowed) { enableScanning(); - mAvailableDevicesCategory.setProgress(mLocalAdapter.isDiscovering()); + mAvailableDevicesCategory.setProgress(mBluetoothAdapter.isDiscovering()); } } diff --git a/src/com/android/settings/bluetooth/LocalBluetoothPreferences.java b/src/com/android/settings/bluetooth/LocalBluetoothPreferences.java index 2a659013eb6..faed1c3c6a2 100644 --- a/src/com/android/settings/bluetooth/LocalBluetoothPreferences.java +++ b/src/com/android/settings/bluetooth/LocalBluetoothPreferences.java @@ -16,13 +16,13 @@ package com.android.settings.bluetooth; +import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.content.SharedPreferences; import android.content.res.Configuration; import android.text.TextUtils; import android.util.Log; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.bluetooth.LocalBluetoothManager; /** @@ -89,7 +89,7 @@ final class LocalBluetoothPreferences { } // If the device was discoverING recently - LocalBluetoothAdapter adapter = manager.getBluetoothAdapter(); + BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter != null) { if (adapter.isDiscovering()) { return true; diff --git a/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragment.java b/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragment.java index 029b974d201..4cbcce8a556 100644 --- a/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragment.java +++ b/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragment.java @@ -25,13 +25,11 @@ import android.os.Bundle; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; -import com.android.settingslib.bluetooth.LocalBluetoothManager; /** Provides a dialog for changing the advertised name of the local bluetooth adapter. */ public class LocalDeviceNameDialogFragment extends BluetoothNameDialogFragment { public static final String TAG = "LocalAdapterName"; - private LocalBluetoothAdapter mLocalAdapter; + private BluetoothAdapter mBluetoothAdapter; public static LocalDeviceNameDialogFragment newInstance() { return new LocalDeviceNameDialogFragment(); @@ -53,8 +51,7 @@ public class LocalDeviceNameDialogFragment extends BluetoothNameDialogFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - LocalBluetoothManager localManager = Utils.getLocalBtManager(getActivity()); - mLocalAdapter = localManager.getBluetoothAdapter(); + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } @Override @@ -84,14 +81,14 @@ public class LocalDeviceNameDialogFragment extends BluetoothNameDialogFragment { @Override protected String getDeviceName() { - if (mLocalAdapter != null && mLocalAdapter.isEnabled()) { - return mLocalAdapter.getName(); + if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) { + return mBluetoothAdapter.getName(); } return null; } @Override protected void setDeviceName(String deviceName) { - mLocalAdapter.setName(deviceName); + mBluetoothAdapter.setName(deviceName); } } diff --git a/src/com/android/settings/bluetooth/RequestPermissionActivity.java b/src/com/android/settings/bluetooth/RequestPermissionActivity.java index 5f6fc3959ea..fff6f12ccc5 100644 --- a/src/com/android/settings/bluetooth/RequestPermissionActivity.java +++ b/src/com/android/settings/bluetooth/RequestPermissionActivity.java @@ -34,8 +34,6 @@ import android.util.Log; import com.android.settings.R; import com.android.settingslib.bluetooth.BluetoothDiscoverableTimeoutReceiver; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; -import com.android.settingslib.bluetooth.LocalBluetoothManager; import androidx.appcompat.app.AlertDialog; @@ -58,7 +56,7 @@ public class RequestPermissionActivity extends Activity implements static final int REQUEST_ENABLE_DISCOVERABLE = 2; static final int REQUEST_DISABLE = 3; - private LocalBluetoothAdapter mLocalAdapter; + private BluetoothAdapter mBluetoothAdapter; private int mTimeout = BluetoothDiscoverableEnabler.DEFAULT_DISCOVERABLE_TIMEOUT; @@ -76,13 +74,13 @@ public class RequestPermissionActivity extends Activity implements setResult(Activity.RESULT_CANCELED); - // Note: initializes mLocalAdapter and returns true on error + // Note: initializes mBluetoothAdapter and returns true on error if (parseIntent()) { finish(); return; } - int btState = mLocalAdapter.getState(); + int btState = mBluetoothAdapter.getState(); if (mRequest == REQUEST_DISABLE) { switch (btState) { @@ -204,7 +202,7 @@ public class RequestPermissionActivity extends Activity implements switch (mRequest) { case REQUEST_ENABLE: case REQUEST_ENABLE_DISCOVERABLE: { - if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) { + if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) { proceedAndFinish(); } else { // If BT is not up yet, show "Turning on Bluetooth..." @@ -216,7 +214,7 @@ public class RequestPermissionActivity extends Activity implements } break; case REQUEST_DISABLE: { - if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_OFF) { + if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF) { proceedAndFinish(); } else { // If BT is not up yet, show "Turning off Bluetooth..." @@ -252,7 +250,7 @@ public class RequestPermissionActivity extends Activity implements if (mRequest == REQUEST_ENABLE || mRequest == REQUEST_DISABLE) { // BT toggled. Done returnCode = RESULT_OK; - } else if (mLocalAdapter.setScanMode( + } else if (mBluetoothAdapter.setScanMode( BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, mTimeout)) { // If already in discoverable mode, this will extend the timeout. long endTime = System.currentTimeMillis() + (long) mTimeout * 1000; @@ -284,7 +282,7 @@ public class RequestPermissionActivity extends Activity implements } /** - * Parse the received Intent and initialize mLocalBluetoothAdapter. + * Parse the received Intent and initialize mBluetoothAdapter. * @return true if an error occurred; false otherwise */ private boolean parseIntent() { @@ -314,13 +312,6 @@ public class RequestPermissionActivity extends Activity implements return true; } - LocalBluetoothManager manager = Utils.getLocalBtManager(this); - if (manager == null) { - Log.e(TAG, "Error: there's a problem starting Bluetooth"); - setResult(RESULT_CANCELED); - return true; - } - String packageName = getCallingPackage(); if (TextUtils.isEmpty(packageName)) { packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME); @@ -340,7 +331,12 @@ public class RequestPermissionActivity extends Activity implements } } - mLocalAdapter = manager.getBluetoothAdapter(); + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (mBluetoothAdapter == null) { + Log.e(TAG, "Error: there's a problem starting Bluetooth"); + setResult(RESULT_CANCELED); + return true; + } return false; } diff --git a/src/com/android/settings/bluetooth/RequestPermissionHelperActivity.java b/src/com/android/settings/bluetooth/RequestPermissionHelperActivity.java index aaa7b507f71..99ac9281510 100644 --- a/src/com/android/settings/bluetooth/RequestPermissionHelperActivity.java +++ b/src/com/android/settings/bluetooth/RequestPermissionHelperActivity.java @@ -28,8 +28,6 @@ import android.util.Log; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; import com.android.settings.R; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; -import com.android.settingslib.bluetooth.LocalBluetoothManager; /** * RequestPermissionHelperActivity asks the user whether to toggle Bluetooth. @@ -49,7 +47,7 @@ public class RequestPermissionHelperActivity extends AlertActivity implements public static final String EXTRA_APP_LABEL = "com.android.settings.bluetooth.extra.APP_LABEL"; - private LocalBluetoothAdapter mLocalAdapter; + private BluetoothAdapter mBluetoothAdapter; private CharSequence mAppLabel; @@ -63,7 +61,7 @@ public class RequestPermissionHelperActivity extends AlertActivity implements setResult(RESULT_CANCELED); - // Note: initializes mLocalAdapter and returns true on error + // Note: initializes mBluetoothAdapter and returns true on error if (!parseIntent()) { finish(); return; @@ -131,20 +129,20 @@ public class RequestPermissionHelperActivity extends AlertActivity implements startActivity(intent); } } else { - mLocalAdapter.enable(); + mBluetoothAdapter.enable(); setResult(Activity.RESULT_OK); } } break; case RequestPermissionActivity.REQUEST_DISABLE: { - mLocalAdapter.disable(); + mBluetoothAdapter.disable(); setResult(Activity.RESULT_OK); } break; } } /** - * Parse the received Intent and initialize mLocalBluetoothAdapter. + * Parse the received Intent and initialize mBluetoothAdapter. * @return true if an error occurred; false otherwise */ private boolean parseIntent() { @@ -167,16 +165,14 @@ public class RequestPermissionHelperActivity extends AlertActivity implements return false; } - LocalBluetoothManager manager = Utils.getLocalBtManager(this); - if (manager == null) { + mAppLabel = getIntent().getCharSequenceExtra(EXTRA_APP_LABEL); + + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (mBluetoothAdapter == null) { Log.e(TAG, "Error: there's a problem starting Bluetooth"); return false; } - mAppLabel = getIntent().getCharSequenceExtra(EXTRA_APP_LABEL); - - mLocalAdapter = manager.getBluetoothAdapter(); - return true; } } diff --git a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java index e5e1a7028ae..feb64b5f101 100644 --- a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java +++ b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java @@ -30,7 +30,6 @@ import com.android.settings.bluetooth.AlwaysDiscoverable; import com.android.settings.bluetooth.Utils; import com.android.settings.core.BasePreferenceController; import com.android.settings.dashboard.DashboardFragment; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; @@ -54,7 +53,7 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro LocalBluetoothManager mLocalManager; private FooterPreferenceMixinCompat mFooterPreferenceMixin; private FooterPreference mPreference; - private LocalBluetoothAdapter mLocalAdapter; + private BluetoothAdapter mBluetoothAdapter; private AlwaysDiscoverable mAlwaysDiscoverable; public DiscoverableFooterPreferenceController(Context context) { @@ -63,8 +62,8 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro if (mLocalManager == null) { return; } - mLocalAdapter = mLocalManager.getBluetoothAdapter(); - mAlwaysDiscoverable = new AlwaysDiscoverable(context, mLocalAdapter); + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + mAlwaysDiscoverable = new AlwaysDiscoverable(context); initReceiver(); } @@ -121,7 +120,7 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro mContext.registerReceiver(mBluetoothChangedReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); mAlwaysDiscoverable.start(); - updateFooterPreferenceTitle(mLocalAdapter.getState()); + updateFooterPreferenceTitle(mBluetoothAdapter.getState()); } @Override @@ -142,7 +141,7 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro } private CharSequence getPreferenceTitle() { - final String deviceName = mLocalAdapter.getName(); + final String deviceName = mBluetoothAdapter.getName(); if (TextUtils.isEmpty(deviceName)) { return null; } diff --git a/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java b/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java index 0d4df995058..a2623e3a9fc 100644 --- a/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java +++ b/src/com/android/settings/deviceinfo/DeviceNamePreferenceController.java @@ -16,7 +16,7 @@ package com.android.settings.deviceinfo; -import android.annotation.Nullable; +import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; @@ -29,8 +29,6 @@ import com.android.settings.bluetooth.BluetoothLengthDeviceNameFilter; import com.android.settings.core.BasePreferenceController; import com.android.settings.widget.ValidatedEditTextPreference; import com.android.settings.wifi.tether.WifiDeviceNameTextValidator; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; -import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnCreate; import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState; @@ -49,10 +47,9 @@ public class DeviceNamePreferenceController extends BasePreferenceController private static final String KEY_PENDING_DEVICE_NAME = "key_pending_device_name"; private String mDeviceName; protected WifiManager mWifiManager; + private final BluetoothAdapter mBluetoothAdapter; private final WifiDeviceNameTextValidator mWifiDeviceNameTextValidator; private ValidatedEditTextPreference mPreference; - @Nullable - private LocalBluetoothManager mBluetoothManager; private DeviceNamePreferenceHost mHost; private String mPendingDeviceName; @@ -61,6 +58,7 @@ public class DeviceNamePreferenceController extends BasePreferenceController mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); mWifiDeviceNameTextValidator = new WifiDeviceNameTextValidator(); + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); initializeDeviceName(); } @@ -115,10 +113,6 @@ public class DeviceNamePreferenceController extends BasePreferenceController return mWifiDeviceNameTextValidator.isTextValid(deviceName); } - public void setLocalBluetoothManager(LocalBluetoothManager localBluetoothManager) { - mBluetoothManager = localBluetoothManager; - } - public void confirmDeviceName() { if (mPendingDeviceName != null) { setDeviceName(mPendingDeviceName); @@ -146,14 +140,8 @@ public class DeviceNamePreferenceController extends BasePreferenceController } private void setBluetoothDeviceName(String deviceName) { - // Bluetooth manager doesn't exist for certain devices. - if (mBluetoothManager == null) { - return; - } - - final LocalBluetoothAdapter localBluetoothAdapter = mBluetoothManager.getBluetoothAdapter(); - if (localBluetoothAdapter != null) { - localBluetoothAdapter.setName(getFilteredBluetoothString(deviceName)); + if (mBluetoothAdapter != null) { + mBluetoothAdapter.setName(getFilteredBluetoothString(deviceName)); } } diff --git a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java index 976a2548d8b..668c58a8d61 100644 --- a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java +++ b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java @@ -16,8 +16,6 @@ package com.android.settings.deviceinfo.aboutphone; -import static com.android.settings.bluetooth.Utils.getLocalBtManager; - import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -116,7 +114,6 @@ public class MyDeviceInfoFragment extends DashboardFragment controllers.add(new BrandedAccountPreferenceController(context)); DeviceNamePreferenceController deviceNamePreferenceController = new DeviceNamePreferenceController(context); - deviceNamePreferenceController.setLocalBluetoothManager(getLocalBtManager(context)); deviceNamePreferenceController.setHost(fragment); if (lifecycle != null) { lifecycle.addObserver(deviceNamePreferenceController); diff --git a/src/com/android/settings/widget/SettingsAppWidgetProvider.java b/src/com/android/settings/widget/SettingsAppWidgetProvider.java index 74108aa20d1..b8730b995fa 100644 --- a/src/com/android/settings/widget/SettingsAppWidgetProvider.java +++ b/src/com/android/settings/widget/SettingsAppWidgetProvider.java @@ -40,9 +40,6 @@ import android.util.Log; import android.widget.RemoteViews; import com.android.settings.R; -import com.android.settings.bluetooth.Utils; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; -import com.android.settingslib.bluetooth.LocalBluetoothManager; /** * Provides control of power-related settings from a widget. @@ -54,7 +51,7 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { new ComponentName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider"); - private static LocalBluetoothAdapter sLocalBluetoothAdapter = null; + private static BluetoothAdapter sBluetoothAdapter = null; private static final int BUTTON_WIFI = 0; private static final int BUTTON_BRIGHTNESS = 1; @@ -450,23 +447,19 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { @Override public int getActualState(Context context) { - if (sLocalBluetoothAdapter == null) { - LocalBluetoothManager manager = Utils.getLocalBtManager(context); - if (manager == null) { - return STATE_UNKNOWN; // On emulator? - } - sLocalBluetoothAdapter = manager.getBluetoothAdapter(); - if (sLocalBluetoothAdapter == null) { + if (sBluetoothAdapter == null) { + sBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (sBluetoothAdapter == null) { return STATE_UNKNOWN; // On emulator? } } - return bluetoothStateToFiveState(sLocalBluetoothAdapter.getBluetoothState()); + return bluetoothStateToFiveState(sBluetoothAdapter.getState()); } @Override protected void requestStateChange(Context context, final boolean desiredState) { - if (sLocalBluetoothAdapter == null) { - Log.d(TAG, "No LocalBluetoothManager"); + if (sBluetoothAdapter == null) { + Log.d(TAG, "No BluetoothAdapter"); return; } // Actually request the Bluetooth change and persistent @@ -476,7 +469,11 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { new AsyncTask() { @Override protected Void doInBackground(Void... args) { - sLocalBluetoothAdapter.setBluetoothEnabled(desiredState); + if (desiredState) { + sBluetoothAdapter.enable(); + } else { + sBluetoothAdapter.disable(); + } return null; } }.execute(); diff --git a/tests/robotests/src/com/android/settings/bluetooth/AlwaysDiscoverableTest.java b/tests/robotests/src/com/android/settings/bluetooth/AlwaysDiscoverableTest.java index d9261c2ec64..1e323ef4db9 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/AlwaysDiscoverableTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/AlwaysDiscoverableTest.java @@ -17,41 +17,41 @@ package com.android.settings.bluetooth; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.content.Intent; import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; @RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = {ShadowBluetoothAdapter.class}) public class AlwaysDiscoverableTest { - @Mock - private LocalBluetoothAdapter mLocalAdapter; - @Mock private Context mContext; private AlwaysDiscoverable mAlwaysDiscoverable; + private BluetoothAdapter mBluetoothAdapter; + private ShadowBluetoothAdapter mShadowBluetoothAdapter; @Before public void setUp() { MockitoAnnotations.initMocks(this); - mAlwaysDiscoverable = new AlwaysDiscoverable(mContext, mLocalAdapter); + mAlwaysDiscoverable = new AlwaysDiscoverable(mContext); + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); } @Test @@ -76,14 +76,15 @@ public class AlwaysDiscoverableTest { public void stopWithoutStart() { mAlwaysDiscoverable.stop(); // expect no crash - verify(mLocalAdapter, never()).setScanMode(anyInt()); + mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE); } @Test public void startSetsModeAndRegistersReceiver() { - when(mLocalAdapter.getScanMode()).thenReturn(BluetoothAdapter.SCAN_MODE_NONE); + mShadowBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_NONE); mAlwaysDiscoverable.start(); - verify(mLocalAdapter).setScanMode(eq(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE)); + assertThat(mBluetoothAdapter.getScanMode()) + .isEqualTo(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); verify(mContext).registerReceiver(eq(mAlwaysDiscoverable), any()); } @@ -97,18 +98,18 @@ public class AlwaysDiscoverableTest { @Test public void resetsToDiscoverableModeWhenScanModeChanges() { mAlwaysDiscoverable.start(); - verify(mLocalAdapter, times(1)) - .setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); + assertThat(mBluetoothAdapter.getScanMode()) + .isEqualTo(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); sendScanModeChangedIntent(BluetoothAdapter.SCAN_MODE_CONNECTABLE, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); - verify(mLocalAdapter, times(2)) - .setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); + assertThat(mBluetoothAdapter.getScanMode()) + .isEqualTo(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); } private void sendScanModeChangedIntent(int newMode, int previousMode) { - when(mLocalAdapter.getScanMode()).thenReturn(newMode); + mShadowBluetoothAdapter.setScanMode(newMode); Intent intent = new Intent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, newMode); intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_SCAN_MODE, previousMode); diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java index dd5f27810b3..afce68efbac 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java @@ -24,22 +24,25 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.bluetooth.BluetoothAdapter; import android.content.Context; import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; @RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = {ShadowBluetoothAdapter.class}) public class BluetoothDeviceNamePreferenceControllerTest { private static final String DEVICE_NAME = "Nightshade"; @@ -48,8 +51,6 @@ public class BluetoothDeviceNamePreferenceControllerTest { private Context mContext; @Mock - private LocalBluetoothAdapter mLocalAdapter; - @Mock private PreferenceScreen mPreferenceScreen; private Preference mPreference; @@ -64,8 +65,7 @@ public class BluetoothDeviceNamePreferenceControllerTest { when(mPreferenceScreen.getContext()).thenReturn(mContext); mPreference = new Preference(mContext); mPreference.setKey(KEY_DEVICE_NAME); - mController = spy(new BluetoothDeviceNamePreferenceController(mContext, mLocalAdapter, - KEY_DEVICE_NAME)); + mController = spy(new BluetoothDeviceNamePreferenceController(mContext, KEY_DEVICE_NAME)); doReturn(DEVICE_NAME).when(mController).getDeviceName(); } diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java index 2b5c7e911bf..0fdfc526693 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java @@ -24,11 +24,11 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.bluetooth.BluetoothAdapter; import android.content.Context; import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; - +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -41,15 +41,16 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; @RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = {ShadowBluetoothAdapter.class}) public class BluetoothDeviceRenamePreferenceControllerTest { private static final String DEVICE_NAME = "Nightshade"; private static final String PREF_KEY = "bt_rename_devices"; - @Mock - private LocalBluetoothAdapter mLocalAdapter; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Fragment mFragment; @Mock @@ -59,6 +60,8 @@ public class BluetoothDeviceRenamePreferenceControllerTest { private Context mContext; private Preference mPreference; private BluetoothDeviceRenamePreferenceController mController; + private BluetoothAdapter mBluetoothAdapter; + private ShadowBluetoothAdapter mShadowBluetoothAdapter; @Before public void setUp() { @@ -67,9 +70,10 @@ public class BluetoothDeviceRenamePreferenceControllerTest { mContext = spy(RuntimeEnvironment.application); mPreference = new Preference(mContext); mPreference.setKey(PREF_KEY); + mBluetoothAdapter = ShadowBluetoothAdapter.getDefaultAdapter(); + mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); - mController = spy(new BluetoothDeviceRenamePreferenceController(mContext, mLocalAdapter, - PREF_KEY)); + mController = spy(new BluetoothDeviceRenamePreferenceController(mContext, PREF_KEY)); mController.setFragment(mFragment); doReturn(DEVICE_NAME).when(mController).getDeviceName(); when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); @@ -102,7 +106,7 @@ public class BluetoothDeviceRenamePreferenceControllerTest { @Test public void updatePreferenceState_whenBTisOnPreferenceShouldBeVisible() { - when(mLocalAdapter.isEnabled()).thenReturn(true); + mShadowBluetoothAdapter.setEnabled(true); mController.updatePreferenceState(mPreference); @@ -111,7 +115,7 @@ public class BluetoothDeviceRenamePreferenceControllerTest { @Test public void updatePreferenceState_whenBTisOffPreferenceShouldBeHide() { - when(mLocalAdapter.isEnabled()).thenReturn(false); + mShadowBluetoothAdapter.setEnabled(false); mController.updatePreferenceState(mPreference); diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java index 6936177c582..927f622b08e 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java @@ -35,13 +35,12 @@ import android.view.View; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.widget.SwitchBar; import com.android.settings.widget.SwitchBarController; import com.android.settings.widget.SwitchWidgetController; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.RestrictedSwitchPreference; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; -import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Before; @@ -53,11 +52,12 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import androidx.preference.PreferenceViewHolder; @RunWith(SettingsRobolectricTestRunner.class) -@Config(shadows = SettingsShadowResources.SettingsShadowTheme.class) +@Config(shadows = {SettingsShadowResources.SettingsShadowTheme.class, ShadowBluetoothAdapter.class}) public class BluetoothEnablerTest { private static EnforcedAdmin sFakeEnforcedAdmin; @@ -74,21 +74,17 @@ public class BluetoothEnablerTest { @Mock private RestrictionUtils mRestrictionUtils; @Mock - private LocalBluetoothManager mBluetoothManager; - @Mock - private LocalBluetoothAdapter mBluetoothAdapter; - @Mock private SwitchWidgetController.OnSwitchChangeListener mCallback; private Context mContext; private SwitchWidgetController mSwitchController; private BluetoothEnabler mBluetoothEnabler; + private ShadowBluetoothAdapter mShadowBluetoothAdapter; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); - when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mBluetoothAdapter); mRestrictedSwitchPreference = new RestrictedSwitchPreference(mContext); mSwitchController = spy(new SwitchBarController(new SwitchBar(mContext))); @@ -96,12 +92,12 @@ public class BluetoothEnablerTest { mContext, mSwitchController, mMetricsFeatureProvider, - mBluetoothManager, 123, mRestrictionUtils); mHolder = PreferenceViewHolder.createInstanceForTests(mock(View.class)); mRestrictedSwitchPreference.onBindViewHolder(mHolder); mBluetoothEnabler.setToggleCallback(mCallback); + mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); } @Test @@ -191,7 +187,7 @@ public class BluetoothEnablerTest { @Test public void startWithBluetoothOff_switchIsOff() { - when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_OFF); + mShadowBluetoothAdapter.setState(BluetoothAdapter.STATE_OFF); verify(mSwitchController, never()).setChecked(anyBoolean()); mBluetoothEnabler.resume(mContext); verify(mSwitchController, never()).setChecked(true); @@ -199,7 +195,7 @@ public class BluetoothEnablerTest { @Test public void startWithBluetoothOn_switchIsOn() { - when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON); + mShadowBluetoothAdapter.setState(BluetoothAdapter.STATE_ON); verify(mSwitchController, never()).setChecked(anyBoolean()); mBluetoothEnabler.resume(mContext); verify(mSwitchController, never()).setChecked(false); @@ -211,7 +207,7 @@ public class BluetoothEnablerTest { // Start up with bluetooth turned on. The switch should get turned on. ArgumentCaptor captor = ArgumentCaptor.forClass(BroadcastReceiver.class); when(mContext.registerReceiver(captor.capture(), any(IntentFilter.class))).thenReturn(null); - when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON); + mShadowBluetoothAdapter.setState(BluetoothAdapter.STATE_ON); verify(mSwitchController, never()).setChecked(anyBoolean()); mBluetoothEnabler.resume(mContext); verify(mSwitchController, never()).setChecked(false); @@ -235,7 +231,7 @@ public class BluetoothEnablerTest { // Start up with bluetooth turned on. The switch should be left off. ArgumentCaptor captor = ArgumentCaptor.forClass(BroadcastReceiver.class); when(mContext.registerReceiver(captor.capture(), any(IntentFilter.class))).thenReturn(null); - when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_OFF); + mShadowBluetoothAdapter.setState(BluetoothAdapter.STATE_OFF); verify(mSwitchController, never()).setChecked(anyBoolean()); mBluetoothEnabler.resume(mContext); verify(mSwitchController, never()).setChecked(anyBoolean()); diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java index a4b214185b8..649184350b3 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java @@ -33,8 +33,8 @@ import android.content.res.Resources; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settingslib.bluetooth.BluetoothDeviceFilter; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.widget.FooterPreference; @@ -45,16 +45,17 @@ import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import androidx.preference.PreferenceGroup; @RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = {ShadowBluetoothAdapter.class}) public class BluetoothPairingDetailTest { @Mock private Resources mResource; - @Mock - private LocalBluetoothAdapter mLocalAdapter; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private LocalBluetoothManager mLocalManager; @Mock @@ -63,6 +64,8 @@ public class BluetoothPairingDetailTest { private Context mContext; private BluetoothProgressCategory mAvailableDevicesCategory; private FooterPreference mFooterPreference; + private BluetoothAdapter mBluetoothAdapter; + private ShadowBluetoothAdapter mShadowBluetoothAdapter; @Before public void setUp() { @@ -75,11 +78,13 @@ public class BluetoothPairingDetailTest { mAvailableDevicesCategory = spy(new BluetoothProgressCategory(mContext)); mFooterPreference = new FooterPreference(mContext); + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); - mFragment.mLocalAdapter = mLocalAdapter; + mFragment.mBluetoothAdapter = mBluetoothAdapter; mFragment.mLocalManager = mLocalManager; mFragment.mDeviceListGroup = mPreferenceGroup; - mFragment.mAlwaysDiscoverable = new AlwaysDiscoverable(mContext, mLocalAdapter); + mFragment.mAlwaysDiscoverable = new AlwaysDiscoverable(mContext); } @Test @@ -102,7 +107,7 @@ public class BluetoothPairingDetailTest { mFragment.enableScanning(); - verify(mLocalAdapter).startScanning(true); + verify(mFragment).startScanning(); verify(mAvailableDevicesCategory).removeAll(); } @@ -117,7 +122,8 @@ public class BluetoothPairingDetailTest { verify(mFragment).addDeviceCategory(mAvailableDevicesCategory, R.string.bluetooth_preference_found_media_devices, BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER, false); - verify(mLocalAdapter).setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); + assertThat(mBluetoothAdapter.getScanMode()) + .isEqualTo(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); } @Test @@ -129,16 +135,16 @@ public class BluetoothPairingDetailTest { @Test public void testUpdateBluetooth_bluetoothOff_turnOnBluetooth() { - doReturn(false).when(mLocalAdapter).isEnabled(); + mShadowBluetoothAdapter.setEnabled(false); mFragment.updateBluetooth(); - verify(mLocalAdapter).enable(); + assertThat(mBluetoothAdapter.isEnabled()).isTrue(); } @Test public void testUpdateBluetooth_bluetoothOn_updateState() { - doReturn(true).when(mLocalAdapter).isEnabled(); + mShadowBluetoothAdapter.setEnabled(true); doNothing().when(mFragment).updateContent(anyInt()); mFragment.updateBluetooth(); @@ -157,27 +163,27 @@ public class BluetoothPairingDetailTest { mFragment.updateContent(BluetoothAdapter.STATE_ON); verify(mFragment).enableScanning(); assertThat(mAvailableDevicesCategory.getPreferenceCount()).isEqualTo(0); - verify(mLocalAdapter).startScanning(true); + verify(mFragment).startScanning(); // Subsequent scan started event will not trigger start/stop nor list clear mFragment.onScanningStateChanged(true); - verify(mLocalAdapter, times(1)).startScanning(anyBoolean()); + verify(mFragment, times(1)).startScanning(); verify(mAvailableDevicesCategory, times(1)).setProgress(true); // Subsequent scan finished event will trigger scan start without list clean mFragment.onScanningStateChanged(false); - verify(mLocalAdapter, times(2)).startScanning(true); + verify(mFragment, times(2)).startScanning(); verify(mAvailableDevicesCategory, times(2)).setProgress(true); // Subsequent scan started event will not trigger any change mFragment.onScanningStateChanged(true); - verify(mLocalAdapter, times(2)).startScanning(anyBoolean()); + verify(mFragment, times(2)).startScanning(); verify(mAvailableDevicesCategory, times(3)).setProgress(true); - verify(mLocalAdapter, never()).stopScanning(); + verify(mFragment, never()).stopScanning(); // Disable scanning will trigger scan stop mFragment.disableScanning(); - verify(mLocalAdapter, times(1)).stopScanning(); + verify(mFragment, times(1)).stopScanning(); // Subsequent scan start event will not trigger any change besides progress circle mFragment.onScanningStateChanged(true); @@ -187,8 +193,8 @@ public class BluetoothPairingDetailTest { // progress circle from spinning mFragment.onScanningStateChanged(false); verify(mAvailableDevicesCategory, times(1)).setProgress(false); - verify(mLocalAdapter, times(2)).startScanning(anyBoolean()); - verify(mLocalAdapter, times(1)).stopScanning(); + verify(mFragment, times(2)).startScanning(); + verify(mFragment, times(1)).stopScanning(); // Verify that clean up only happen once at initialization verify(mAvailableDevicesCategory, times(1)).removeAll(); diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSliceBuilderTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSliceBuilderTest.java index f85a58401c1..75361d71b97 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSliceBuilderTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSliceBuilderTest.java @@ -22,6 +22,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; +import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.content.Intent; import android.content.res.Resources; @@ -29,10 +30,7 @@ import android.content.res.Resources; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.SliceTester; -import com.android.settings.testutils.shadow.ShadowLocalBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowLocalBluetoothProfileManager; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; -import com.android.settingslib.bluetooth.LocalBluetoothManager; import org.junit.Before; import org.junit.Test; @@ -52,7 +50,7 @@ import androidx.slice.core.SliceAction; import androidx.slice.widget.SliceLiveData; @RunWith(SettingsRobolectricTestRunner.class) -@Config(shadows = {ShadowLocalBluetoothAdapter.class, ShadowLocalBluetoothProfileManager.class}) +@Config(shadows = {ShadowLocalBluetoothProfileManager.class}) public class BluetoothSliceBuilderTest { private Context mContext; @@ -90,11 +88,10 @@ public class BluetoothSliceBuilderTest { @Test public void handleUriChange_updatesBluetooth() { - final LocalBluetoothAdapter adapter = LocalBluetoothManager.getInstance(mContext, - null /* callback */).getBluetoothAdapter(); + final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); final Intent intent = new Intent(); intent.putExtra(android.app.slice.Slice.EXTRA_TOGGLE_STATE, true); - adapter.setBluetoothEnabled(false /* enabled */); + adapter.disable()/* enabled */; BluetoothSliceBuilder.handleUriChange(mContext, intent); diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSummaryUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSummaryUpdaterTest.java index 2ac1ed8fea2..2cab95bf7dd 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSummaryUpdaterTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSummaryUpdaterTest.java @@ -23,7 +23,6 @@ import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -31,8 +30,8 @@ import android.content.Context; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.bluetooth.LocalBluetoothManager; import org.junit.Before; @@ -42,11 +41,14 @@ import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import java.util.HashSet; import java.util.Set; @RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = {ShadowBluetoothAdapter.class}) public class BluetoothSummaryUpdaterTest { private static final String DEVICE_NAME = "Nightshade"; @@ -56,8 +58,6 @@ public class BluetoothSummaryUpdaterTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private LocalBluetoothManager mBluetoothManager; @Mock - private LocalBluetoothAdapter mBtAdapter; - @Mock private BluetoothDevice mConnectedDevice; @Mock private BluetoothDevice mConnectedKeyBoardDevice; @@ -72,16 +72,13 @@ public class BluetoothSummaryUpdaterTest { private final boolean[] mDeviceConnected = {false, false}; private final Set mBondedDevices = new HashSet<>(); private BluetoothSummaryUpdater mSummaryUpdater; + private ShadowBluetoothAdapter mShadowBluetoothAdapter; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application.getApplicationContext(); doCallRealMethod().when(mListener).onSummaryChanged(anyString()); - // Setup mock adapter - when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mBtAdapter); - doAnswer(invocation -> mAdapterEnabled[0]).when(mBtAdapter).isEnabled(); - doAnswer(invocation -> mAdapterConnectionState[0]).when(mBtAdapter).getConnectionState(); mSummaryUpdater = new BluetoothSummaryUpdater(mContext, mListener, mBluetoothManager); // Setup first device doReturn(DEVICE_NAME).when(mConnectedDevice).getName(); @@ -89,7 +86,11 @@ public class BluetoothSummaryUpdaterTest { // Setup second device doReturn(DEVICE_KEYBOARD_NAME).when(mConnectedKeyBoardDevice).getName(); doAnswer(invocation -> mDeviceConnected[1]).when(mConnectedKeyBoardDevice).isConnected(); - doReturn(mBondedDevices).when(mBtAdapter).getBondedDevices(); + // Setup BluetoothAdapter + mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); + mShadowBluetoothAdapter.setEnabled(mAdapterEnabled[0]); + mShadowBluetoothAdapter.setBondedDevices(mBondedDevices); + mShadowBluetoothAdapter.setConnectionState(mAdapterConnectionState[0]); } @Test @@ -108,9 +109,10 @@ public class BluetoothSummaryUpdaterTest { @Test public void register_true_shouldSendSummaryChange() { - mAdapterEnabled[0] = true; - mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; + mShadowBluetoothAdapter.setEnabled(true); + mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED); mBondedDevices.add(mConnectedDevice); + mShadowBluetoothAdapter.setBondedDevices(mBondedDevices); mDeviceConnected[0] = true; mSummaryUpdater.register(true); @@ -122,8 +124,9 @@ public class BluetoothSummaryUpdaterTest { @Test public void onBluetoothStateChanged_btDisabled_shouldSendDisabledSummary() { // These states should be ignored - mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; + mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED); mBondedDevices.add(mConnectedDevice); + mShadowBluetoothAdapter.setBondedDevices(mBondedDevices); mDeviceConnected[0] = true; mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF); @@ -133,9 +136,10 @@ public class BluetoothSummaryUpdaterTest { @Test public void onBluetoothStateChanged_btEnabled_connected_shouldSendConnectedSummary() { - mAdapterEnabled[0] = true; - mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; + mShadowBluetoothAdapter.setEnabled(true); + mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED); mBondedDevices.add(mConnectedDevice); + mShadowBluetoothAdapter.setBondedDevices(mBondedDevices); mDeviceConnected[0] = true; mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_ON); @@ -146,9 +150,10 @@ public class BluetoothSummaryUpdaterTest { @Test public void onBluetoothStateChanged_btEnabled_connectedMisMatch_shouldSendNotConnected() { - mAdapterEnabled[0] = true; - mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; + mShadowBluetoothAdapter.setEnabled(true); + mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED); mBondedDevices.add(mConnectedDevice); + mShadowBluetoothAdapter.setBondedDevices(mBondedDevices); // State mismatch mDeviceConnected[0] = false; @@ -159,9 +164,10 @@ public class BluetoothSummaryUpdaterTest { @Test public void onBluetoothStateChanged_btEnabled_notConnected_shouldSendDisconnectedMessage() { - mAdapterEnabled[0] = true; - mAdapterConnectionState[0] = BluetoothAdapter.STATE_DISCONNECTED; + mShadowBluetoothAdapter.setEnabled(true); + mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_DISCONNECTED); mBondedDevices.add(mConnectedDevice); + mShadowBluetoothAdapter.setBondedDevices(mBondedDevices); // This should be ignored mDeviceConnected[0] = true; @@ -172,22 +178,23 @@ public class BluetoothSummaryUpdaterTest { @Test public void onBluetoothStateChanged_ConnectedDisabledEnabled_shouldSendDisconnectedSummary() { - mAdapterEnabled[0] = true; - mAdapterConnectionState[0] = BluetoothAdapter.STATE_DISCONNECTED; + mShadowBluetoothAdapter.setEnabled(true); + mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_DISCONNECTED); mBondedDevices.add(mConnectedDevice); + mShadowBluetoothAdapter.setBondedDevices(mBondedDevices); mDeviceConnected[0] = false; mSummaryUpdater.register(true); verify(mListener).onSummaryChanged(mContext.getString(R.string.disconnected)); - mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; + mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED); mDeviceConnected[0] = true; mSummaryUpdater.onConnectionStateChanged(null /* device */, BluetoothAdapter.STATE_CONNECTED); verify(mListener).onSummaryChanged( mContext.getString(R.string.bluetooth_connected_summary, DEVICE_NAME)); - mAdapterEnabled[0] = false; + mShadowBluetoothAdapter.setEnabled(false); mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF); verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_disabled)); @@ -196,7 +203,7 @@ public class BluetoothSummaryUpdaterTest { // There should still be only one invocation of disabled message verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_disabled)); - mAdapterEnabled[0] = true; + mShadowBluetoothAdapter.setEnabled(true); mDeviceConnected[0] = false; mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_ON); verify(mListener, times(2)).onSummaryChanged(mContext.getString(R.string.disconnected)); @@ -205,9 +212,10 @@ public class BluetoothSummaryUpdaterTest { @Test public void onConnectionStateChanged_connected_shouldSendConnectedMessage() { - mAdapterEnabled[0] = true; - mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; + mShadowBluetoothAdapter.setEnabled(true); + mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED); mBondedDevices.add(mConnectedDevice); + mShadowBluetoothAdapter.setBondedDevices(mBondedDevices); mDeviceConnected[0] = true; mSummaryUpdater.onConnectionStateChanged(null /* device */, @@ -219,9 +227,10 @@ public class BluetoothSummaryUpdaterTest { @Test public void onConnectionStateChanged_inconsistentState_shouldSendDisconnectedMessage() { - mAdapterEnabled[0] = true; - mAdapterConnectionState[0] = BluetoothAdapter.STATE_DISCONNECTED; + mShadowBluetoothAdapter.setEnabled(true); + mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_DISCONNECTED); mBondedDevices.add(mConnectedDevice); + mShadowBluetoothAdapter.setBondedDevices(mBondedDevices); mDeviceConnected[0] = false; mSummaryUpdater.onConnectionStateChanged(null /* device */, @@ -232,8 +241,8 @@ public class BluetoothSummaryUpdaterTest { @Test public void onConnectionStateChanged_noBondedDevice_shouldSendDisconnectedMessage() { - mAdapterEnabled[0] = true; - mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; + mShadowBluetoothAdapter.setEnabled(true); + mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTED); mSummaryUpdater.onConnectionStateChanged(null /* device */, BluetoothAdapter.STATE_CONNECTED); @@ -244,8 +253,8 @@ public class BluetoothSummaryUpdaterTest { @Test public void onConnectionStateChanged_connecting_shouldSendConnectingMessage() { // No need for bonded devices - mAdapterEnabled[0] = true; - mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTING; + mShadowBluetoothAdapter.setEnabled(true); + mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_CONNECTING); mSummaryUpdater.onConnectionStateChanged(null /* device */, BluetoothAdapter.STATE_CONNECTING); @@ -256,8 +265,8 @@ public class BluetoothSummaryUpdaterTest { @Test public void onConnectionStateChanged_disconnecting_shouldSendDisconnectingMessage() { // No need for bonded devices - mAdapterEnabled[0] = true; - mAdapterConnectionState[0] = BluetoothAdapter.STATE_DISCONNECTING; + mShadowBluetoothAdapter.setEnabled(true); + mShadowBluetoothAdapter.setConnectionState(BluetoothAdapter.STATE_DISCONNECTING); mSummaryUpdater.onConnectionStateChanged(null /* device */, BluetoothAdapter.STATE_DISCONNECTING); @@ -268,6 +277,7 @@ public class BluetoothSummaryUpdaterTest { @Test public void getConnectedDeviceSummary_hasConnectedDevice_returnOneDeviceSummary() { mBondedDevices.add(mConnectedDevice); + mShadowBluetoothAdapter.setBondedDevices(mBondedDevices); mDeviceConnected[0] = true; final String expectedSummary = mContext.getString(R.string.bluetooth_connected_summary, DEVICE_NAME); @@ -279,6 +289,8 @@ public class BluetoothSummaryUpdaterTest { public void getConnectedDeviceSummary_multipleDevices_returnMultipleDevicesSummary() { mBondedDevices.add(mConnectedDevice); mBondedDevices.add(mConnectedKeyBoardDevice); + mShadowBluetoothAdapter.setBondedDevices(mBondedDevices); + mDeviceConnected[0] = true; mDeviceConnected[1] = true; final String expectedSummary = diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceControllerTest.java index 9f9aaf4ec3e..cca9ff0954b 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceControllerTest.java @@ -43,8 +43,6 @@ public class BluetoothSwitchPreferenceControllerTest { public static final String BLUETOOTH_INFO_STRING = "When Bluetooth is turned on, your device" + " can communicate with other nearby Bluetooth devices."; - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private LocalBluetoothManager mBluetoothManager; @Mock private RestrictionUtils mRestrictionUtils; @Mock @@ -62,7 +60,7 @@ public class BluetoothSwitchPreferenceControllerTest { FakeFeatureFactory.setupForTest(); mController = - new BluetoothSwitchPreferenceController(mContext, mBluetoothManager, mRestrictionUtils, + new BluetoothSwitchPreferenceController(mContext, mRestrictionUtils, mSwitchController, mFooterPreference); } diff --git a/tests/robotests/src/com/android/settings/bluetooth/DeviceListPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/DeviceListPreferenceFragmentTest.java index 7aacd38f672..c64b904a02a 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/DeviceListPreferenceFragmentTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/DeviceListPreferenceFragmentTest.java @@ -18,20 +18,20 @@ package com.android.settings.bluetooth; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.content.res.Resources; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settingslib.bluetooth.CachedBluetoothDevice; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.core.AbstractPreferenceController; import org.junit.Before; @@ -40,12 +40,14 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; import java.util.List; import androidx.preference.Preference; @RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = {ShadowBluetoothAdapter.class}) public class DeviceListPreferenceFragmentTest { private static final String FOOTAGE_MAC_STRING = "Bluetooth mac: xxxx"; @@ -54,8 +56,7 @@ public class DeviceListPreferenceFragmentTest { private Resources mResource; @Mock private Context mContext; - @Mock - private LocalBluetoothAdapter mLocalAdapter; + private TestFragment mFragment; private Preference mMyDevicePreference; @@ -66,7 +67,7 @@ public class DeviceListPreferenceFragmentTest { mFragment = spy(new TestFragment()); doReturn(mContext).when(mFragment).getContext(); doReturn(mResource).when(mFragment).getResources(); - mFragment.mLocalAdapter = mLocalAdapter; + mFragment.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); mMyDevicePreference = new Preference(RuntimeEnvironment.application); } @@ -84,11 +85,11 @@ public class DeviceListPreferenceFragmentTest { @Test public void testEnableDisableScanning_testStateAfterEanbleDisable() { mFragment.enableScanning(); - verify(mLocalAdapter).startScanning(true); + verify(mFragment).startScanning(); assertThat(mFragment.mScanEnabled).isTrue(); mFragment.disableScanning(); - verify(mLocalAdapter).stopScanning(); + verify(mFragment).stopScanning(); assertThat(mFragment.mScanEnabled).isFalse(); } @@ -96,21 +97,21 @@ public class DeviceListPreferenceFragmentTest { public void testScanningStateChanged_testScanStarted() { mFragment.enableScanning(); assertThat(mFragment.mScanEnabled).isTrue(); - verify(mLocalAdapter).startScanning(true); + verify(mFragment).startScanning(); mFragment.onScanningStateChanged(true); - verify(mLocalAdapter, times(1)).startScanning(anyBoolean()); + verify(mFragment, times(1)).startScanning(); } @Test public void testScanningStateChanged_testScanFinished() { // Could happen when last scanning not done while current scan gets enabled mFragment.enableScanning(); - verify(mLocalAdapter).startScanning(true); + verify(mFragment).startScanning(); assertThat(mFragment.mScanEnabled).isTrue(); mFragment.onScanningStateChanged(false); - verify(mLocalAdapter, times(2)).startScanning(true); + verify(mFragment, times(2)).startScanning(); } @Test @@ -118,53 +119,53 @@ public class DeviceListPreferenceFragmentTest { // Could happen when last scanning not done while current scan gets enabled mFragment.enableScanning(); assertThat(mFragment.mScanEnabled).isTrue(); - verify(mLocalAdapter).startScanning(true); + verify(mFragment).startScanning(); mFragment.onScanningStateChanged(true); - verify(mLocalAdapter, times(1)).startScanning(anyBoolean()); + verify(mFragment, times(1)).startScanning(); mFragment.onScanningStateChanged(false); - verify(mLocalAdapter, times(2)).startScanning(true); + verify(mFragment, times(2)).startScanning(); mFragment.onScanningStateChanged(true); - verify(mLocalAdapter, times(2)).startScanning(anyBoolean()); + verify(mFragment, times(2)).startScanning(); mFragment.disableScanning(); - verify(mLocalAdapter).stopScanning(); + verify(mFragment).stopScanning(); mFragment.onScanningStateChanged(false); - verify(mLocalAdapter, times(2)).startScanning(anyBoolean()); + verify(mFragment, times(2)).startScanning(); mFragment.onScanningStateChanged(true); - verify(mLocalAdapter, times(2)).startScanning(anyBoolean()); + verify(mFragment, times(2)).startScanning(); } @Test public void testScanningStateChanged_testScanFinishedAfterDisable() { mFragment.enableScanning(); - verify(mLocalAdapter).startScanning(true); + verify(mFragment).startScanning(); assertThat(mFragment.mScanEnabled).isTrue(); mFragment.disableScanning(); - verify(mLocalAdapter).stopScanning(); + verify(mFragment).stopScanning(); assertThat(mFragment.mScanEnabled).isFalse(); mFragment.onScanningStateChanged(false); - verify(mLocalAdapter, times(1)).startScanning(anyBoolean()); + verify(mFragment, times(1)).startScanning(); } @Test public void testScanningStateChanged_testScanStartedAfterDisable() { mFragment.enableScanning(); - verify(mLocalAdapter).startScanning(true); + verify(mFragment).startScanning(); assertThat(mFragment.mScanEnabled).isTrue(); mFragment.disableScanning(); - verify(mLocalAdapter).stopScanning(); + verify(mFragment).stopScanning(); assertThat(mFragment.mScanEnabled).isFalse(); mFragment.onScanningStateChanged(true); - verify(mLocalAdapter, times(1)).startScanning(anyBoolean()); + verify(mFragment, times(1)).startScanning(); } /** diff --git a/tests/robotests/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragmentTest.java index 25333414982..49d72fbd0ee 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragmentTest.java @@ -30,7 +30,6 @@ import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl; import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.testutils.FragmentTestUtils; @@ -50,10 +49,6 @@ import androidx.appcompat.app.AlertDialog; @Config(shadows = {ShadowAlertDialogCompat.class, SettingsShadowResourcesImpl.class}) public class LocalDeviceNameDialogFragmentTest { - @Mock - private LocalBluetoothManager mManager; - @Mock - private LocalBluetoothAdapter mAdapter; @Mock private InputMethodManager mInputMethodManager; @@ -65,8 +60,6 @@ public class LocalDeviceNameDialogFragmentTest { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); doReturn(mInputMethodManager).when(mContext).getSystemService(Context.INPUT_METHOD_SERVICE); - ReflectionHelpers.setStaticField(LocalBluetoothManager.class, "sInstance", mManager); - when(mManager.getBluetoothAdapter()).thenReturn(mAdapter); mFragment = spy(LocalDeviceNameDialogFragment.newInstance()); when(mFragment.getContext()).thenReturn(mContext); diff --git a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java index 4c7cd517a10..e6ef2d9d3c1 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java @@ -35,7 +35,6 @@ import com.android.settings.core.BasePreferenceController; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowBluetoothPan; -import com.android.settings.testutils.shadow.ShadowLocalBluetoothAdapter; import com.android.settingslib.widget.FooterPreference; import com.android.settingslib.widget.FooterPreferenceMixinCompat; @@ -47,6 +46,7 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowApplication; import java.util.ArrayList; @@ -55,8 +55,7 @@ import java.util.List; import androidx.preference.PreferenceScreen; @RunWith(SettingsRobolectricTestRunner.class) -@Config(shadows = {ShadowBluetoothPan.class, ShadowBluetoothAdapter.class, - ShadowLocalBluetoothAdapter.class}) +@Config(shadows = {ShadowBluetoothPan.class, ShadowBluetoothAdapter.class}) public class DiscoverableFooterPreferenceControllerTest { private static final String DEVICE_NAME = "device name"; private static final String KEY = "discoverable_footer_preference"; @@ -75,6 +74,7 @@ public class DiscoverableFooterPreferenceControllerTest { private DiscoverableFooterPreferenceController mDiscoverableFooterPreferenceController; private BroadcastReceiver mBluetoothChangedReceiver; private ShadowApplication mShadowApplication; + private ShadowBluetoothAdapter mShadowBluetoothAdapter; @Before public void setUp() { @@ -90,6 +90,7 @@ public class DiscoverableFooterPreferenceControllerTest { mAlwaysDiscoverable); mBluetoothChangedReceiver = mDiscoverableFooterPreferenceController .mBluetoothChangedReceiver; + mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); } @Test @@ -135,7 +136,7 @@ public class DiscoverableFooterPreferenceControllerTest { @Test public void onBluetoothStateChanged_bluetoothOn_updateTitle() { - ShadowLocalBluetoothAdapter.setName(DEVICE_NAME); + mShadowBluetoothAdapter.setName(DEVICE_NAME); sendBluetoothStateChangedIntent(BluetoothAdapter.STATE_ON); assertThat(mPreference.getTitle()).isEqualTo(generateTitle(DEVICE_NAME)); @@ -143,7 +144,7 @@ public class DiscoverableFooterPreferenceControllerTest { @Test public void onBluetoothStateChanged_bluetoothOff_updateTitle(){ - ShadowLocalBluetoothAdapter.setName(DEVICE_NAME); + mShadowBluetoothAdapter.setName(DEVICE_NAME); sendBluetoothStateChangedIntent(BluetoothAdapter.STATE_OFF); assertThat(mPreference.getTitle()).isEqualTo(generateTitle(null)); diff --git a/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java index 0e6bf8d3229..4268d94dcac 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/DeviceNamePreferenceControllerTest.java @@ -18,11 +18,10 @@ package com.android.settings.deviceinfo; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; @@ -30,29 +29,25 @@ import android.os.Build; import android.provider.Settings; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.widget.ValidatedEditTextPreference; -import com.android.settingslib.bluetooth.LocalBluetoothAdapter; -import com.android.settingslib.bluetooth.LocalBluetoothManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Answers; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplication; import androidx.preference.PreferenceScreen; @RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = {ShadowBluetoothAdapter.class}) public class DeviceNamePreferenceControllerTest { private static final String TESTING_STRING = "Testing"; - @Mock - private LocalBluetoothAdapter mBluetoothAdapter; - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private LocalBluetoothManager mBluetoothManager; @Mock private WifiManager mWifiManager; @Mock @@ -60,6 +55,7 @@ public class DeviceNamePreferenceControllerTest { private ValidatedEditTextPreference mPreference; private DeviceNamePreferenceController mController; private Context mContext; + private BluetoothAdapter mBluetoothAdapter; @Before @@ -69,14 +65,13 @@ public class DeviceNamePreferenceControllerTest { shadowApplication.setSystemService(Context.WIFI_SERVICE, mWifiManager); mContext = shadowApplication.getApplicationContext(); mPreference = new ValidatedEditTextPreference(mContext); - when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mBluetoothAdapter); when(mScreen.findPreference(anyString())).thenReturn(mPreference); final WifiConfiguration configuration = new WifiConfiguration(); configuration.SSID = "test-ap"; when(mWifiManager.getWifiApConfiguration()).thenReturn(configuration); mController = new DeviceNamePreferenceController(mContext); - mController.setLocalBluetoothManager(mBluetoothManager); + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } @Test @@ -89,7 +84,6 @@ public class DeviceNamePreferenceControllerTest { Settings.Global.putString( mContext.getContentResolver(), Settings.Global.DEVICE_NAME, "Test"); mController = new DeviceNamePreferenceController(mContext); - mController.setLocalBluetoothManager(mBluetoothManager); assertThat(mController.getSummary()).isEqualTo("Test"); } @@ -118,7 +112,7 @@ public class DeviceNamePreferenceControllerTest { mController.displayPreference(mScreen); mController.onPreferenceChange(mPreference, TESTING_STRING); - verify(mBluetoothAdapter).setName(eq(TESTING_STRING)); + assertThat(mBluetoothAdapter.getName()).isEqualTo(TESTING_STRING); } @Test @@ -141,10 +135,11 @@ public class DeviceNamePreferenceControllerTest { @Test public void setDeviceName_ignoresIfCancelPressed() { + forceAcceptDeviceName(); mController.displayPreference(mScreen); mController.onPreferenceChange(mPreference, TESTING_STRING); - verify(mBluetoothAdapter, never()).setName(eq(TESTING_STRING)); + assertThat(mBluetoothAdapter.getName()).isEqualTo(TESTING_STRING); } private void forceAcceptDeviceName() { diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java index 2bd2ec33aaa..91afb87021f 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java @@ -26,6 +26,11 @@ import java.util.List; @Implements(value = BluetoothAdapter.class, inheritImplementationMethods = true) public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBluetoothAdapter { + + private String mName; + private int mScanMode; + private int mState; + /** * Do nothing, implement it to avoid null pointer error inside BluetoothAdapter */ @@ -33,4 +38,32 @@ public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBlueto public List getSupportedProfiles() { return new ArrayList(); } + + public void setName(String name) { + mName = name; + } + + @Implementation + public String getName() { + return mName; + } + + @Implementation + public void setScanMode(int scanMode) { + mScanMode = scanMode; + } + + @Implementation + public int getScanMode() { + return mScanMode; + } + + @Implementation + public int getConnectionState() { + return mState; + } + + public void setConnectionState(int state) { + mState = state; + } } From 6f980feeba69bb50fc4ababf27eff602e9f4d37b Mon Sep 17 00:00:00 2001 From: tmfang Date: Tue, 31 Jul 2018 14:20:12 +0800 Subject: [PATCH 5/6] Unable to send files over Bluetooth OPP DevicPickerActivity switches to an androidx fragment in layout of bluetooth_device_picker. But android.app.Activity doesn't support androidx fragment. So, let DevicePiackerActivity extend androidx FragmentActivity. Change-Id: I5da98a5e2242b75d2205a786bf373b81dfe6f613 Fixes: 112010509 Test: manual test, robo test --- src/com/android/settings/bluetooth/DevicePickerActivity.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/bluetooth/DevicePickerActivity.java b/src/com/android/settings/bluetooth/DevicePickerActivity.java index 43ba05d8812..5228cd89ef2 100644 --- a/src/com/android/settings/bluetooth/DevicePickerActivity.java +++ b/src/com/android/settings/bluetooth/DevicePickerActivity.java @@ -16,16 +16,17 @@ package com.android.settings.bluetooth; -import android.app.Activity; import android.os.Bundle; import com.android.settings.R; +import androidx.fragment.app.FragmentActivity; + /** * Activity for Bluetooth device picker dialog. The device picker logic * is implemented in the {@link BluetoothPairingDetail} fragment. */ -public final class DevicePickerActivity extends Activity { +public final class DevicePickerActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { From 4b5cbca5c855b591b68e8bb36c04e75d85d330b8 Mon Sep 17 00:00:00 2001 From: tmfang Date: Tue, 31 Jul 2018 16:24:57 +0800 Subject: [PATCH 6/6] Fix windows leaked in ZenModeScheduleRuleSettings ZenModeScheduleRuleSettings creates an DaysDialog when user clicked Days option. If Activity was destroyed suddenly, WindowsManager throws a windows leaked exception. And then DaysDialog try to do something(dismiss), settings app will crash. So, we need to dismiss dialog when activity was destroyed. Test: robo test, change code to recover symptom, manual test Change-Id: I8d5370fe9673573581d613da91c7ab9be55d8199 Fixes: 111841375 --- .../ZenModeScheduleRuleSettings.java | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java index 3cfd13d1540..1769871fa13 100644 --- a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java +++ b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java @@ -63,6 +63,7 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase { private TimePickerPreference mStart; private TimePickerPreference mEnd; private SwitchPreference mExitAtAlarm; + private AlertDialog mDayDialog; private ScheduleInfo mSchedule; @@ -195,7 +196,6 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase { updateEndSummary(); } - @Override protected List createPreferenceControllers(Context context) { List controllers = new ArrayList<>(); @@ -214,18 +214,27 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase { return MetricsEvent.NOTIFICATION_ZEN_MODE_SCHEDULE_RULE; } + @Override + public void onDestroy() { + super.onDestroy(); + if (mDayDialog != null && mDayDialog.isShowing()) { + mDayDialog.dismiss(); + mDayDialog = null; + } + } + private void showDaysDialog() { - new AlertDialog.Builder(mContext) + mDayDialog = new AlertDialog.Builder(mContext) .setTitle(R.string.zen_mode_schedule_rule_days) .setView(new ZenModeScheduleDaysSelection(mContext, mSchedule.days) { - @Override - protected void onChanged(final int[] days) { - if (mDisableListeners) return; - if (Arrays.equals(days, mSchedule.days)) return; - if (DEBUG) Log.d(TAG, "days.onChanged days=" + Arrays.asList(days)); - mSchedule.days = days; - updateRule(ZenModeConfig.toScheduleConditionId(mSchedule)); - } + @Override + protected void onChanged(final int[] days) { + if (mDisableListeners) return; + if (Arrays.equals(days, mSchedule.days)) return; + if (DEBUG) Log.d(TAG, "days.onChanged days=" + Arrays.asList(days)); + mSchedule.days = days; + updateRule(ZenModeConfig.toScheduleConditionId(mSchedule)); + } }) .setOnDismissListener(new OnDismissListener() { @Override @@ -249,7 +258,7 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase { super(context); mContext = context; setPersistent(false); - setOnPreferenceClickListener(new OnPreferenceClickListener(){ + setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { final TimePickerFragment frag = new TimePickerFragment();