Merge "Remove flag, use new api for auto on in settings." into main
diff --git a/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceController.java
index f6f62e8..3aca85e 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.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(
@@ -71,26 +49,54 @@
     }
 
     @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;
         }
-        updateValue();
-        return mAutoOnValue != UNSET ? AVAILABLE : 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;
+        }
     }
 
     @Override
@@ -106,26 +112,20 @@
 
     @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 @@
     }
 
     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 ac55758..fc8365d 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.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 @@
                 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 @@
                         mRestrictionUtils);
         mBluetoothEnabler.setToggleCallback(this);
         mAlwaysDiscoverable = new AlwaysDiscoverable(context);
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
     }
 
     @Override
@@ -157,11 +156,15 @@
     }
 
     private boolean isAutoOnFeatureAvailable() {
-        if (!Flags.bluetoothQsTileDialogAutoOnToggle()) {
+        if (mBluetoothAdapter == null) {
             return false;
         }
-        return Settings.Secure.getIntForUser(
-                        mContext.getContentResolver(), SETTING_NAME, UNSET, UserHandle.myUserId())
-                != UNSET;
+        try {
+            return mBluetoothAdapter.isAutoOnSupported();
+        } catch (Exception e) {
+            // Server could throw TimeoutException, InterruptedException or ExecutionException
+            Log.e(TAG, "Error calling isAutoOnFeatureAvailable()", e);
+            return false;
+        }
     }
 }
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothAutoOnPreferenceControllerTest.java
index d82dcc4..3980711 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);
-    }
 }