OSDN Git Service

Merge "Update bluetooth preference to take user to new screen" into pi-dev
authorTreeHugger Robot <treehugger-gerrit@google.com>
Fri, 13 Apr 2018 23:00:52 +0000 (23:00 +0000)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Fri, 13 Apr 2018 23:00:52 +0000 (23:00 +0000)
13 files changed:
res/values/strings.xml
res/xml/bluetooth_screen.xml [new file with mode: 0644]
res/xml/connected_devices.xml
src/com/android/settings/bluetooth/BluetoothEnabler.java
src/com/android/settings/bluetooth/BluetoothSwitchPreferenceController.java
src/com/android/settings/bluetooth/Utils.java
src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java [new file with mode: 0644]
src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
src/com/android/settings/search/SearchIndexableResourcesImpl.java
src/com/android/settings/utils/AnnotationSpan.java
tests/robotests/assets/grandfather_invalid_base_preference_controller_constructor
tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
tests/robotests/src/com/android/settings/bluetooth/BluetoothSwitchPreferenceControllerTest.java

index f1795a2..1dad1fb 100644 (file)
     <string name="bluetooth_advanced_titlebar">Advanced Bluetooth</string>
     <!-- Bluetooth settings. Text displayed when Bluetooth is off and device list is empty [CHAR LIMIT=50]-->
     <string name="bluetooth_empty_list_bluetooth_off">When Bluetooth is turned on, your device can communicate with other nearby Bluetooth devices.</string>
+    <!-- Bluetooth settings. Text displayed when Bluetooth is off and bluetooth scanning is turned on [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_scanning_on_info_message">When Bluetooth is turned on, your device can communicate with other nearby Bluetooth devices.\n\nTo improve device experience, apps and services can still scan for nearby devices at any time, even when Bluetooth is off. This can be used, for example, to improve location-based features and services. you can change this in <annotation id="link">scanning settings</annotation>.</string>
     <!-- Message to describe "BLE scan always available feature" when Bluetooth is off. The
       place-holders "LINK_BEGIN" and "LINK_END" must NOT be translated. They mark a link to bring
       the user to "scanning settings" screen. -->
     <string name="help_uri_wifi_calling" translatable="false"></string>
     <!-- url for the wifi scanning required dialog help page -->
     <string name="help_uri_wifi_scanning_required" translatable="false"></string>
+    <!-- url for the bluetooth toggle required dialog help page -->
+    <string name="help_uri_bluetooth_screen" translatable="false"></string>
 
     <!-- User account title [CHAR LIMIT=30] -->
     <string name="user_account_title">Account for content</string>
diff --git a/res/xml/bluetooth_screen.xml b/res/xml/bluetooth_screen.xml
new file mode 100644 (file)
index 0000000..ec25520
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:key="bluetooth_switchbar_screen"
+    android:title="@string/bluetooth_settings_title" />
\ No newline at end of file
index 030428f..390a33d 100644 (file)
         android:fragment="com.android.settings.connecteddevice.PreviouslyConnectedDeviceDashboardFragment"
         settings:allowDividerAbove="true"/>
 
-    <com.android.settingslib.RestrictedSwitchPreference
-        android:key="toggle_bluetooth_switch"
+    <Preference
+        android:fragment="com.android.settings.connecteddevice.BluetoothDashboardFragment"
+        android:key="bluetooth_settings"
         android:title="@string/bluetooth_settings_title"
         android:icon="@drawable/ic_settings_bluetooth"
-        android:summary="@string/bluetooth_pref_summary"
-        settings:controller="com.android.settings.bluetooth.BluetoothSwitchPreferenceController"
-        settings:userRestriction="no_bluetooth"
-        settings:platform_slice="true"/>
+        settings:allowDividerAbove="true"/>
 
     <SwitchPreference
         android:key="toggle_nfc"
index 0f294bd..c1bcf50 100644 (file)
@@ -47,6 +47,7 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh
     private final LocalBluetoothAdapter mLocalAdapter;
     private final IntentFilter mIntentFilter;
     private final RestrictionUtils mRestrictionUtils;
+    private SwitchWidgetController.OnSwitchChangeListener mCallback;
 
     private static final String EVENT_DATA_IS_BT_ON = "is_bluetooth_on";
     private static final int EVENT_UPDATE_INDEX = 0;
@@ -170,6 +171,7 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh
     @Override
     public boolean onSwitchToggled(boolean isChecked) {
         if (maybeEnforceRestrictions()) {
+            triggerParentPreferenceCallback(isChecked);
             return true;
         }
 
@@ -179,6 +181,7 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh
             Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
             // Reset switch to off
             mSwitchController.setChecked(false);
+            triggerParentPreferenceCallback(false);
             return false;
         }
 
@@ -193,14 +196,25 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh
                 mSwitchController.setChecked(false);
                 mSwitchController.setEnabled(true);
                 mSwitchController.updateTitle(false);
+                triggerParentPreferenceCallback(false);
                 return false;
             }
         }
         mSwitchController.setEnabled(false);
