From 7b9568c10d18f91e34a24fe9e11503bb1513b7e1 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Wed, 12 Jul 2017 10:18:54 -0700 Subject: [PATCH] UI refresh on bluetooth list page - xml layout clean up - add "Device name" preference, tapping will bring up rename dialog - Remove tap target from original device_name pref Merged-In: I6e9764dbb6c51f94be6d6a61d5a6401141407409 Change-Id: I9cb67cc557a9b932d7cf795a8d4a6fb5215c4365 Fix: 62890841 Fix: 62891178 Test: robotests --- res/layout/dialog_edittext.xml | 14 +-- res/xml/bluetooth_settings.xml | 24 +++-- ...uetoothDeviceNamePreferenceController.java | 33 ++----- ...toothDeviceRenamePreferenceController.java | 67 +++++++++++++ .../BluetoothNameDialogFragment.java | 4 + .../bluetooth/BluetoothPairingDetail.java | 2 +- .../settings/bluetooth/BluetoothSettings.java | 13 ++- ...othDeviceNamePreferenceControllerTest.java | 31 +------ ...hDeviceRenamePreferenceControllerTest.java | 93 +++++++++++++++++++ 9 files changed, 205 insertions(+), 76 deletions(-) create mode 100644 src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java diff --git a/res/layout/dialog_edittext.xml b/res/layout/dialog_edittext.xml index c534bf19dd0..22729b66ef2 100644 --- a/res/layout/dialog_edittext.xml +++ b/res/layout/dialog_edittext.xml @@ -4,9 +4,9 @@ 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. @@ -14,20 +14,20 @@ limitations under the License. --> - + android:paddingBottom="12dp"> + android:singleLine="true" /> diff --git a/res/xml/bluetooth_settings.xml b/res/xml/bluetooth_settings.xml index 1ab2b16ab33..86d6d01ee31 100644 --- a/res/xml/bluetooth_settings.xml +++ b/res/xml/bluetooth_settings.xml @@ -16,22 +16,28 @@ + android:key="device_name" /> + android:title="@string/bluetooth_paired_device_title" /> - + - + + + + + + + diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java index 7e826c8ab3e..bd771e70ca5 100644 --- a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java +++ b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java @@ -16,12 +16,12 @@ package com.android.settings.bluetooth; -import android.app.Fragment; import android.bluetooth.BluetoothAdapter; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.support.annotation.VisibleForTesting; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; import android.text.Spannable; @@ -30,7 +30,6 @@ import android.text.TextUtils; import android.text.style.ForegroundColorSpan; import android.util.Log; -import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.core.PreferenceController; import com.android.settingslib.bluetooth.LocalBluetoothAdapter; @@ -48,15 +47,15 @@ public class BluetoothDeviceNamePreferenceController extends PreferenceControlle private static final String TAG = "BluetoothNamePrefCtrl"; public static final String KEY_DEVICE_NAME = "device_name"; - private int mAccentColor; - private Fragment mFragment; + + private final int mAccentColor; + private LocalBluetoothManager mLocalManager; private LocalBluetoothAdapter mLocalAdapter; private Preference mPreference; - public BluetoothDeviceNamePreferenceController(Context context, Fragment fragment, - Lifecycle lifecycle) { - this(context, fragment, (LocalBluetoothAdapter) null); + public BluetoothDeviceNamePreferenceController(Context context, Lifecycle lifecycle) { + this(context, (LocalBluetoothAdapter) null); mLocalManager = Utils.getLocalBtManager(context); if (mLocalManager == null) { @@ -68,17 +67,16 @@ public class BluetoothDeviceNamePreferenceController extends PreferenceControlle } @VisibleForTesting - BluetoothDeviceNamePreferenceController(Context context, Fragment fragment, - LocalBluetoothAdapter localAdapter) { + BluetoothDeviceNamePreferenceController(Context context, LocalBluetoothAdapter localAdapter) { super(context); mAccentColor = com.android.settingslib.Utils.getColorAccent(context); - mFragment = fragment; mLocalAdapter = localAdapter; } @Override public void displayPreference(PreferenceScreen screen) { mPreference = screen.findPreference(KEY_DEVICE_NAME); + super.displayPreference(screen); } @Override @@ -107,22 +105,11 @@ public class BluetoothDeviceNamePreferenceController extends PreferenceControlle updateDeviceName(preference, mLocalAdapter.getName()); } - @Override - public boolean handlePreferenceTreeClick(Preference preference) { - if (KEY_DEVICE_NAME.equals(preference.getKey())) { - LocalDeviceNameDialogFragment.newInstance() - .show(mFragment.getFragmentManager(), LocalDeviceNameDialogFragment.TAG); - return true; - } - - return false; - } - /** * Create preference to show bluetooth device name * * @param screen to add the preference in - * @param order to decide position of the preference + * @param order to decide position of the preference * @return bluetooth preference that created in this method */ public Preference createBluetoothDeviceNamePreference(PreferenceScreen screen, int order) { @@ -140,7 +127,7 @@ public class BluetoothDeviceNamePreferenceController extends PreferenceControlle * @param preference to set the summary for * @param deviceName bluetooth device name to show in the summary */ - public void updateDeviceName(final Preference preference, final String deviceName) { + protected void updateDeviceName(final Preference preference, final String deviceName) { if (deviceName == null) { // TODO: show error message in preference subtitle return; diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java new file mode 100644 index 00000000000..6f9cf409945 --- /dev/null +++ b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java @@ -0,0 +1,67 @@ +/* + * 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.app.Fragment; +import android.content.Context; +import android.support.annotation.VisibleForTesting; +import android.support.v7.preference.Preference; + +import com.android.settingslib.bluetooth.LocalBluetoothAdapter; +import com.android.settingslib.core.lifecycle.Lifecycle; + +public class BluetoothDeviceRenamePreferenceController extends + BluetoothDeviceNamePreferenceController { + + public static final String PREF_KEY = "bt_rename_device"; + + private final Fragment mFragment; + + public BluetoothDeviceRenamePreferenceController(Context context, Fragment fragment, + Lifecycle lifecycle) { + super(context, lifecycle); + mFragment = fragment; + } + + @VisibleForTesting + BluetoothDeviceRenamePreferenceController(Context context, Fragment fragment, + LocalBluetoothAdapter localAdapter) { + super(context, localAdapter); + mFragment = fragment; + } + + @Override + public String getPreferenceKey() { + return PREF_KEY; + } + + @Override + protected void updateDeviceName(final Preference preference, final String deviceName) { + preference.setSummary(deviceName); + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + if (PREF_KEY.equals(preference.getKey())) { + LocalDeviceNameDialogFragment.newInstance() + .show(mFragment.getFragmentManager(), LocalDeviceNameDialogFragment.TAG); + return true; + } + + return false; + } +} diff --git a/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java b/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java index e415b47c1a8..25413fa6db5 100644 --- a/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java +++ b/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java @@ -24,6 +24,7 @@ import android.content.res.Configuration; import android.os.Bundle; import android.text.Editable; import android.text.InputFilter; +import android.text.TextUtils; import android.text.TextWatcher; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -111,6 +112,9 @@ abstract class BluetoothNameDialogFragment extends InstrumentedDialogFragment new Utf8ByteLengthFilter(BLUETOOTH_NAME_MAX_LENGTH_BYTES) }); mDeviceNameView.setText(deviceName); // set initial value before adding listener + if (!TextUtils.isEmpty(deviceName)) { + mDeviceNameView.setSelection(deviceName.length()); + } mDeviceNameView.addTextChangedListener(this); mDeviceNameView.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override diff --git a/src/com/android/settings/bluetooth/BluetoothPairingDetail.java b/src/com/android/settings/bluetooth/BluetoothPairingDetail.java index d7b86c5869c..2e7a7fb7e79 100644 --- a/src/com/android/settings/bluetooth/BluetoothPairingDetail.java +++ b/src/com/android/settings/bluetooth/BluetoothPairingDetail.java @@ -186,7 +186,7 @@ public class BluetoothPairingDetail extends DeviceListPreferenceFragment impleme protected List getPreferenceControllers(Context context) { List controllers = new ArrayList<>(); mDeviceNamePrefController = new BluetoothDeviceNamePreferenceController(context, - this, getLifecycle()); + getLifecycle()); controllers.add(mDeviceNamePrefController); return controllers; diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java index 85eb23ea056..a5019804fae 100644 --- a/src/com/android/settings/bluetooth/BluetoothSettings.java +++ b/src/com/android/settings/bluetooth/BluetoothSettings.java @@ -22,7 +22,6 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.ContentResolver; import android.content.Context; -import android.content.IntentFilter; import android.content.res.Resources; import android.os.Bundle; import android.os.SystemProperties; @@ -55,6 +54,8 @@ import com.android.settingslib.bluetooth.BluetoothDeviceFilter; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.widget.FooterPreference; import java.util.ArrayList; @@ -66,7 +67,6 @@ import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH; /** * BluetoothSettings is the Settings screen for Bluetooth configuration and * connection management. - * */ public class BluetoothSettings extends DeviceListPreferenceFragment implements Indexable { private static final String TAG = "BluetoothSettings"; @@ -87,7 +87,6 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I private SwitchBar mSwitchBar; - private final IntentFilter mIntentFilter; private BluetoothDeviceNamePreferenceController mDeviceNamePrefController; @VisibleForTesting BluetoothPairingPreferenceController mPairingPrefController; @@ -98,7 +97,6 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I public BluetoothSettings() { super(DISALLOW_CONFIG_BLUETOOTH); - mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED); } @Override @@ -356,14 +354,15 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I @Override protected List getPreferenceControllers(Context context) { - List controllers = new ArrayList<>(); - mDeviceNamePrefController = new BluetoothDeviceNamePreferenceController(context, - this, getLifecycle()); + final List controllers = new ArrayList<>(); + final Lifecycle lifecycle = getLifecycle(); + mDeviceNamePrefController = new BluetoothDeviceNamePreferenceController(context, lifecycle); mPairingPrefController = new BluetoothPairingPreferenceController(context, this, (SettingsActivity) getActivity()); controllers.add(mDeviceNamePrefController); controllers.add(mPairingPrefController); controllers.add(new BluetoothFilesPreferenceController(context)); + controllers.add(new BluetoothDeviceRenamePreferenceController(context, this, lifecycle)); return controllers; } diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java index 84bdfcf147e..41fe2c2e3ce 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceControllerTest.java @@ -17,33 +17,25 @@ package com.android.settings.bluetooth; import static com.google.common.truth.Truth.assertThat; - import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; 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.app.Fragment; -import android.app.FragmentManager; -import android.app.FragmentTransaction; import android.content.Context; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; -import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; +import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settingslib.bluetooth.LocalBluetoothAdapter; -import com.android.settingslib.core.lifecycle.Lifecycle; 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; @@ -56,17 +48,9 @@ public class BluetoothDeviceNamePreferenceControllerTest { private static final int ORDER = 1; private Context mContext; - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private Fragment mFragment; - @Mock - private Lifecycle mLifecycle; @Mock private LocalBluetoothAdapter mLocalAdapter; @Mock - private FragmentManager mFragmentManager; - @Mock - private FragmentTransaction mFragmentTransaction; - @Mock private PreferenceScreen mPreferenceScreen; private Preference mPreference; @@ -82,7 +66,7 @@ public class BluetoothDeviceNamePreferenceControllerTest { mPreference = new Preference(mContext); mPreference.setKey(BluetoothDeviceNamePreferenceController.KEY_DEVICE_NAME); mController = new BluetoothDeviceNamePreferenceController( - mContext, mFragment, mLocalAdapter); + mContext, mLocalAdapter); } @Test @@ -124,15 +108,4 @@ public class BluetoothDeviceNamePreferenceControllerTest { mController.onStop(); verify(mContext).unregisterReceiver(mController.mReceiver); } - - @Test - public void testHandlePreferenceTreeClick_startDialogFragment() { - when(mFragment.getFragmentManager().beginTransaction()).thenReturn(mFragmentTransaction); - - mController.handlePreferenceTreeClick(mPreference); - - verify(mFragmentTransaction).add(any(), anyString()); - verify(mFragmentTransaction).commit(); - } - } diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java new file mode 100644 index 00000000000..f0460960e83 --- /dev/null +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceControllerTest.java @@ -0,0 +1,93 @@ +/* + * 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.Matchers.anyString; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.Fragment; +import android.app.FragmentManager; +import android.app.FragmentTransaction; +import android.content.Context; +import android.support.v7.preference.Preference; + +import com.android.settings.TestConfig; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.bluetooth.LocalBluetoothAdapter; + +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 BluetoothDeviceRenamePreferenceControllerTest { + + private static final String DEVICE_NAME = "Nightshade"; + + @Mock + private LocalBluetoothAdapter mLocalAdapter; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Fragment mFragment; + @Mock + private FragmentManager mFragmentManager; + @Mock + private FragmentTransaction mFragmentTransaction; + private Context mContext; + private Preference mPreference; + private BluetoothDeviceRenamePreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mContext = spy(RuntimeEnvironment.application); + mPreference = new Preference(mContext); + mPreference.setKey(BluetoothDeviceRenamePreferenceController.PREF_KEY); + + mController = new BluetoothDeviceRenamePreferenceController( + mContext, mFragment, mLocalAdapter); + } + + @Test + public void testUpdateDeviceName_showSummaryWithDeviceName() { + mController.updateDeviceName(mPreference, DEVICE_NAME); + + final CharSequence summary = mPreference.getSummary(); + + assertThat(summary.toString()).isEqualTo(DEVICE_NAME); + } + + @Test + public void testHandlePreferenceTreeClick_startDialogFragment() { + when(mFragment.getFragmentManager().beginTransaction()).thenReturn(mFragmentTransaction); + + mController.handlePreferenceTreeClick(mPreference); + + verify(mFragmentTransaction).add(any(), anyString()); + verify(mFragmentTransaction).commit(); + } +}