Remove DeviceProfilesSettings
It's not used anymore since we have a bt detail page. Change-Id: Ib2ecfabf544913701ca613048e9f37e297ffff18 Fixes: 111305587 Test: robo still pass
This commit is contained in:
@@ -1,69 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2015 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingStart="25dp"
|
|
||||||
android:paddingEnd="25dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/bluetooth_preference_paired_dialog_name_label"
|
|
||||||
android:textAppearance="@android:style/TextAppearance.Material.Body1"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
|
||||||
android:textDirection="locale"
|
|
||||||
android:paddingTop="16dp"
|
|
||||||
style="@style/bt_item_label"/>
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/name"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:inputType="textNoSuggestions"
|
|
||||||
android:maxLength="@integer/bluetooth_name_length"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:paddingBottom="@dimen/bluetooth_dialog_padding"
|
|
||||||
android:textDirection="locale"
|
|
||||||
style="@style/bt_item_edit_content"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/profiles_label"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingTop="16dp"
|
|
||||||
android:paddingBottom="4dp"
|
|
||||||
android:text="@string/bluetooth_device_advanced_profile_header_title"
|
|
||||||
android:textAppearance="@android:style/TextAppearance.Material.Body1"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"/>
|
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/profiles_section"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</ScrollView>
|
|
@@ -185,7 +185,6 @@
|
|||||||
<!-- Bluetooth Preferences -->
|
<!-- Bluetooth Preferences -->
|
||||||
<dimen name="bluetooth_dialog_padding">8dip</dimen>
|
<dimen name="bluetooth_dialog_padding">8dip</dimen>
|
||||||
<dimen name="bluetooth_dialog_padding_top">20dp</dimen>
|
<dimen name="bluetooth_dialog_padding_top">20dp</dimen>
|
||||||
<integer name="bluetooth_name_length">32</integer>
|
|
||||||
<dimen name="bluetooth_pairing_padding">24dp</dimen>
|
<dimen name="bluetooth_pairing_padding">24dp</dimen>
|
||||||
<dimen name="bluetooth_pairing_edittext_padding">21dp</dimen>
|
<dimen name="bluetooth_pairing_edittext_padding">21dp</dimen>
|
||||||
<dimen name="bluetooth_checkbox_padding">16dp</dimen>
|
<dimen name="bluetooth_checkbox_padding">16dp</dimen>
|
||||||
|
@@ -268,10 +268,6 @@
|
|||||||
<string name="bluetooth_is_disconnect_question">Disconnect <xliff:g id="device_name">%1$s</xliff:g>?</string>
|
<string name="bluetooth_is_disconnect_question">Disconnect <xliff:g id="device_name">%1$s</xliff:g>?</string>
|
||||||
<!-- Bluetooth broadcasting settings, option to enable/disable broadcasting -->
|
<!-- Bluetooth broadcasting settings, option to enable/disable broadcasting -->
|
||||||
<string name="bluetooth_broadcasting">Broadcasting</string>
|
<string name="bluetooth_broadcasting">Broadcasting</string>
|
||||||
<!-- Bluetooth settings. Dialog title to disable a single profile of a device. [CHAR LIMIT=40] -->
|
|
||||||
<string name="bluetooth_disable_profile_title">Disable profile?</string>
|
|
||||||
<!-- Bluetooth settings. Message for disabling a profile of a bluetooth device. [CHAR LIMIT=NONE] -->
|
|
||||||
<string name="bluetooth_disable_profile_message">This will disable:<br><b><xliff:g id="profile_name">%1$s</xliff:g></b><br><br>From:<br><b><xliff:g id="device_name">%2$s</xliff:g></b></string>
|
|
||||||
|
|
||||||
<!-- Bluetooth settings. Message when the device state is unknown -->
|
<!-- Bluetooth settings. Message when the device state is unknown -->
|
||||||
<string name="bluetooth_unknown" />
|
<string name="bluetooth_unknown" />
|
||||||
@@ -1592,8 +1588,6 @@
|
|||||||
<string name="bluetooth_preference_device_settings">Device settings</string>
|
<string name="bluetooth_preference_device_settings">Device settings</string>
|
||||||
<!-- Bluetooth settings: Paired dialog title [CHAR LIMIT=40] -->
|
<!-- Bluetooth settings: Paired dialog title [CHAR LIMIT=40] -->
|
||||||
<string name="bluetooth_preference_paired_dialog_title">Paired device</string>
|
<string name="bluetooth_preference_paired_dialog_title">Paired device</string>
|
||||||
<!-- Bluetooth settings: Name label [CHAR LIMIT=40] -->
|
|
||||||
<string name="bluetooth_preference_paired_dialog_name_label">Name</string>
|
|
||||||
<!-- Bluetooth settings: Checkbox label for enable/disable internet connection. [CHAR LIMIT=40] -->
|
<!-- Bluetooth settings: Checkbox label for enable/disable internet connection. [CHAR LIMIT=40] -->
|
||||||
<string name="bluetooth_preference_paired_dialog_internet_option">Internet connection</string>
|
<string name="bluetooth_preference_paired_dialog_internet_option">Internet connection</string>
|
||||||
<!-- Bluetooth settings: Checkbox label for enable/disable keyboard connection. [CHAR LIMIT=40] -->
|
<!-- Bluetooth settings: Checkbox label for enable/disable keyboard connection. [CHAR LIMIT=40] -->
|
||||||
@@ -1608,8 +1602,6 @@
|
|||||||
<string name="bluetooth_pairing_dialog_contants_request"><xliff:g id="device_name">%1$s</xliff:g> wants to access your contacts and call history.</string>
|
<string name="bluetooth_pairing_dialog_contants_request"><xliff:g id="device_name">%1$s</xliff:g> wants to access your contacts and call history.</string>
|
||||||
<!-- Bluetooth settings: paring permission message. [CHAR LIMIT=100] -->
|
<!-- Bluetooth settings: paring permission message. [CHAR LIMIT=100] -->
|
||||||
<string name="bluetooth_pairing_dialog_paring_request"><xliff:g id="device_name">%1$s</xliff:g> wants to pair with Bluetooth. When connected, it will have access to your contacts and call history.</string>
|
<string name="bluetooth_pairing_dialog_paring_request"><xliff:g id="device_name">%1$s</xliff:g> wants to pair with Bluetooth. When connected, it will have access to your contacts and call history.</string>
|
||||||
<!-- Bluetooth settings: The sub heading for devices which have already been paired with this device. [CHAR LIMIT=40] -->
|
|
||||||
<string name="bluetooth_preference_paired_devices">Paired devices</string>
|
|
||||||
<!-- Bluetooth settings: The sub heading for available devices during and after scanning. [CHAR LIMIT=40] -->
|
<!-- Bluetooth settings: The sub heading for available devices during and after scanning. [CHAR LIMIT=40] -->
|
||||||
<string name="bluetooth_preference_found_media_devices">Available devices</string>
|
<string name="bluetooth_preference_found_media_devices">Available devices</string>
|
||||||
<!-- Bluetooth settings: The message displayed if no Bluetooth devices were found. [CHAR LIMIT=40] -->
|
<!-- Bluetooth settings: The message displayed if no Bluetooth devices were found. [CHAR LIMIT=40] -->
|
||||||
|
@@ -157,13 +157,6 @@
|
|||||||
<item name="android:gravity">start</item>
|
<item name="android:gravity">start</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="bt_item_label">
|
|
||||||
<item name="android:layout_width">wrap_content</item>
|
|
||||||
<item name="android:layout_height">wrap_content</item>
|
|
||||||
<item name="android:textSize">14sp</item>
|
|
||||||
<item name="android:textAlignment">viewStart</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="bt_item_edit_content">
|
<style name="bt_item_edit_content">
|
||||||
<item name="android:layout_width">match_parent</item>
|
<item name="android:layout_width">match_parent</item>
|
||||||
<item name="android:layout_height">wrap_content</item>
|
<item name="android:layout_height">wrap_content</item>
|
||||||
|
@@ -1,434 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 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.AlertDialog;
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.bluetooth.BluetoothDevice;
|
|
||||||
import android.bluetooth.BluetoothProfile;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.Html;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
|
||||||
import com.android.settingslib.bluetooth.A2dpProfile;
|
|
||||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
|
||||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
|
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
|
||||||
import com.android.settingslib.bluetooth.MapProfile;
|
|
||||||
import com.android.settingslib.bluetooth.PanProfile;
|
|
||||||
import com.android.settingslib.bluetooth.PbapServerProfile;
|
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
|
|
||||||
public final class DeviceProfilesSettings extends InstrumentedDialogFragment implements
|
|
||||||
CachedBluetoothDevice.Callback, DialogInterface.OnClickListener, OnClickListener {
|
|
||||||
private static final String TAG = "DeviceProfilesSettings";
|
|
||||||
|
|
||||||
public static final String ARG_DEVICE_ADDRESS = "device_address";
|
|
||||||
|
|
||||||
private static final String KEY_PROFILE_CONTAINER = "profile_container";
|
|
||||||
private static final String KEY_UNPAIR = "unpair";
|
|
||||||
private static final String KEY_PBAP_SERVER = "PBAP Server";
|
|
||||||
@VisibleForTesting
|
|
||||||
static final String HIGH_QUALITY_AUDIO_PREF_TAG = "A2dpProfileHighQualityAudio";
|
|
||||||
|
|
||||||
private CachedBluetoothDevice mCachedDevice;
|
|
||||||
private LocalBluetoothManager mManager;
|
|
||||||
private LocalBluetoothProfileManager mProfileManager;
|
|
||||||
|
|
||||||
private ViewGroup mProfileContainer;
|
|
||||||
private TextView mProfileLabel;
|
|
||||||
|
|
||||||
private AlertDialog mDisconnectDialog;
|
|
||||||
private boolean mProfileGroupIsRemoved;
|
|
||||||
|
|
||||||
private View mRootView;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsCategory() {
|
|
||||||
return MetricsProto.MetricsEvent.DIALOG_BLUETOOTH_PAIRED_DEVICE_PROFILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
mManager = Utils.getLocalBtManager(getActivity());
|
|
||||||
CachedBluetoothDeviceManager deviceManager = mManager.getCachedDeviceManager();
|
|
||||||
|
|
||||||
String address = getArguments().getString(ARG_DEVICE_ADDRESS);
|
|
||||||
BluetoothDevice remoteDevice = mManager.getBluetoothAdapter().getRemoteDevice(address);
|
|
||||||
|
|
||||||
mCachedDevice = deviceManager.findDevice(remoteDevice);
|
|
||||||
if (mCachedDevice == null) {
|
|
||||||
mCachedDevice = deviceManager.addDevice(mManager.getBluetoothAdapter(),
|
|
||||||
mManager.getProfileManager(), remoteDevice);
|
|
||||||
}
|
|
||||||
mProfileManager = mManager.getProfileManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
|
||||||
mRootView = LayoutInflater.from(getContext()).inflate(R.layout.device_profiles_settings,
|
|
||||||
null);
|
|
||||||
mProfileContainer = (ViewGroup) mRootView.findViewById(R.id.profiles_section);
|
|
||||||
mProfileLabel = (TextView) mRootView.findViewById(R.id.profiles_label);
|
|
||||||
final EditText deviceName = (EditText) mRootView.findViewById(R.id.name);
|
|
||||||
deviceName.setText(mCachedDevice.getName(), TextView.BufferType.EDITABLE);
|
|
||||||
return new AlertDialog.Builder(getContext())
|
|
||||||
.setView(mRootView)
|
|
||||||
.setNeutralButton(R.string.forget, this)
|
|
||||||
.setPositiveButton(R.string.okay, this)
|
|
||||||
.setTitle(R.string.bluetooth_preference_paired_devices)
|
|
||||||
.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
switch (which) {
|
|
||||||
case DialogInterface.BUTTON_POSITIVE:
|
|
||||||
EditText deviceName = (EditText) mRootView.findViewById(R.id.name);
|
|
||||||
mCachedDevice.setName(deviceName.getText().toString());
|
|
||||||
break;
|
|
||||||
case DialogInterface.BUTTON_NEUTRAL:
|
|
||||||
mCachedDevice.unpair();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
if (mDisconnectDialog != null) {
|
|
||||||
mDisconnectDialog.dismiss();
|
|
||||||
mDisconnectDialog = null;
|
|
||||||
}
|
|
||||||
if (mCachedDevice != null) {
|
|
||||||
mCachedDevice.unregisterCallback(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
mManager.setForegroundActivity(getActivity());
|
|
||||||
if (mCachedDevice != null) {
|
|
||||||
mCachedDevice.registerCallback(this);
|
|
||||||
if (mCachedDevice.getBondState() == BluetoothDevice.BOND_NONE) {
|
|
||||||
dismiss();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
addPreferencesForProfiles();
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
|
|
||||||
if (mCachedDevice != null) {
|
|
||||||
mCachedDevice.unregisterCallback(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
mManager.setForegroundActivity(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addPreferencesForProfiles() {
|
|
||||||
mProfileContainer.removeAllViews();
|
|
||||||
for (LocalBluetoothProfile profile : mCachedDevice.getConnectableProfiles()) {
|
|
||||||
CheckBox pref = createProfilePreference(profile);
|
|
||||||
// MAP and PBAP profiles would be added based on permission access
|
|
||||||
if (!((profile instanceof PbapServerProfile) ||
|
|
||||||
(profile instanceof MapProfile))) {
|
|
||||||
mProfileContainer.addView(pref);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (profile instanceof A2dpProfile) {
|
|
||||||
BluetoothDevice device = mCachedDevice.getDevice();
|
|
||||||
A2dpProfile a2dpProfile = (A2dpProfile) profile;
|
|
||||||
if (a2dpProfile.supportsHighQualityAudio(device)) {
|
|
||||||
CheckBox highQualityPref = new CheckBox(getActivity());
|
|
||||||
highQualityPref.setTag(HIGH_QUALITY_AUDIO_PREF_TAG);
|
|
||||||
highQualityPref.setOnClickListener(v -> {
|
|
||||||
a2dpProfile.setHighQualityAudioEnabled(device, highQualityPref.isChecked());
|
|
||||||
});
|
|
||||||
highQualityPref.setVisibility(View.GONE);
|
|
||||||
mProfileContainer.addView(highQualityPref);
|
|
||||||
}
|
|
||||||
refreshProfilePreference(pref, profile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final int pbapPermission = mCachedDevice.getPhonebookPermissionChoice();
|
|
||||||
Log.d(TAG, "addPreferencesForProfiles: pbapPermission = " + pbapPermission);
|
|
||||||
// Only provide PBAP cabability if the client device has requested PBAP.
|
|
||||||
if (pbapPermission != CachedBluetoothDevice.ACCESS_UNKNOWN) {
|
|
||||||
final PbapServerProfile psp = mManager.getProfileManager().getPbapProfile();
|
|
||||||
CheckBox pbapPref = createProfilePreference(psp);
|
|
||||||
mProfileContainer.addView(pbapPref);
|
|
||||||
}
|
|
||||||
|
|
||||||
final MapProfile mapProfile = mManager.getProfileManager().getMapProfile();
|
|
||||||
final int mapPermission = mCachedDevice.getMessagePermissionChoice();
|
|
||||||
Log.d(TAG, "addPreferencesForProfiles: mapPermission = " + mapPermission);
|
|
||||||
if (mapPermission != CachedBluetoothDevice.ACCESS_UNKNOWN) {
|
|
||||||
CheckBox mapPreference = createProfilePreference(mapProfile);
|
|
||||||
mProfileContainer.addView(mapPreference);
|
|
||||||
}
|
|
||||||
|
|
||||||
showOrHideProfileGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showOrHideProfileGroup() {
|
|
||||||
int numProfiles = mProfileContainer.getChildCount();
|
|
||||||
if (!mProfileGroupIsRemoved && numProfiles == 0) {
|
|
||||||
mProfileContainer.setVisibility(View.GONE);
|
|
||||||
mProfileLabel.setVisibility(View.GONE);
|
|
||||||
mProfileGroupIsRemoved = true;
|
|
||||||
} else if (mProfileGroupIsRemoved && numProfiles != 0) {
|
|
||||||
mProfileContainer.setVisibility(View.VISIBLE);
|
|
||||||
mProfileLabel.setVisibility(View.VISIBLE);
|
|
||||||
mProfileGroupIsRemoved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a checkbox preference for the particular profile. The key will be
|
|
||||||
* the profile's name.
|
|
||||||
*
|
|
||||||
* @param profile The profile for which the preference controls.
|
|
||||||
* @return A preference that allows the user to choose whether this profile
|
|
||||||
* will be connected to.
|
|
||||||
*/
|
|
||||||
private CheckBox createProfilePreference(LocalBluetoothProfile profile) {
|
|
||||||
CheckBox pref = new CheckBox(getActivity());
|
|
||||||
pref.setTag(profile.toString());
|
|
||||||
pref.setText(profile.getNameResource(mCachedDevice.getDevice()));
|
|
||||||
pref.setOnClickListener(this);
|
|
||||||
|
|
||||||
refreshProfilePreference(pref, profile);
|
|
||||||
|
|
||||||
return pref;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (v instanceof CheckBox) {
|
|
||||||
LocalBluetoothProfile prof = getProfileOf(v);
|
|
||||||
onProfileClicked(prof, (CheckBox) v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onProfileClicked(LocalBluetoothProfile profile, CheckBox profilePref) {
|
|
||||||
BluetoothDevice device = mCachedDevice.getDevice();
|
|
||||||
|
|
||||||
if (!profilePref.isChecked()) {
|
|
||||||
// Recheck it, until the dialog is done.
|
|
||||||
profilePref.setChecked(true);
|
|
||||||
askDisconnect(mManager.getForegroundActivity(), profile);
|
|
||||||
} else {
|
|
||||||
if (profile instanceof MapProfile) {
|
|
||||||
mCachedDevice.setMessagePermissionChoice(BluetoothDevice.ACCESS_ALLOWED);
|
|
||||||
}
|
|
||||||
if (profile instanceof PbapServerProfile) {
|
|
||||||
mCachedDevice.setPhonebookPermissionChoice(BluetoothDevice.ACCESS_ALLOWED);
|
|
||||||
refreshProfilePreference(profilePref, profile);
|
|
||||||
// PBAP server is not preffered profile and cannot initiate connection, so return
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (profile.isPreferred(device)) {
|
|
||||||
// profile is preferred but not connected: disable auto-connect
|
|
||||||
if (profile instanceof PanProfile) {
|
|
||||||
mCachedDevice.connectProfile(profile);
|
|
||||||
} else {
|
|
||||||
profile.setPreferred(device, false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
profile.setPreferred(device, true);
|
|
||||||
mCachedDevice.connectProfile(profile);
|
|
||||||
}
|
|
||||||
refreshProfilePreference(profilePref, profile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void askDisconnect(Context context,
|
|
||||||
final LocalBluetoothProfile profile) {
|
|
||||||
// local reference for callback
|
|
||||||
final CachedBluetoothDevice device = mCachedDevice;
|
|
||||||
String name = device.getName();
|
|
||||||
if (TextUtils.isEmpty(name)) {
|
|
||||||
name = context.getString(R.string.bluetooth_device);
|
|
||||||
}
|
|
||||||
|
|
||||||
String profileName = context.getString(profile.getNameResource(device.getDevice()));
|
|
||||||
|
|
||||||
String title = context.getString(R.string.bluetooth_disable_profile_title);
|
|
||||||
String message = context.getString(R.string.bluetooth_disable_profile_message,
|
|
||||||
profileName, name);
|
|
||||||
|
|
||||||
DialogInterface.OnClickListener disconnectListener =
|
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
|
|
||||||
// Disconnect only when user has selected OK otherwise ignore
|
|
||||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
|
||||||
device.disconnect(profile);
|
|
||||||
profile.setPreferred(device.getDevice(), false);
|
|
||||||
if (profile instanceof MapProfile) {
|
|
||||||
device.setMessagePermissionChoice(BluetoothDevice.ACCESS_REJECTED);
|
|
||||||
}
|
|
||||||
if (profile instanceof PbapServerProfile) {
|
|
||||||
device.setPhonebookPermissionChoice(BluetoothDevice.ACCESS_REJECTED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
refreshProfilePreference(findProfile(profile.toString()), profile);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mDisconnectDialog = Utils.showDisconnectDialog(context,
|
|
||||||
mDisconnectDialog, disconnectListener, title, Html.fromHtml(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDeviceAttributesChanged() {
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void refresh() {
|
|
||||||
final EditText deviceNameField = (EditText) mRootView.findViewById(R.id.name);
|
|
||||||
if (deviceNameField != null) {
|
|
||||||
deviceNameField.setText(mCachedDevice.getName());
|
|
||||||
com.android.settings.Utils.setEditTextCursorPosition(deviceNameField);
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshProfiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void refreshProfiles() {
|
|
||||||
for (LocalBluetoothProfile profile : mCachedDevice.getConnectableProfiles()) {
|
|
||||||
CheckBox profilePref = findProfile(profile.toString());
|
|
||||||
if (profilePref == null) {
|
|
||||||
profilePref = createProfilePreference(profile);
|
|
||||||
mProfileContainer.addView(profilePref);
|
|
||||||
} else {
|
|
||||||
refreshProfilePreference(profilePref, profile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (LocalBluetoothProfile profile : mCachedDevice.getRemovedProfiles()) {
|
|
||||||
CheckBox profilePref = findProfile(profile.toString());
|
|
||||||
if (profilePref != null) {
|
|
||||||
|
|
||||||
if (profile instanceof PbapServerProfile) {
|
|
||||||
final int pbapPermission = mCachedDevice.getPhonebookPermissionChoice();
|
|
||||||
Log.d(TAG, "refreshProfiles: pbapPermission = " + pbapPermission);
|
|
||||||
if (pbapPermission != CachedBluetoothDevice.ACCESS_UNKNOWN)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (profile instanceof MapProfile) {
|
|
||||||
final int mapPermission = mCachedDevice.getMessagePermissionChoice();
|
|
||||||
Log.d(TAG, "refreshProfiles: mapPermission = " + mapPermission);
|
|
||||||
if (mapPermission != CachedBluetoothDevice.ACCESS_UNKNOWN)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Log.d(TAG, "Removing " + profile.toString() + " from profile list");
|
|
||||||
mProfileContainer.removeView(profilePref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
showOrHideProfileGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private CheckBox findProfile(String profile) {
|
|
||||||
return (CheckBox) mProfileContainer.findViewWithTag(profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void refreshProfilePreference(CheckBox profilePref,
|
|
||||||
LocalBluetoothProfile profile) {
|
|
||||||
BluetoothDevice device = mCachedDevice.getDevice();
|
|
||||||
|
|
||||||
// Gray out checkbox while connecting and disconnecting.
|
|
||||||
profilePref.setEnabled(!mCachedDevice.isBusy());
|
|
||||||
|
|
||||||
if (profile instanceof MapProfile) {
|
|
||||||
profilePref.setChecked(mCachedDevice.getMessagePermissionChoice()
|
|
||||||
== CachedBluetoothDevice.ACCESS_ALLOWED);
|
|
||||||
|
|
||||||
} else if (profile instanceof PbapServerProfile) {
|
|
||||||
profilePref.setChecked(mCachedDevice.getPhonebookPermissionChoice()
|
|
||||||
== CachedBluetoothDevice.ACCESS_ALLOWED);
|
|
||||||
|
|
||||||
} else if (profile instanceof PanProfile) {
|
|
||||||
profilePref.setChecked(profile.getConnectionStatus(device) ==
|
|
||||||
BluetoothProfile.STATE_CONNECTED);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
profilePref.setChecked(profile.isPreferred(device));
|
|
||||||
}
|
|
||||||
if (profile instanceof A2dpProfile) {
|
|
||||||
A2dpProfile a2dpProfile = (A2dpProfile) profile;
|
|
||||||
View v = mProfileContainer.findViewWithTag(HIGH_QUALITY_AUDIO_PREF_TAG);
|
|
||||||
if (v instanceof CheckBox) {
|
|
||||||
CheckBox highQualityPref = (CheckBox) v;
|
|
||||||
highQualityPref.setText(a2dpProfile.getHighQualityAudioOptionLabel(device));
|
|
||||||
highQualityPref.setChecked(a2dpProfile.isHighQualityAudioEnabled(device));
|
|
||||||
|
|
||||||
if (a2dpProfile.isPreferred(device)) {
|
|
||||||
v.setVisibility(View.VISIBLE);
|
|
||||||
v.setEnabled(!mCachedDevice.isBusy());
|
|
||||||
} else {
|
|
||||||
v.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private LocalBluetoothProfile getProfileOf(View v) {
|
|
||||||
if (!(v instanceof CheckBox)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String key = (String) v.getTag();
|
|
||||||
if (TextUtils.isEmpty(key)) return null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
return mProfileManager.getProfileByName(key);
|
|
||||||
} catch (IllegalArgumentException ignored) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,204 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.eq;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.CheckBox;
|
|
||||||
|
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
|
||||||
import com.android.settingslib.R;
|
|
||||||
import com.android.settingslib.bluetooth.A2dpProfile;
|
|
||||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
|
||||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
|
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
|
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
|
||||||
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.robolectric.util.FragmentTestUtil;
|
|
||||||
import org.robolectric.util.ReflectionHelpers;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
|
||||||
public class DeviceProfilesSettingsTest {
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private LocalBluetoothManager mManager;
|
|
||||||
@Mock
|
|
||||||
private LocalBluetoothAdapter mAdapter;
|
|
||||||
@Mock
|
|
||||||
private LocalBluetoothProfileManager mProfileManager;
|
|
||||||
@Mock
|
|
||||||
private CachedBluetoothDeviceManager mDeviceManager;
|
|
||||||
@Mock
|
|
||||||
private CachedBluetoothDevice mCachedDevice;
|
|
||||||
@Mock
|
|
||||||
private A2dpProfile mProfile;
|
|
||||||
|
|
||||||
private DeviceProfilesSettings mFragment;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
|
|
||||||
when(mProfile.getNameResource(any())).thenReturn(R.string.bluetooth_profile_a2dp);
|
|
||||||
List<LocalBluetoothProfile> profiles = new ArrayList<>();
|
|
||||||
profiles.add(mProfile);
|
|
||||||
when(mCachedDevice.getConnectableProfiles()).thenReturn(profiles);
|
|
||||||
|
|
||||||
mFragment = new DeviceProfilesSettings();
|
|
||||||
mFragment.setArguments(new Bundle());
|
|
||||||
|
|
||||||
ReflectionHelpers.setStaticField(LocalBluetoothManager.class, "sInstance", mManager);
|
|
||||||
when(mManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
|
|
||||||
when(mManager.getBluetoothAdapter()).thenReturn(mAdapter);
|
|
||||||
when(mManager.getProfileManager()).thenReturn(mProfileManager);
|
|
||||||
when(mProfileManager.getMapProfile()).thenReturn(null);
|
|
||||||
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() {
|
|
||||||
ReflectionHelpers.setStaticField(LocalBluetoothManager.class, "sInstance", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void deviceHasHighQualityAudio() {
|
|
||||||
when(mProfile.supportsHighQualityAudio(any())).thenReturn(true);
|
|
||||||
when(mProfile.isHighQualityAudioEnabled(any())).thenReturn(true);
|
|
||||||
when(mProfile.isPreferred(any())).thenReturn(true);
|
|
||||||
FragmentTestUtil.startFragment(mFragment);
|
|
||||||
|
|
||||||
ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section);
|
|
||||||
CheckBox box =
|
|
||||||
profilesGroup.findViewWithTag(DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
|
|
||||||
assertThat(box).isNotNull();
|
|
||||||
assertThat(box.getVisibility()).isEqualTo(View.VISIBLE);
|
|
||||||
assertThat(box.isEnabled()).isTrue();
|
|
||||||
assertThat(box.isChecked()).isTrue();
|
|
||||||
|
|
||||||
box.performClick();
|
|
||||||
verify(mProfile).setHighQualityAudioEnabled(any(), eq(false));
|
|
||||||
box.performClick();
|
|
||||||
verify(mProfile).setHighQualityAudioEnabled(any(), eq(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void busyDeviceDisablesControl() {
|
|
||||||
when(mProfile.supportsHighQualityAudio(any())).thenReturn(true);
|
|
||||||
when(mProfile.isHighQualityAudioEnabled(any())).thenReturn(true);
|
|
||||||
when(mProfile.isPreferred(any())).thenReturn(true);
|
|
||||||
when(mCachedDevice.isBusy()).thenReturn(true);
|
|
||||||
FragmentTestUtil.startFragment(mFragment);
|
|
||||||
|
|
||||||
// Make sure that the high quality audio option is present but disabled when the device
|
|
||||||
// is busy.
|
|
||||||
ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section);
|
|
||||||
CheckBox box =
|
|
||||||
profilesGroup.findViewWithTag(DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
|
|
||||||
assertThat(box).isNotNull();
|
|
||||||
assertThat(box.getVisibility()).isEqualTo(View.VISIBLE);
|
|
||||||
assertThat(box.isEnabled()).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void mediaAudioGetsDisabledAndReEnabled() {
|
|
||||||
when(mProfile.supportsHighQualityAudio(any())).thenReturn(true);
|
|
||||||
when(mProfile.isHighQualityAudioEnabled(any())).thenReturn(true);
|
|
||||||
when(mProfile.isPreferred(any())).thenReturn(true);
|
|
||||||
FragmentTestUtil.startFragment(mFragment);
|
|
||||||
|
|
||||||
ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section);
|
|
||||||
CheckBox audioBox = profilesGroup.findViewWithTag(mProfile.toString());
|
|
||||||
CheckBox highQualityAudioBox =
|
|
||||||
profilesGroup.findViewWithTag(DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
|
|
||||||
assertThat(audioBox).isNotNull();
|
|
||||||
assertThat(audioBox.isChecked()).isTrue();
|
|
||||||
assertThat(highQualityAudioBox).isNotNull();
|
|
||||||
assertThat(highQualityAudioBox.isChecked()).isTrue();
|
|
||||||
|
|
||||||
// Disabling media audio should cause the high quality audio box to disappear.
|
|
||||||
when(mProfile.isPreferred(any())).thenReturn(false);
|
|
||||||
mFragment.onDeviceAttributesChanged();
|
|
||||||
audioBox = profilesGroup.findViewWithTag(mProfile.toString());
|
|
||||||
highQualityAudioBox =
|
|
||||||
profilesGroup.findViewWithTag(DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
|
|
||||||
assertThat(audioBox).isNotNull();
|
|
||||||
assertThat(audioBox.isChecked()).isFalse();
|
|
||||||
assertThat(highQualityAudioBox).isNotNull();
|
|
||||||
assertThat(highQualityAudioBox.getVisibility()).isEqualTo(View.GONE);
|
|
||||||
|
|
||||||
// And re-enabling media audio should make it reappear.
|
|
||||||
when(mProfile.isPreferred(any())).thenReturn(true);
|
|
||||||
mFragment.onDeviceAttributesChanged();
|
|
||||||
audioBox = profilesGroup.findViewWithTag(mProfile.toString());
|
|
||||||
highQualityAudioBox =
|
|
||||||
profilesGroup.findViewWithTag(DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
|
|
||||||
assertThat(audioBox).isNotNull();
|
|
||||||
assertThat(audioBox.isChecked()).isTrue();
|
|
||||||
assertThat(highQualityAudioBox).isNotNull();
|
|
||||||
assertThat(highQualityAudioBox.isChecked()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void mediaAudioStartsDisabled() {
|
|
||||||
when(mProfile.supportsHighQualityAudio(any())).thenReturn(true);
|
|
||||||
when(mProfile.isHighQualityAudioEnabled(any())).thenReturn(true);
|
|
||||||
when(mProfile.isPreferred(any())).thenReturn(false);
|
|
||||||
|
|
||||||
FragmentTestUtil.startFragment(mFragment);
|
|
||||||
ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section);
|
|
||||||
CheckBox audioBox = profilesGroup.findViewWithTag(mProfile.toString());
|
|
||||||
CheckBox highQualityAudioBox =
|
|
||||||
profilesGroup.findViewWithTag(DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
|
|
||||||
|
|
||||||
assertThat(audioBox).isNotNull();
|
|
||||||
assertThat(audioBox.isChecked()).isFalse();
|
|
||||||
assertThat(highQualityAudioBox).isNotNull();
|
|
||||||
assertThat(highQualityAudioBox.getVisibility()).isEqualTo(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void deviceDoesntHaveHighQualityAudio() {
|
|
||||||
when(mProfile.supportsHighQualityAudio(any())).thenReturn(false);
|
|
||||||
when(mProfile.isPreferred(any())).thenReturn(true);
|
|
||||||
FragmentTestUtil.startFragment(mFragment);
|
|
||||||
|
|
||||||
// A device that doesn't support high quality audio shouldn't have the checkbox for
|
|
||||||
// high quality audio support.
|
|
||||||
ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section);
|
|
||||||
CheckBox box =
|
|
||||||
profilesGroup.findViewWithTag(DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG);
|
|
||||||
assertThat(box).isNull();
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user