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(); + } +}