+        triggerParentPreferenceCallback(isChecked);
         return true;
     }
 
     /**
+     * Sets a callback back that this enabler will trigger in case the preference using the enabler
+     * still needed the callback on the SwitchController (which we now use).
+     * @param listener The listener with a callback to trigger.
+     */
+    public void setToggleCallback(SwitchWidgetController.OnSwitchChangeListener listener) {
+        mCallback = listener;
+    }
+
+    /**
      * Enforces user restrictions disallowing Bluetooth (or its configuration) if there are any.
      *
      * @return if there was any user restriction to enforce.
@@ -227,4 +241,11 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh
         return admin;
     }
 
+    // This triggers the callback which was manually set for this enabler since the enabler will
+    // take over the switch controller callback
+    private void triggerParentPreferenceCallback(boolean isChecked) {
+        if (mCallback != null) {
+            mCallback.onSwitchToggled(isChecked);
+        }
+    }
 }
index c0fa884..bbc90c4 100644 (file)
 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 android.view.View;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.R;
+import com.android.settings.core.SubSettingLauncher;
+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.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;
+import com.android.settingslib.widget.FooterPreference;
 
 /**
- * PreferenceController to update of bluetooth {@link SwitchPreference}. It will
- *
- * 1. Invoke the user toggle
- * 2. Listen to the update from {@link LocalBluetoothManager}
+ * PreferenceController to update of bluetooth state. All behavior except managing the footer text
+ * is delegated to the SwitchWidgetController it uses.
  */
