diff --git a/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceController.java index f6f62e8ffd8..3aca85e7118 100644 --- a/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceController.java +++ b/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceController.java @@ -16,11 +16,8 @@ package com.android.settings.bluetooth; +import android.bluetooth.BluetoothAdapter; import android.content.Context; -import android.database.ContentObserver; -import android.os.Handler; -import android.os.UserHandle; -import android.provider.Settings; import android.util.Log; import androidx.annotation.NonNull; @@ -30,39 +27,20 @@ import androidx.preference.PreferenceScreen; import androidx.preference.TwoStatePreference; import com.android.settings.core.TogglePreferenceController; +import com.android.settingslib.bluetooth.BluetoothCallback; +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; -import com.android.settingslib.flags.Flags; import com.android.settingslib.utils.ThreadUtils; public class BluetoothAutoOnPreferenceController extends TogglePreferenceController - implements LifecycleObserver, OnStart, OnStop { - private static final String TAG = "BluetoothAutoOnPreferenceController"; + implements BluetoothCallback, LifecycleObserver, OnStart, OnStop { + private static final String TAG = "BluetoothAutoOnPrefCtlr"; @VisibleForTesting static final String PREF_KEY = "bluetooth_auto_on_settings_toggle"; - static final String SETTING_NAME = "bluetooth_automatic_turn_on"; - static final int UNSET = -1; - @VisibleForTesting static final int ENABLED = 1; - @VisibleForTesting static final int DISABLED = 0; - private final ContentObserver mContentObserver = - new ContentObserver(new Handler(/* async= */ true)) { - @Override - public void onChange(boolean selfChange) { - var unused = - ThreadUtils.postOnBackgroundThread( - () -> { - updateValue(); - mContext.getMainExecutor() - .execute( - () -> { - if (mPreference != null) { - updateState(mPreference); - } - }); - }); - } - }; - private int mAutoOnValue = UNSET; + @VisibleForTesting BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + private final LocalBluetoothManager mLocalBluetoothManager = Utils.getLocalBtManager(mContext); + private boolean mAutoOnValue = false; @Nullable private TwoStatePreference mPreference; public BluetoothAutoOnPreferenceController( @@ -70,27 +48,55 @@ public class BluetoothAutoOnPreferenceController extends TogglePreferenceControl super(context, preferenceKey); } + @Override + public void onAutoOnStateChanged(int state) { + var unused = + ThreadUtils.postOnBackgroundThread( + () -> { + Log.i(TAG, "onAutoOnStateChanged() state: " + state); + updateValue(); + mContext.getMainExecutor() + .execute( + () -> { + if (mPreference != null) { + updateState(mPreference); + } + }); + }); + } + @Override public void onStart() { - mContext.getContentResolver() - .registerContentObserver( - Settings.Secure.getUriFor(SETTING_NAME), - /* notifyForDescendants= */ false, - mContentObserver); + if (mLocalBluetoothManager == null) { + return; + } + mLocalBluetoothManager.getEventManager().registerCallback(this); } @Override public void onStop() { - mContext.getContentResolver().unregisterContentObserver(mContentObserver); + if (mLocalBluetoothManager == null) { + return; + } + mLocalBluetoothManager.getEventManager().unregisterCallback(this); } @Override public int getAvailabilityStatus() { - if (!Flags.bluetoothQsTileDialogAutoOnToggle()) { + if (mBluetoothAdapter == null) { + return UNSUPPORTED_ON_DEVICE; + } + try { + boolean isSupported = mBluetoothAdapter.isAutoOnSupported(); + Log.i(TAG, "getAvailabilityStatus() isSupported: " + isSupported); + if (isSupported) { + var unused = ThreadUtils.postOnBackgroundThread(this::updateValue); + } + return isSupported ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + } catch (Exception e) { + // Server could throw TimeoutException, InterruptedException or ExecutionException return UNSUPPORTED_ON_DEVICE; } - updateValue(); - return mAutoOnValue != UNSET ? AVAILABLE : UNSUPPORTED_ON_DEVICE; } @Override @@ -106,26 +112,20 @@ public class BluetoothAutoOnPreferenceController extends TogglePreferenceControl @Override public boolean isChecked() { - return mAutoOnValue == ENABLED; + return mAutoOnValue; } @Override public boolean setChecked(boolean isChecked) { - if (getAvailabilityStatus() != AVAILABLE) { - Log.w(TAG, "Trying to set toggle value while feature not available."); - return false; - } var unused = ThreadUtils.postOnBackgroundThread( () -> { - boolean updated = - Settings.Secure.putIntForUser( - mContext.getContentResolver(), - SETTING_NAME, - isChecked ? ENABLED : DISABLED, - UserHandle.myUserId()); - if (updated) { - updateValue(); + try { + mBluetoothAdapter.setAutoOnEnabled(isChecked); + } catch (Exception e) { + // Server could throw IllegalStateException, TimeoutException, + // InterruptedException or ExecutionException + Log.e(TAG, "Error calling setAutoOnEnabled()", e); } }); return true; @@ -137,8 +137,14 @@ public class BluetoothAutoOnPreferenceController extends TogglePreferenceControl } private void updateValue() { - mAutoOnValue = - Settings.Secure.getIntForUser( - mContext.getContentResolver(), SETTING_NAME, UNSET, UserHandle.myUserId()); + if (mBluetoothAdapter == null) { + return; + } + try { + mAutoOnValue = mBluetoothAdapter.isAutoOnEnabled(); + } catch (Exception e) { + // Server could throw TimeoutException, InterruptedException or ExecutionException + Log.e(TAG, "Error calling isAutoOnEnabled()", e); + } } } diff --git a/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java index ac5575803c1..fc8365d1777 100644 --- a/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java +++ b/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java @@ -15,13 +15,10 @@ */ package com.android.settings.bluetooth; -import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.SETTING_NAME; -import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.UNSET; - import android.app.settings.SettingsEnums; +import android.bluetooth.BluetoothAdapter; import android.content.Context; -import android.os.UserHandle; -import android.provider.Settings; +import android.util.Log; import android.view.View; import androidx.annotation.VisibleForTesting; @@ -34,7 +31,6 @@ import com.android.settings.widget.SwitchWidgetController; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; -import com.android.settingslib.flags.Flags; import com.android.settingslib.widget.FooterPreference; /** @@ -47,11 +43,13 @@ public class BluetoothSwitchPreferenceController OnStop, SwitchWidgetController.OnSwitchChangeListener, View.OnClickListener { + private static final String TAG = "BluetoothSwitchPrefCtrl"; private BluetoothEnabler mBluetoothEnabler; private RestrictionUtils mRestrictionUtils; private SwitchWidgetController mSwitch; private Context mContext; + private BluetoothAdapter mBluetoothAdapter; private FooterPreference mFooterPreference; private boolean mIsAlwaysDiscoverable; @@ -87,6 +85,7 @@ public class BluetoothSwitchPreferenceController mRestrictionUtils); mBluetoothEnabler.setToggleCallback(this); mAlwaysDiscoverable = new AlwaysDiscoverable(context); + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } @Override @@ -157,11 +156,15 @@ public class BluetoothSwitchPreferenceController } private boolean isAutoOnFeatureAvailable() { - if (!Flags.bluetoothQsTileDialogAutoOnToggle()) { + if (mBluetoothAdapter == null) { + return false; + } + try { + return mBluetoothAdapter.isAutoOnSupported(); + } catch (Exception e) { + // Server could throw TimeoutException, InterruptedException or ExecutionException + Log.e(TAG, "Error calling isAutoOnFeatureAvailable()", e); return false; } - return Settings.Secure.getIntForUser( - mContext.getContentResolver(), SETTING_NAME, UNSET, UserHandle.myUserId()) - != UNSET; } } diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceControllerTest.java index d82dcc43ac3..3980711b864 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceControllerTest.java @@ -16,82 +16,62 @@ package com.android.settings.bluetooth; -import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.DISABLED; -import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.ENABLED; import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.PREF_KEY; -import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.SETTING_NAME; -import static com.android.settings.bluetooth.BluetoothAutoOnPreferenceController.UNSET; import static com.android.settings.core.BasePreferenceController.AVAILABLE; import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; -import static com.android.settingslib.flags.Flags.FLAG_BLUETOOTH_QS_TILE_DIALOG_AUTO_ON_TOGGLE; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; +import android.bluetooth.BluetoothAdapter; import android.content.ContentResolver; import android.content.Context; -import android.platform.test.flag.junit.SetFlagsRule; -import android.provider.Settings; import androidx.test.core.app.ApplicationProvider; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; @RunWith(RobolectricTestRunner.class) public class BluetoothAutoOnPreferenceControllerTest { - @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private Context mContext; private ContentResolver mContentResolver; private BluetoothAutoOnPreferenceController mController; + private BluetoothAdapter mBluetoothAdapter; @Before public void setUp() { - mSetFlagsRule.enableFlags(FLAG_BLUETOOTH_QS_TILE_DIALOG_AUTO_ON_TOGGLE); mContext = spy(ApplicationProvider.getApplicationContext()); mContentResolver = mContext.getContentResolver(); mController = new BluetoothAutoOnPreferenceController(mContext, PREF_KEY); + mBluetoothAdapter = spy(BluetoothAdapter.getDefaultAdapter()); + mController.mBluetoothAdapter = mBluetoothAdapter; } @Test public void getAvailability_valueUnset_returnUnsupported() { - Settings.Secure.putInt(mContentResolver, SETTING_NAME, UNSET); + doReturn(false).when(mBluetoothAdapter).isAutoOnSupported(); assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); } @Test public void getAvailability_valueSet_returnAvailable() { - Settings.Secure.putInt(mContentResolver, SETTING_NAME, DISABLED); + doReturn(true).when(mBluetoothAdapter).isAutoOnSupported(); assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); } @Test public void isChecked_valueEnabled_returnTrue() { - Settings.Secure.putInt(mContentResolver, SETTING_NAME, ENABLED); + doReturn(true).when(mBluetoothAdapter).isAutoOnSupported(); + doReturn(true).when(mBluetoothAdapter).isAutoOnEnabled(); assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); assertThat(mController.isChecked()).isEqualTo(true); } - - @Test - public void setChecked_returnTrue() { - Settings.Secure.putInt(mContentResolver, SETTING_NAME, DISABLED); - - mController.setChecked(true); - assertThat(mController.isChecked()).isEqualTo(true); - } - - @Test - public void setChecked_returnFalse() { - Settings.Secure.putInt(mContentResolver, SETTING_NAME, ENABLED); - - mController.setChecked(false); - assertThat(mController.isChecked()).isEqualTo(false); - } }