Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14b1831f authored by Chelsea Hao's avatar Chelsea Hao Committed by Android (Google) Code Review
Browse files

Merge "Remove flag, use new api for auto on in settings." into main

parents f0917545 74f65ed3
Loading
Loading
Loading
Loading
+61 −55
Original line number Diff line number Diff line
@@ -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,27 +27,33 @@ 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)) {
    @VisibleForTesting BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    private final LocalBluetoothManager mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
    private boolean mAutoOnValue = false;
    @Nullable private TwoStatePreference mPreference;

    public BluetoothAutoOnPreferenceController(
            @NonNull Context context, @NonNull String preferenceKey) {
        super(context, preferenceKey);
    }

    @Override
                public void onChange(boolean selfChange) {
    public void onAutoOnStateChanged(int state) {
        var unused =
                ThreadUtils.postOnBackgroundThread(
                        () -> {
                            Log.i(TAG, "onAutoOnStateChanged() state: " + state);
                            updateValue();
                            mContext.getMainExecutor()
                                    .execute(
@@ -61,36 +64,39 @@ public class BluetoothAutoOnPreferenceController extends TogglePreferenceControl
                                            });
                        });
    }
            };
    private int mAutoOnValue = UNSET;
    @Nullable private TwoStatePreference mPreference;

    public BluetoothAutoOnPreferenceController(
            @NonNull Context context, @NonNull String preferenceKey) {
        super(context, preferenceKey);
    }

    @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);
        }
    }
}
+13 −10
Original line number Diff line number Diff line
@@ -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;
    }
}
+9 −29
Original line number Diff line number Diff line
@@ -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);
    }
}