OSDN Git Service

Create BluetoothSwitchPreference
authorjackqdyulei <jackqdyulei@google.com>
Mon, 4 Dec 2017 21:57:31 +0000 (13:57 -0800)
committerjackqdyulei <jackqdyulei@google.com>
Mon, 11 Dec 2017 21:05:01 +0000 (13:05 -0800)
In the new design, bluetooth preference is not MasterSwitchPreference
any more. This cl creates BluetoothSwitchPreference while reuse the
BluetoothEnabler.

Future cl will remove the BluetoothMasterSwitchPreference when P
feature is finalized.

Bug: 69333961
Test: RunSettingsRoboTests
Change-Id: Ie1f934b4e93a6758a1b0cf83bb5098585a635c2a

res/values/strings.xml
res/xml/connected_devices_advanced.xml
src/com/android/settings/bluetooth/BluetoothMasterSwitchPreferenceController.java
src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java [new file with mode: 0644]
src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
tests/robotests/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceControllerTest.java [new file with mode: 0644]

index 7331d72..45aadf3 100644 (file)
     <string name="bluetooth_paired_device_title">Your devices</string>
     <!-- Title for pairing bluetooth device page [CHAR LIMIT=none] -->
     <string name="bluetooth_pairing_page_title">Pair new device</string>
+    <!-- Summary for bluetooth item in connection detail page -->
+    <string name="bluetooth_pref_summary">Allow device to pair and connect to bluetooth devices</string>
 
     <!-- Title for connected device group [CHAR LIMIT=none]-->
     <string name="connected_device_connected_title">Currently connected</string>
index 946151f..57a2580 100644 (file)
     android:key="connected_devices_screen"
     android:title="@string/connected_devices_dashboard_title">
 
-    <com.android.settings.widget.MasterSwitchPreference
-      android:key="toggle_bluetooth"
+    <SwitchPreference
+      android:key="toggle_bluetooth_switch"
       android:title="@string/bluetooth_settings_title"
       android:icon="@drawable/ic_settings_bluetooth"
+      android:summary="@string/bluetooth_pref_summary"
       android:order="-7"/>
 
     <SwitchPreference
index d1492e4..331907b 100644 (file)
@@ -38,6 +38,7 @@ import com.android.settingslib.core.lifecycle.events.OnResume;
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
 