-public class BluetoothSwitchPreferenceController extends TogglePreferenceController
-        implements LifecycleObserver, OnStart, OnStop {
+public class BluetoothSwitchPreferenceController
+        implements LifecycleObserver, OnStart, OnStop,
+        SwitchWidgetController.OnSwitchChangeListener, View.OnClickListener {
 
-    public static final String KEY_TOGGLE_BLUETOOTH = "toggle_bluetooth_switch";
+    @VisibleForTesting
+    LocalBluetoothAdapter mBluetoothAdapter;
 
     private LocalBluetoothManager mBluetoothManager;
-    private SwitchPreference mBtPreference;
     private BluetoothEnabler mBluetoothEnabler;
     private RestrictionUtils mRestrictionUtils;
-    @VisibleForTesting
-    LocalBluetoothAdapter mBluetoothAdapter;
+    private SwitchWidgetController mSwitch;
+    private Context mContext;
+    private FooterPreference mFooterPreference;
 
-    public BluetoothSwitchPreferenceController(Context context) {
-        this(context, Utils.getLocalBtManager(context), new RestrictionUtils());
+    public BluetoothSwitchPreferenceController(Context context,
+            SwitchWidgetController switchController,
+            FooterPreference footerPreference) {
+        this(context, Utils.getLocalBtManager(context), new RestrictionUtils(), switchController,
+                footerPreference);
     }
 
     @VisibleForTesting
     public BluetoothSwitchPreferenceController(Context context,
-            LocalBluetoothManager bluetoothManager, RestrictionUtils restrictionUtils) {
-        super(context, KEY_TOGGLE_BLUETOOTH);
+            LocalBluetoothManager bluetoothManager, RestrictionUtils restrictionUtils,
+            SwitchWidgetController switchController, FooterPreference footerPreference) {
         mBluetoothManager = bluetoothManager;
         mRestrictionUtils = restrictionUtils;
+        mSwitch = switchController;
+        mContext = context;
+        mFooterPreference = footerPreference;
+
+        mSwitch.setupView();
+        updateText(mSwitch.isChecked());
 
         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,
+        mBluetoothEnabler = new BluetoothEnabler(context,
+                switchController,
+                FeatureFactory.getFactory(context).getMetricsFeatureProvider(), mBluetoothManager,
                 MetricsEvent.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE,
                 mRestrictionUtils);
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        return mBluetoothAdapter != null ? AVAILABLE : DISABLED_UNSUPPORTED;
+        mBluetoothEnabler.setToggleCallback(this);
     }
 
     @Override
     public void onStart() {
         mBluetoothEnabler.resume(mContext);
+        if (mSwitch != null) {
+            updateText(mSwitch.isChecked());
+        }
     }
 
     @Override
@@ -93,70 +97,30 @@ public class BluetoothSwitchPreferenceController extends TogglePreferenceControl
     }
 
     @Override
-    public boolean isChecked() {
-        return mBluetoothAdapter != null ? mBluetoothAdapter.isEnabled() : false;
+    public boolean onSwitchToggled(boolean isChecked) {
+        updateText(isChecked);
+        return true;
     }
 
     @Override
-    public boolean setChecked(boolean isChecked) {
-        if (mBluetoothAdapter != null) {
-            mBluetoothAdapter.setBluetoothEnabled(isChecked);
-        }
-        return true;
+    public void onClick(View v) {
+        // send users to scanning settings if they click on the link in the summary text
+        new SubSettingLauncher(mContext)
+                .setDestination(ScanningSettings.class.getName())
+                .setSourceMetricsCategory(MetricsProto.MetricsEvent.BLUETOOTH_FRAGMENT)
+                .launch();
     }
 
-    /**
-     * Control the switch inside {@link SwitchPreference}
-     */
-    @VisibleForTesting
-    static 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) {
-            mSwitchPreference.setEnabled(admin == null);
+    @VisibleForTesting void updateText(boolean isChecked) {
+        if (!isChecked
+                && Utils.isBluetoothScanningEnabled(mContext)) {
+            AnnotationSpan.LinkInfo info = new AnnotationSpan.LinkInfo(
+                    AnnotationSpan.LinkInfo.DEFAULT_ANNOTATION, this);
+            CharSequence text = AnnotationSpan.linkify(
+                    mContext.getText(R.string.bluetooth_scanning_on_info_message), info);
+            mFooterPreference.setTitle(text);
+        } else {
+            mFooterPreference.setTitle(R.string.bluetooth_empty_list_bluetooth_off);
         }
     }
-}
+}
\ No newline at end of file
index d5d4e50..f5377f5 100755 (executable)
@@ -21,6 +21,7 @@ import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.provider.Settings;
 import android.support.annotation.VisibleForTesting;
 import android.widget.Toast;
 
@@ -142,4 +143,8 @@ public final class Utils {
         }
     };
 
+    public static boolean isBluetoothScanningEnabled(Context context) {
+        return Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0) == 1;
+    }
 }
