| /* |
| * Copyright (C) 2008 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.bluetooth.BluetoothClass; |
| import android.bluetooth.BluetoothDevice; |
| import android.content.Context; |
| import android.content.DialogInterface; |
| import android.os.UserManager; |
| import android.support.v7.preference.Preference; |
| import android.support.v7.preference.PreferenceViewHolder; |
| import android.text.Html; |
| import android.text.TextUtils; |
| import android.util.Log; |
| import android.util.TypedValue; |
| import android.view.View; |
| import android.view.View.OnClickListener; |
| import android.widget.ImageView; |
| |
| import com.android.settings.R; |
| import com.android.settings.search.Index; |
| import com.android.settings.search.SearchIndexableRaw; |
| import com.android.settingslib.bluetooth.CachedBluetoothDevice; |
| import com.android.settingslib.bluetooth.HidProfile; |
| import com.android.settingslib.bluetooth.LocalBluetoothProfile; |
| |
| import java.util.List; |
| |
| 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"; |
| |
| private static int sDimAlpha = Integer.MIN_VALUE; |
| |
| private final CachedBluetoothDevice mCachedDevice; |
| |
| private OnClickListener mOnSettingsClickListener; |
| |
| private AlertDialog mDisconnectDialog; |
| |
| public BluetoothDevicePreference(Context context, CachedBluetoothDevice cachedDevice) { |
| super(context); |
| |
| if (sDimAlpha == Integer.MIN_VALUE) { |
| TypedValue outValue = new TypedValue(); |
| context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true); |
| sDimAlpha = (int) (outValue.getFloat() * 255); |
| } |
| |
| mCachedDevice = cachedDevice; |
| |
| setLayoutResource(R.layout.preference_bt_icon); |
| |
| 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(); |
| } |
| |
| CachedBluetoothDevice getCachedDevice() { |
| return mCachedDevice; |
| } |
| |
| public void setOnSettingsClickListener(OnClickListener listener) { |
| mOnSettingsClickListener = listener; |
| } |
| |
| @Override |
| protected void onPrepareForRemoval() { |
| super.onPrepareForRemoval(); |
| mCachedDevice.unregisterCallback(this); |
| if (mDisconnectDialog != null) { |
| mDisconnectDialog.dismiss(); |
| mDisconnectDialog = null; |
| } |
| } |
| |
| public void onDeviceAttributesChanged() { |
| /* |
| * The preference framework takes care of making sure the value has |
| * changed before proceeding. It will also call notifyChanged() if |
| * any preference info has changed from the previous value. |
| */ |
| setTitle(mCachedDevice.getName()); |
| |
| int summaryResId = mCachedDevice.getConnectionSummary(); |
| if (summaryResId != 0) { |
| setSummary(summaryResId); |
| } else { |
| setSummary(null); // empty summary for unpaired devices |
| } |
| |
| int iconResId = getBtClassDrawable(); |
| if (iconResId != 0) { |
| setIcon(iconResId); |
| } |
| |
| // Used to gray out the item |
| setEnabled(!mCachedDevice.isBusy()); |
| |
| // This could affect ordering, so notify that |
| notifyHierarchyChanged(); |
| } |
| |
| @Override |
| public void onBindViewHolder(PreferenceViewHolder view) { |
| // Disable this view if the bluetooth enable/disable preference view is off |
| if (null != findPreferenceInHierarchy("bt_checkbox")) { |
| setDependency("bt_checkbox"); |
| } |
| |
| if (mCachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) { |
| ImageView deviceDetails = (ImageView) view.findViewById(R.id.deviceDetails); |
| |
| if (deviceDetails != null) { |
| deviceDetails.setOnClickListener(this); |
| deviceDetails.setTag(mCachedDevice); |
| } |
| } |
| |
| 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)) { |
| return false; |
| } |
| return mCachedDevice.equals( |
| ((BluetoothDevicePreference) o).mCachedDevice); |
| } |
| |
| @Override |
| public int hashCode() { |
| return mCachedDevice.hashCode(); |
| } |
| |
| @Override |
| public int compareTo(Preference another) { |
| if (!(another instanceof BluetoothDevicePreference)) { |
| // Rely on default sort |
| return super.compareTo(another); |
| } |
| |
| return mCachedDevice |
| .compareTo(((BluetoothDevicePreference) another).mCachedDevice); |
| } |
| |
| void onClicked() { |
| int bondState = mCachedDevice.getBondState(); |
| |
| if (mCachedDevice.isConnected()) { |
| askDisconnect(); |
| } else if (bondState == BluetoothDevice.BOND_BONDED) { |
| mCachedDevice.connect(true); |
| } else if (bondState == BluetoothDevice.BOND_NONE) { |
| pair(); |
| } |
| } |
| |
| // Show disconnect confirmation dialog for a device. |
| private void askDisconnect() { |
| Context context = getContext(); |
| String name = mCachedDevice.getName(); |
| if (TextUtils.isEmpty(name)) { |
| name = context.getString(R.string.bluetooth_device); |
| } |
| String message = context.getString(R.string.bluetooth_disconnect_all_profiles, name); |
| String title = context.getString(R.string.bluetooth_disconnect_title); |
| |
| DialogInterface.OnClickListener disconnectListener = new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int which) { |
| mCachedDevice.disconnect(); |
| } |
| }; |
| |
| mDisconnectDialog = Utils.showDisconnectDialog(context, |
| mDisconnectDialog, disconnectListener, title, Html.fromHtml(message)); |
| } |
| |
| private void pair() { |
| if (!mCachedDevice.startPairing()) { |
| Utils.showError(getContext(), mCachedDevice.getName(), |
| R.string.bluetooth_pairing_error_message); |
| } else { |
| final Context context = getContext(); |
| |
| SearchIndexableRaw data = new SearchIndexableRaw(context); |
| data.className = BluetoothSettings.class.getName(); |
| data.title = mCachedDevice.getName(); |
| data.screenTitle = context.getResources().getString(R.string.bluetooth_settings); |
| data.iconResId = R.drawable.ic_settings_bluetooth; |
| data.enabled = true; |
| |
| Index.getInstance(context).updateFromSearchIndexableData(data); |
| } |
| } |
| |
| private int getBtClassDrawable() { |
| BluetoothClass btClass = mCachedDevice.getBtClass(); |
| if (btClass != null) { |
| switch (btClass.getMajorDeviceClass()) { |
| case BluetoothClass.Device.Major.COMPUTER: |
| return R.drawable.ic_bt_laptop; |
| |
| case BluetoothClass.Device.Major.PHONE: |
| return R.drawable.ic_bt_cellphone; |
| |
| case BluetoothClass.Device.Major.PERIPHERAL: |
| return HidProfile.getHidClassDrawable(btClass); |
| |
| case BluetoothClass.Device.Major.IMAGING: |
| return R.drawable.ic_bt_imaging; |
| |
| default: |
| // unrecognized device class; continue |
| } |
| } else { |
| Log.w(TAG, "mBtClass is null"); |
| } |
| |
| List<LocalBluetoothProfile> profiles = mCachedDevice.getProfiles(); |
| for (LocalBluetoothProfile profile : profiles) { |
| int resId = profile.getDrawableResource(btClass); |
| if (resId != 0) { |
| return resId; |
| } |
| } |
| if (btClass != null) { |
| if (btClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) { |
| return R.drawable.ic_bt_headphones_a2dp; |
| |
| } |
| if (btClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) { |
| return R.drawable.ic_bt_headset_hfp; |
| } |
| } |
| return R.drawable.ic_settings_bluetooth; |
| } |
| } |