+//TODO(b/69926683): remove this controller in Android P.
 public class BluetoothMasterSwitchPreferenceController extends AbstractPreferenceController
         implements PreferenceControllerMixin, OnSummaryChangeListener, LifecycleObserver, OnResume,
         OnPause, OnStart, OnStop {
diff --git a/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java
new file mode 100644 (file)
index 0000000..3482ee2
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2017 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.bluetooth;
+
+import android.content.Context;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.widget.SwitchWidgetController;
+import com.android.settingslib.RestrictedLockUtils;
+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;
+
+/**
+ * PreferenceController to update of bluetooth {@link SwitchPreference}. It will
+ *
+ * 1. Invoke the user toggle
+ * 2. Listen to the update from {@link LocalBluetoothManager}
+ */
+public class BluetoothSwitchPreferenceController extends TogglePreferenceController
+        implements LifecycleObserver, OnStart, OnStop {
+
+    public static final String KEY_TOGGLE_BLUETOOTH = "toggle_bluetooth_switch";
+
+    private LocalBluetoothManager mBluetoothManager;
+    private SwitchPreference mBtPreference;
+    private BluetoothEnabler mBluetoothEnabler;
+    private RestrictionUtils mRestrictionUtils;
+    @VisibleForTesting
+    LocalBluetoothAdapter mBluetoothAdapter;
+
+    public BluetoothSwitchPreferenceController(Context context) {
+        this(context, Utils.getLocalBtManager(context), new RestrictionUtils());
+    }
+
+    @VisibleForTesting
+    public BluetoothSwitchPreferenceController(Context context,
+            LocalBluetoothManager bluetoothManager, RestrictionUtils restrictionUtils) {
+        super(context, KEY_TOGGLE_BLUETOOTH);
+        mBluetoothManager = bluetoothManager;
+        mRestrictionUtils = restrictionUtils;
+
+        if (mBluetoothManager != null) {
+            mBluetoothAdapter = mBluetoothManager.getBluetoothAdapter();
+        }
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mBtPreference = (SwitchPreference) screen.findPreference(KEY_TOGGLE_BLUETOOTH);
+        mBluetoothEnabler = new BluetoothEnabler(mContext,
+                new SwitchController(mBtPreference),
+                FeatureFactory.getFactory(mContext).getMetricsFeatureProvider(), mBluetoothManager,
+                MetricsEvent.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE,
+                mRestrictionUtils);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return mBluetoothAdapter != null ? AVAILABLE : DISABLED_UNSUPPORTED;
+    }
+
+    @Override
+    public void onStart() {
+        mBluetoothEnabler.resume(mContext);
+    }
+
+    @Override
+    public void onStop() {
+        mBluetoothEnabler.pause();
+    }
+
+    @Override
+    public boolean isChecked() {
+        return mBluetoothAdapter != null ? mBluetoothAdapter.isEnabled() : false;
+    }
+
+    @Override
+    public void setChecked(boolean isChecked) {
+        if (mBluetoothAdapter != null) {
+            mBluetoothAdapter.setBluetoothEnabled(isChecked);
+        }
+    }
+
+    /**
+     * Control the switch inside {@link SwitchPreference}
+     */
+    @VisibleForTesting
+    class SwitchController extends SwitchWidgetController implements
+            Preference.OnPreferenceChangeListener {
+        private SwitchPreference mSwitchPreference;
+
+        public SwitchController(SwitchPreference switchPreference) {
+            mSwitchPreference = switchPreference;
+        }
+
+        @Override
+        public void updateTitle(boolean isChecked) {
+        }
+
+        @Override
+        public void startListening() {
+            mSwitchPreference.setOnPreferenceChangeListener(this);
+        }
+
+        @Override
+        public void stopListening() {
+            mSwitchPreference.setOnPreferenceChangeListener(null);
+        }
+
+        @Override
+        public void setChecked(boolean checked) {
+            mSwitchPreference.setChecked(checked);
+        }
+
+        @Override
+        public boolean isChecked() {
+            return mSwitchPreference.isChecked();
+        }
+
+        @Override
+        public void setEnabled(boolean enabled) {
+            mSwitchPreference.setEnabled(enabled);
+        }
+
+        @Override
+        public boolean onPreferenceChange(Preference preference, Object newValue) {
+            if (mListener != null) {
+                return mListener.onSwitchToggled((Boolean) newValue);
+            }
+            return false;
+        }
+
+        @Override
+        public void setDisabledByAdmin(RestrictedLockUtils.EnforcedAdmin admin) {
+            mBtPreference.setEnabled(admin == null);
+        }
+    }
+}
index ea93fef..a4f6e5c 100644 (file)
@@ -24,6 +24,7 @@ import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.bluetooth.BluetoothFilesPreferenceController;
 import com.android.settings.bluetooth.BluetoothMasterSwitchPreferenceController;
+import com.android.settings.bluetooth.BluetoothSwitchPreferenceController;
 import com.android.settings.bluetooth.Utils;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.deviceinfo.UsbBackend;
@@ -83,10 +84,8 @@ public class AdvancedConnectedDeviceDashboardFragment extends DashboardFragment
         mUsbPrefController = new UsbModePreferenceController(context, new UsbBackend(context));
         lifecycle.addObserver(mUsbPrefController);
         controllers.add(mUsbPrefController);
-        final BluetoothMasterSwitchPreferenceController bluetoothPreferenceController =
-                new BluetoothMasterSwitchPreferenceController(
-                        context, Utils.getLocalBtManager(context), this,
-                        (SettingsActivity) getActivity());
+        final BluetoothSwitchPreferenceController bluetoothPreferenceController =
+                new BluetoothSwitchPreferenceController(context);
         lifecycle.addObserver(bluetoothPreferenceController);
         controllers.add(bluetoothPreferenceController);
 
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceControllerTest.java
new file mode 100644 (file)
index 0000000..aa9d266
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2017 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.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+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.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class BluetoothSwitchPreferenceControllerTest {
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private LocalBluetoothManager mBluetoothManager;
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private SwitchPreference mPreference;
+    @Mock
+    private RestrictionUtils mRestrictionUtils;
+    @Mock
+    private LocalBluetoothAdapter mLocalBluetoothAdapter;
+
+    private Context mContext;
+    private BluetoothSwitchPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application.getApplicationContext());
+        FakeFeatureFactory.setupForTest();
+
+        mController = new BluetoothSwitchPreferenceController(
+                mContext, mBluetoothManager, mRestrictionUtils);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
+    }
+
+    @Test
+    public void testGetAvailabilityStatus_adapterNull_returnDisabled() {
+        mController.mBluetoothAdapter = null;
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.DISABLED_UNSUPPORTED);
+    }
+
+    @Test
+    public void testGetAvailabilityStatus_adapterExisted_returnAvailable() {
+        mController.mBluetoothAdapter = mLocalBluetoothAdapter;
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void testOnStart_shouldRegisterPreferenceChangeListener() {
+        mController.displayPreference(mScreen);
+        mController.onStart();
+
+        verify(mPreference).setOnPreferenceChangeListener(
+                any(BluetoothSwitchPreferenceController.SwitchController.class));
+    }
+
+    @Test
+    public void testOnStop_shouldRegisterPreferenceChangeListener() {
+        mController.displayPreference(mScreen);
+        mController.onStart();
+
+        mController.onStop();
+
+        verify(mPreference).setOnPreferenceChangeListener(null);
+    }
+
+    @Test
+    public void testIsChecked_adapterNull_returnFalse() {
+        mController.mBluetoothAdapter = null;
+
+        assertThat(mController.isChecked()).isFalse();
+    }
+
+    @Test
+    public void testIsChecked_adapterExisted_returnFromAdapter() {
+        mController.mBluetoothAdapter = mLocalBluetoothAdapter;
+        doReturn(true).when(mLocalBluetoothAdapter).isEnabled();
+
+        assertThat(mController.isChecked()).isTrue();
+    }
+
+    @Test
+    public void testSetChecked_adapterExisted() {
+        mController.mBluetoothAdapter = mLocalBluetoothAdapter;
+
+        mController.setChecked(true);
+
+        verify(mLocalBluetoothAdapter).setBluetoothEnabled(true);
+    }
+}