Merge "Revert "Revert "Convert BT preference to use TwoTargetPreference""" into oc-dev

This commit is contained in:
TreeHugger Robot
2017-04-11 23:35:13 +00:00
committed by Android (Google) Code Review
8 changed files with 147 additions and 112 deletions

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2006 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<!-- Details button -->
<ImageView
android:id="@+id/deviceDetails"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="8dip"
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/ic_settings"
android:contentDescription="@string/bluetooth_device_details" />
</LinearLayout>

View File

@@ -35,7 +35,6 @@
android:id="@android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tint="?android:attr/textColorPrimary"
android:maxWidth="18dp"
android:maxHeight="18dp"/>
</LinearLayout>
@@ -47,7 +46,8 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="start|center"
android:textAppearance="@android:style/TextAppearance.Material.Body2"/>
android:textAppearance="@android:style/TextAppearance.Material.Body2"
android:textColor="?android:attr/colorAccent"/>
<ProgressBar
android:id="@+id/scanning_progress"

View File

@@ -30,14 +30,13 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.GearPreference;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.HidProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
@@ -50,15 +49,14 @@ import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
* BluetoothDevicePreference is the preference type used to display each remote
* Bluetooth device in the Bluetooth Settings screen.
*/
public final class BluetoothDevicePreference extends Preference implements
CachedBluetoothDevice.Callback, OnClickListener {
private static final String TAG = "BluetoothDevicePreference";
public final class BluetoothDevicePreference extends GearPreference implements
CachedBluetoothDevice.Callback {
private static final String TAG = "BluetoothDevicePref";
private static int sDimAlpha = Integer.MIN_VALUE;
private final CachedBluetoothDevice mCachedDevice;
private OnClickListener mOnSettingsClickListener;
private final UserManager mUserManager;
private AlertDialog mDisconnectDialog;
@@ -76,7 +74,8 @@ public final class BluetoothDevicePreference extends Preference implements
public final String BLUETOOTH = r.getString(R.string.bluetooth_talkback_bluetooth);
public BluetoothDevicePreference(Context context, CachedBluetoothDevice cachedDevice) {
super(context);
super(context, null);
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
if (sDimAlpha == Integer.MIN_VALUE) {
TypedValue outValue = new TypedValue();
@@ -85,14 +84,6 @@ public final class BluetoothDevicePreference extends Preference implements
}
mCachedDevice = cachedDevice;
if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
if (!um.hasUserRestriction(DISALLOW_CONFIG_BLUETOOTH)) {
setWidgetLayoutResource(R.layout.preference_bluetooth);
}
}
mCachedDevice.registerCallback(this);
onDeviceAttributesChanged();
@@ -102,12 +93,20 @@ public final class BluetoothDevicePreference extends Preference implements
notifyChanged();
}
CachedBluetoothDevice getCachedDevice() {
return mCachedDevice;
@Override
protected boolean shouldHideSecondTarget() {
return mCachedDevice == null
|| mCachedDevice.getBondState() != BluetoothDevice.BOND_BONDED
|| mUserManager.hasUserRestriction(DISALLOW_CONFIG_BLUETOOTH);
}
public void setOnSettingsClickListener(OnClickListener listener) {
mOnSettingsClickListener = listener;
@Override
protected int getSecondTargetResId() {
return R.layout.preference_widget_gear;
}
CachedBluetoothDevice getCachedDevice() {
return mCachedDevice;
}
@Override
@@ -120,6 +119,10 @@ public final class BluetoothDevicePreference extends Preference implements
}
}
public CachedBluetoothDevice getBluetoothDevice() {
return mCachedDevice;
}
public void onDeviceAttributesChanged() {
/*
* The preference framework takes care of making sure the value has
@@ -157,11 +160,10 @@ public final class BluetoothDevicePreference extends Preference implements
}
if (mCachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
ImageView deviceDetails = (ImageView) view.findViewById(R.id.deviceDetails);
ImageView deviceDetails = (ImageView) view.findViewById(R.id.settings_button);
if (deviceDetails != null) {
deviceDetails.setOnClickListener(this);
deviceDetails.setTag(mCachedDevice);
}
}
final ImageView imageView = (ImageView) view.findViewById(android.R.id.icon);
@@ -171,13 +173,6 @@ public final class BluetoothDevicePreference extends Preference implements
super.onBindViewHolder(view);
}
public void onClick(View v) {
// Should never be null by construction
if (mOnSettingsClickListener != null) {
mOnSettingsClickListener.onClick(v);
}
}
@Override
public boolean equals(Object o) {
if ((o == null) || !(o instanceof BluetoothDevicePreference)) {
@@ -207,19 +202,19 @@ public final class BluetoothDevicePreference extends Preference implements
int bondState = mCachedDevice.getBondState();
final MetricsFeatureProvider metricsFeatureProvider =
FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider();
FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider();
if (mCachedDevice.isConnected()) {
metricsFeatureProvider.action(getContext(),
MetricsEvent.ACTION_SETTINGS_BLUETOOTH_DISCONNECT);
MetricsEvent.ACTION_SETTINGS_BLUETOOTH_DISCONNECT);
askDisconnect();
} else if (bondState == BluetoothDevice.BOND_BONDED) {
metricsFeatureProvider.action(getContext(),
MetricsEvent.ACTION_SETTINGS_BLUETOOTH_CONNECT);
MetricsEvent.ACTION_SETTINGS_BLUETOOTH_CONNECT);
mCachedDevice.connect(true);
} else if (bondState == BluetoothDevice.BOND_NONE) {
metricsFeatureProvider.action(getContext(),
MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR);
MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR);
pair();
}
}
@@ -283,10 +278,10 @@ public final class BluetoothDevicePreference extends Preference implements
}
}
if (btClass != null) {
if (btClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) {
if (btClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) {
return new Pair<Integer, String>(R.drawable.ic_bt_headset_hfp, HEADSET);
}
if (btClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) {
if (btClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) {
return new Pair<Integer, String>(R.drawable.ic_bt_headphones_a2dp, HEADPHONE);
}
}

View File

@@ -45,13 +45,14 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.LinkifyUtils;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.location.ScanningSettings;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import com.android.settings.widget.FooterPreference;
import com.android.settings.widget.GearPreference;
import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener;
import com.android.settings.widget.SwitchBar;
import com.android.settings.widget.SwitchBarController;
import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
@@ -476,24 +477,25 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem
}
}
private final View.OnClickListener mDeviceProfilesListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// User clicked on advanced options icon for a device in the list
if (!(v.getTag() instanceof CachedBluetoothDevice)) {
Log.w(TAG, "onClick() called for other View: " + v);
return;
}
final CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
Bundle args = new Bundle();
args.putString(DeviceProfilesSettings.ARG_DEVICE_ADDRESS,
device.getDevice().getAddress());
DeviceProfilesSettings profileSettings = new DeviceProfilesSettings();
profileSettings.setArguments(args);
profileSettings.show(getFragmentManager(),
DeviceProfilesSettings.class.getSimpleName());
private final GearPreference.OnGearClickListener mDeviceProfilesListener = pref -> {
// User clicked on advanced options icon for a device in the list
if (!(pref instanceof BluetoothDevicePreference)) {
Log.w(TAG, "onClick() called for other View: " + pref);
return;
}
final CachedBluetoothDevice device =
((BluetoothDevicePreference) pref).getBluetoothDevice();
if (device == null) {
Log.w(TAG, "No BT device attached with this pref: " + pref);
return;
}
final Bundle args = new Bundle();
args.putString(DeviceProfilesSettings.ARG_DEVICE_ADDRESS,
device.getDevice().getAddress());
final DeviceProfilesSettings profileSettings = new DeviceProfilesSettings();
profileSettings.setArguments(args);
profileSettings.show(getFragmentManager(),
DeviceProfilesSettings.class.getSimpleName());
};
/**
@@ -506,7 +508,7 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem
CachedBluetoothDevice cachedDevice = preference.getCachedDevice();
if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
// Only paired device have an associated advanced settings screen
preference.setOnSettingsClickListener(mDeviceProfilesListener);
preference.setOnGearClickListener(mDeviceProfilesListener);
}
}

View File

@@ -61,11 +61,6 @@ public final class DevicePickerFragment extends DeviceListPreferenceFragment {
mLaunchClass = intent.getStringExtra(BluetoothDevicePicker.EXTRA_LAUNCH_CLASS);
}
@Override
void initDevicePreference(BluetoothDevicePreference preference) {
preference.setWidgetLayoutResource(R.layout.preference_empty_list);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.add(Menu.NONE, MENU_ID_REFRESH, 0, R.string.bluetooth_search_for_devices)

View File

@@ -0,0 +1,46 @@
/*
* 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.Instrumentation;
import android.content.Intent;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class DevicePickerActivityTest {
private Instrumentation mInstrumentation;
@Before
public void setUp() throws Exception {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
}
@Test
public void startActivityNoCrash() {
mInstrumentation.startActivitySync(
new Intent("android.bluetooth.devicepicker.action.LAUNCH"));
// No crash
}
}

View File

@@ -16,26 +16,11 @@
package com.android.settings.fuelgauge;
import static android.support.test.InstrumentationRegistry.getTargetContext;
import static android.support.test.espresso.Espresso.onData;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.intent.Intents.intended;
import static android.support.test.espresso.intent.Intents.intending;
import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent;
import static android.support.test.espresso.matcher.PreferenceMatchers.withKey;
import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.core.IsAnything.anything;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;

View File

@@ -17,8 +17,10 @@ package com.android.settings.bluetooth;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.UserManager;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
@@ -32,7 +34,10 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -66,7 +71,7 @@ public class BluetoothDevicePreferenceTest {
mPreference.onClicked();
verify(mMetricsFeatureProvider).action(
mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_DISCONNECT);
mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_DISCONNECT);
}
@Test
@@ -77,7 +82,7 @@ public class BluetoothDevicePreferenceTest {
mPreference.onClicked();
verify(mMetricsFeatureProvider).action(
mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_CONNECT);
mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_CONNECT);
}
@Test
@@ -89,6 +94,46 @@ public class BluetoothDevicePreferenceTest {
mPreference.onClicked();
verify(mMetricsFeatureProvider).action(
mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR);
mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR);
}
@Test
public void getSecondTargetResource_shouldBeGearIconLayout() {
assertThat(mPreference.getSecondTargetResId()).isEqualTo(R.layout.preference_widget_gear);
}
@Test
public void shouldHideSecondTarget_noDevice_shouldReturnTrue() {
ReflectionHelpers.setField(mPreference, "mCachedDevice", null);
assertThat(mPreference.shouldHideSecondTarget()).isTrue();
}
@Test
public void shouldHideSecondTarget_notBond_shouldReturnTrue() {
when(mCachedBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
assertThat(mPreference.shouldHideSecondTarget()).isTrue();
}
@Test
public void shouldHideSecondTarget_hasUserRestriction_shouldReturnTrue() {
final UserManager um = mock(UserManager.class);
ReflectionHelpers.setField(mPreference, "mUserManager", um);
when(um.hasUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH))
.thenReturn(true);
assertThat(mPreference.shouldHideSecondTarget()).isTrue();
}
@Test
public void shouldHideSecondTarget_hasBoundDeviceAndNoRestriction_shouldReturnFalse() {
when(mCachedBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
final UserManager um = mock(UserManager.class);
ReflectionHelpers.setField(mPreference, "mUserManager", um);
when(um.hasUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH))
.thenReturn(false);
assertThat(mPreference.shouldHideSecondTarget()).isFalse();
}
}