diff --git a/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java b/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java
new file mode 100644 (file)
index 0000000..ec616c8
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * 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.connecteddevice;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.bluetooth.BluetoothSwitchPreferenceController;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.location.ScanningSettings;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.SearchIndexableRaw;
+import com.android.settings.widget.SwitchBar;
+import com.android.settings.widget.SwitchBarController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.FooterPreference;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Dedicated screen for allowing the user to toggle bluetooth which displays relevant information to
+ * the user based on related settings such as bluetooth scanning.
+ */
+public class BluetoothDashboardFragment extends DashboardFragment {
+
+    private static final String TAG = "BluetoothDashboardFrag";
+    public static final String KEY_BLUETOOTH_SCREEN = "bluetooth_switchbar_screen";
+
+    private FooterPreference mFooterPreference;
+    private SwitchBar mSwitchBar;
+    private BluetoothSwitchPreferenceController mController;
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsProto.MetricsEvent.BLUETOOTH_FRAGMENT;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    public int getHelpResource() {
+        return R.string.help_uri_bluetooth_screen;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.bluetooth_screen;
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mFooterPreference = mFooterPreferenceMixin.createFooterPreference();
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        SettingsActivity activity = (SettingsActivity) getActivity();
+        mSwitchBar = activity.getSwitchBar();
+        mController = new BluetoothSwitchPreferenceController(activity,
+                new SwitchBarController(mSwitchBar), mFooterPreference);
+        Lifecycle lifecycle = getLifecycle();
+        if (lifecycle != null) {
+            lifecycle.addObserver(mController);
+        }
+    }
+    /**
+     * For Search.
+     */
+    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider() {
+                @Override
+                public List<SearchIndexableRaw> getRawDataToIndex(Context context,
+                        boolean enabled) {
+                    final List<SearchIndexableRaw> result = new ArrayList<>();
+
+                    // Add the activity title
+                    SearchIndexableRaw data = new SearchIndexableRaw(context);
+                    data.title = context.getString(R.string.bluetooth_settings_title);
+                    data.screenTitle = context.getString(R.string.settings_label);
+                    data.keywords = context.getString(R.string.keywords_bluetooth_settings);
+                    data.intentTargetPackage = context.getPackageName();
+                    data.intentTargetClass = BluetoothDashboardFragment.class.getName();
+                    data.intentAction = new SubSettingLauncher(context)
+                            .setDestination(ScanningSettings.class.getName())
+                            .setSourceMetricsCategory(MetricsProto.MetricsEvent.BLUETOOTH_FRAGMENT)
+                            .toIntent()
+                            .getAction();
+                    data.key = KEY_BLUETOOTH_SCREEN;
+                    result.add(data);
+
+                    return result;
+                }
+
+                @Override
+                public List<String> getNonIndexableKeys(Context context) {
+                    final List<String> keys = super.getNonIndexableKeys(context);
+                    BluetoothManager manager =
+                            (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
+                    if (manager != null) {
+                        BluetoothAdapter adapter = manager.getAdapter();
+                        final int status = adapter != null
+                                ? TogglePreferenceController.AVAILABLE
+                                : TogglePreferenceController.DISABLED_UNSUPPORTED;
+                        if (status != TogglePreferenceController.AVAILABLE) {
+                            keys.add(KEY_BLUETOOTH_SCREEN);
+                        }
+                    }
+
+                    return keys;
+                }
+            };
+}
index 942fd7b..2b55ab1 100644 (file)
@@ -22,7 +22,6 @@ import android.support.annotation.VisibleForTesting;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.bluetooth.BluetoothSwitchPreferenceController;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.nfc.NfcPreferenceController;
@@ -77,13 +76,8 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment {
                 new NfcPreferenceController(context);
         controllers.add(nfcPreferenceController);
 
-        final BluetoothSwitchPreferenceController bluetoothPreferenceController =
-                new BluetoothSwitchPreferenceController(context);
-        controllers.add(bluetoothPreferenceController);
-
         if (lifecycle != null) {
             lifecycle.addObserver(nfcPreferenceController);
-            lifecycle.addObserver(bluetoothPreferenceController);
         }
 
         return controllers;
index 33bc2e0..3b58c64 100644 (file)
@@ -23,6 +23,7 @@ import com.android.settings.DisplaySettings;
 import com.android.settings.LegalSettings;
 import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
 import com.android.settings.connecteddevice.PreviouslyConnectedDeviceDashboardFragment;
+import com.android.settings.connecteddevice.BluetoothDashboardFragment;
 import com.android.settings.datausage.DataUsageSummaryLegacy;
 import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
 import com.android.settings.accessibility.AccessibilitySettings;
@@ -185,6 +186,7 @@ public class SearchIndexableResourcesImpl implements SearchIndexableResources {
         addIndex(VibrationSettings.class);
         addIndex(RecentLocationRequestSeeAllFragment.class);
         addIndex(PreviouslyConnectedDeviceDashboardFragment.class);
+        addIndex(BluetoothDashboardFragment.class);
     }
 
     @Override
index c70cba5..e6457da 100644 (file)
@@ -80,6 +80,7 @@ public class AnnotationSpan extends URLSpan {
      */
     public static class LinkInfo {
         private static final String TAG = "AnnotationSpan.LinkInfo";
+        public static final String DEFAULT_ANNOTATION = "link";
         private final String mAnnotation;
         private final Boolean mActionable;
         private final View.OnClickListener mListener;
index 85cf92b..7faa14a 100644 (file)
@@ -5,7 +5,6 @@ com.android.settings.applications.appinfo.AppMemoryPreferenceController
 com.android.settings.applications.appinfo.InstantAppButtonsPreferenceController
 com.android.settings.bluetooth.BluetoothDeviceNamePreferenceController
 com.android.settings.bluetooth.BluetoothDeviceRenamePreferenceController
-com.android.settings.bluetooth.BluetoothSwitchPreferenceController
 com.android.settings.connecteddevice.ConnectedDeviceGroupController
 com.android.settings.connecteddevice.SavedDeviceGroupController
 com.android.settings.datausage.DataUsageSummaryPreferenceController
index 3895d42..d9e4e6b 100644 (file)
@@ -37,9 +37,11 @@ import android.view.View;
 import android.widget.Switch;
 
 import com.android.settings.R;
-import com.android.settings.bluetooth.BluetoothSwitchPreferenceController.SwitchController;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
+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;
@@ -77,9 +79,11 @@ public class BluetoothEnablerTest {
     private LocalBluetoothManager mBluetoothManager;
     @Mock
     private LocalBluetoothAdapter mBluetoothAdapter;
+    @Mock
+    private SwitchWidgetController.OnSwitchChangeListener mCallback;
 
     private Context mContext;
-    private SwitchController mSwitchController;
+    private SwitchWidgetController mSwitchController;
     private BluetoothEnabler mBluetoothEnabler;
 
     @Before
@@ -89,7 +93,7 @@ public class BluetoothEnablerTest {
         when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mBluetoothAdapter);
 
         mRestrictedSwitchPreference = new RestrictedSwitchPreference(mContext);
-        mSwitchController = spy(new SwitchController(mRestrictedSwitchPreference));
+        mSwitchController = spy(new SwitchBarController(new SwitchBar(mContext)));
         mBluetoothEnabler = new BluetoothEnabler(
                 mContext,
                 mSwitchController,
@@ -99,6 +103,7 @@ public class BluetoothEnablerTest {
                 mRestrictionUtils);
         mHolder = PreferenceViewHolder.createInstanceForTests(mock(View.class));
         mRestrictedSwitchPreference.onBindViewHolder(mHolder);
+        mBluetoothEnabler.setToggleCallback(mCallback);
     }
 
     @Test
@@ -111,6 +116,15 @@ public class BluetoothEnablerTest {
     }
 
     @Test
+    public void onSwitchToggled_shouldTriggerCallback() {
+        // WHEN the switch is toggled...
+        mBluetoothEnabler.onSwitchToggled(false);
+
+        // THEN the callback is triggered
+        verify(mCallback).onSwitchToggled(false);
+    }
+
+    @Test
     public void maybeEnforceRestrictions_noRestrictions() {
         // GIVEN there are no restrictions set...
         when(mRestrictionUtils.checkIfRestrictionEnforced(any(Context.class), any(String.class)))
index a05859d..ccd57f5 100644 (file)
 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.ArgumentMatchers.eq;
 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 android.provider.Settings;
 
-import com.android.settings.core.BasePreferenceController;
+import com.android.settings.R;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settings.utils.AnnotationSpan;
+import com.android.settings.widget.SwitchWidgetController;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.widget.FooterPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -44,17 +44,16 @@ import org.robolectric.RuntimeEnvironment;
 @RunWith(SettingsRobolectricTestRunner.class)
 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 PreferenceScreen mScreen;
-    @Mock
-    private SwitchPreference mPreference;
-    @Mock
     private RestrictionUtils mRestrictionUtils;
     @Mock
-    private LocalBluetoothAdapter mLocalBluetoothAdapter;
+    private SwitchWidgetController mSwitchController;
 
+    private FooterPreference mFooterPreference;
     private Context mContext;
     private BluetoothSwitchPreferenceController mController;
 
@@ -62,70 +61,52 @@ public class BluetoothSwitchPreferenceControllerTest {
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = spy(RuntimeEnvironment.application.getApplicationContext());
+        mFooterPreference = new FooterPreference(mContext);
         FakeFeatureFactory.setupForTest();
 
         mController =
-            new BluetoothSwitchPreferenceController(mContext, mBluetoothManager, mRestrictionUtils);
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
-        when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
+            new BluetoothSwitchPreferenceController(mContext, mBluetoothManager, mRestrictionUtils,
+                    mSwitchController, mFooterPreference);
     }
 
     @Test
-    public void testGetAvailabilityStatus_adapterNull_returnDisabled() {
-        mController.mBluetoothAdapter = null;
-
-        assertThat(mController.getAvailabilityStatus())
-            .isEqualTo(BasePreferenceController.DISABLED_UNSUPPORTED);
+    public void updateText_bluetoothOffScanningOn() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 1);
+        mController.updateText(false);
+        AnnotationSpan.LinkInfo info = new AnnotationSpan.LinkInfo(
+                AnnotationSpan.LinkInfo.DEFAULT_ANNOTATION, mController);
+        CharSequence text = AnnotationSpan.linkify(
+                mContext.getText(R.string.bluetooth_scanning_on_info_message), info);
+
+        assertThat(mFooterPreference.getTitle()).isEqualTo(text);
     }
 
     @Test
-    public void testGetAvailabilityStatus_adapterExisted_returnAvailable() {
-        mController.mBluetoothAdapter = mLocalBluetoothAdapter;
+    public void updateText_bluetoothOffScanningOff() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0);
+        mController.updateText(false);
 
-        assertThat(mController.getAvailabilityStatus())
-            .isEqualTo(BasePreferenceController.AVAILABLE);
-    }
+        assertThat(mFooterPreference.getTitle()).isEqualTo(BLUETOOTH_INFO_STRING);
 
-    @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();
+    public void updateText_bluetoothOnScanningOff() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0);
+        mController.updateText(true);
 
-        mController.onStop();
-
-        verify(mPreference).setOnPreferenceChangeListener(null);
+        assertThat(mFooterPreference.getTitle()).isEqualTo(BLUETOOTH_INFO_STRING);
     }
 
     @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);
+    public void updateText_bluetoothOnScanningOn() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 1);
+        mController.updateText(true);
 
-        verify(mLocalBluetoothAdapter).setBluetoothEnabled(true);
+        assertThat(mFooterPreference.getTitle()).isEqualTo(BLUETOOTH_INFO_STRING);
     }
 }