summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/bluetooth/LocalBluetoothDevice.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/settings/bluetooth/LocalBluetoothDevice.java')
-rw-r--r--src/com/android/settings/bluetooth/LocalBluetoothDevice.java576
1 files changed, 0 insertions, 576 deletions
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothDevice.java b/src/com/android/settings/bluetooth/LocalBluetoothDevice.java
deleted file mode 100644
index a4885401e..000000000
--- a/src/com/android/settings/bluetooth/LocalBluetoothDevice.java
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * 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 com.android.settings.R;
-import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
-
-import android.app.AlertDialog;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothClass;
-import android.bluetooth.IBluetoothDeviceCallback;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.Menu;
-import android.view.MenuItem;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * LocalBluetoothDevice represents a remote Bluetooth device. It contains
- * attributes of the device (such as the address, name, RSSI, etc.) and
- * functionality that can be performed on the device (connect, pair, disconnect,
- * etc.).
- */
-public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
- private static final String TAG = "LocalBluetoothDevice";
-
- private static final int CONTEXT_ITEM_CONNECT = Menu.FIRST + 1;
- private static final int CONTEXT_ITEM_DISCONNECT = Menu.FIRST + 2;
- private static final int CONTEXT_ITEM_UNPAIR = Menu.FIRST + 3;
- private static final int CONTEXT_ITEM_CONNECT_ADVANCED = Menu.FIRST + 4;
-
- private final String mAddress;
- private String mName;
- private short mRssi;
- private int mBtClass = BluetoothClass.ERROR;
-
- private List<Profile> mProfiles = new ArrayList<Profile>();
-
- private boolean mVisible;
-
- private final LocalBluetoothManager mLocalManager;
-
- private List<Callback> mCallbacks = new ArrayList<Callback>();
-
- /**
- * When we connect to multiple profiles, we only want to display a single
- * error even if they all fail. This tracks that state.
- */
- private boolean mIsConnectingErrorPossible;
-
- LocalBluetoothDevice(Context context, String address) {
- mLocalManager = LocalBluetoothManager.getInstance(context);
- if (mLocalManager == null) {
- throw new IllegalStateException(
- "Cannot use LocalBluetoothDevice without Bluetooth hardware");
- }
-
- mAddress = address;
-
- fillData();
- }
-
- public void onClicked() {
- int bondState = getBondState();
-
- if (isConnected()) {
- askDisconnect();
- } else if (bondState == BluetoothDevice.BOND_BONDED) {
- connect();
- } else if (bondState == BluetoothDevice.BOND_NOT_BONDED) {
- pair();
- }
- }
-
- public void disconnect() {
- for (Profile profile : mProfiles) {
- disconnect(profile);
- }
- }
-
- public void disconnect(Profile profile) {
- LocalBluetoothProfileManager profileManager =
- LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
- int status = profileManager.getConnectionStatus(mAddress);
- if (SettingsBtStatus.isConnectionStatusConnected(status)) {
- profileManager.disconnect(mAddress);
- }
- }
-
- public void askDisconnect() {
- Context context = mLocalManager.getForegroundActivity();
- if (context == null) {
- // Cannot ask, since we need an activity context
- disconnect();
- return;
- }
-
- Resources res = context.getResources();
-
- String name = getName();
- if (TextUtils.isEmpty(name)) {
- name = res.getString(R.string.bluetooth_device);
- }
- String message = res.getString(R.string.bluetooth_disconnect_blank, name);
-
- DialogInterface.OnClickListener disconnectListener = new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- disconnect();
- }
- };
-
- AlertDialog ad = new AlertDialog.Builder(context)
- .setTitle(getName())
- .setMessage(message)
- .setPositiveButton(android.R.string.ok, disconnectListener)
- .setNegativeButton(android.R.string.cancel, null)
- .show();
- }
-
- public void connect() {
- if (!ensurePaired()) return;
-
- // Reset the only-show-one-error-dialog tracking variable
- mIsConnectingErrorPossible = true;
-
- Context context = mLocalManager.getContext();
- boolean hasAtLeastOnePreferredProfile = false;
- for (Profile profile : mProfiles) {
- LocalBluetoothProfileManager profileManager =
- LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
- if (profileManager.isPreferred(mAddress)) {
- hasAtLeastOnePreferredProfile = true;
- connectInt(profile);
- }
- }
-
- if (!hasAtLeastOnePreferredProfile) {
- connectAndPreferAllProfiles();
- }
- }
-
- private void connectAndPreferAllProfiles() {
- if (!ensurePaired()) return;
-
- // Reset the only-show-one-error-dialog tracking variable
- mIsConnectingErrorPossible = true;
-
- Context context = mLocalManager.getContext();
- for (Profile profile : mProfiles) {
- LocalBluetoothProfileManager profileManager =
- LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
- profileManager.setPreferred(mAddress, true);
- connectInt(profile);
- }
- }
-
- public void connect(Profile profile) {
- // Reset the only-show-one-error-dialog tracking variable
- mIsConnectingErrorPossible = true;
- connectInt(profile);
- }
-
- public void connectInt(Profile profile) {
- if (!ensurePaired()) return;
-
- LocalBluetoothProfileManager profileManager =
- LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
- int status = profileManager.getConnectionStatus(mAddress);
- if (!SettingsBtStatus.isConnectionStatusConnected(status)) {
- if (profileManager.connect(mAddress) != BluetoothDevice.RESULT_SUCCESS) {
- Log.i(TAG, "Failed to connect " + profile.toString() + " to " + mName);
- }
- }
- }
-
- public void showConnectingError() {
- if (!mIsConnectingErrorPossible) return;
- mIsConnectingErrorPossible = false;
-
- mLocalManager.showError(mAddress, R.string.bluetooth_error_title,
- R.string.bluetooth_connecting_error_message);
- }
-
- private boolean ensurePaired() {
- if (getBondState() == BluetoothDevice.BOND_NOT_BONDED) {
- pair();
- return false;
- } else {
- return true;
- }
- }
-
- public void pair() {
- BluetoothDevice manager = mLocalManager.getBluetoothManager();
-
- // Pairing is unreliable while scanning, so cancel discovery
- if (manager.isDiscovering()) {
- manager.cancelDiscovery();
- }
-
- if (!mLocalManager.getBluetoothManager().createBond(mAddress)) {
- mLocalManager.showError(mAddress, R.string.bluetooth_error_title,
- R.string.bluetooth_pairing_error_message);
- }
- }
-
- public void unpair() {
- BluetoothDevice manager = mLocalManager.getBluetoothManager();
-
- switch (getBondState()) {
- case BluetoothDevice.BOND_BONDED:
- manager.removeBond(mAddress);
- break;
-
- case BluetoothDevice.BOND_BONDING:
- manager.cancelBondProcess(mAddress);
- break;
- }
- }
-
- private void fillData() {
- BluetoothDevice manager = mLocalManager.getBluetoothManager();
-
- fetchName();
- fetchBtClass();
-
- mVisible = false;
-
- dispatchAttributesChanged();
- }
-
- public String getAddress() {
- return mAddress;
- }
-
- public String getName() {
- return mName;
- }
-
- public void refreshName() {
- fetchName();
- dispatchAttributesChanged();
- }
-
- private void fetchName() {
- mName = mLocalManager.getBluetoothManager().getRemoteName(mAddress);
-
- if (TextUtils.isEmpty(mName)) {
- mName = mAddress;
- }
- }
-
- public void refresh() {
- dispatchAttributesChanged();
- }
-
- public boolean isVisible() {
- return mVisible;
- }
-
- void setVisible(boolean visible) {
- if (mVisible != visible) {
- mVisible = visible;
- dispatchAttributesChanged();
- }
- }
-
- public int getBondState() {
- return mLocalManager.getBluetoothManager().getBondState(mAddress);
- }
-
- void setRssi(short rssi) {
- if (mRssi != rssi) {
- mRssi = rssi;
- dispatchAttributesChanged();
- }
- }
-
- /**
- * Checks whether we are connected to this device (any profile counts).
- *
- * @return Whether it is connected.
- */
- public boolean isConnected() {
- for (Profile profile : mProfiles) {
- int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
- .getConnectionStatus(mAddress);
- if (SettingsBtStatus.isConnectionStatusConnected(status)) {
- return true;
- }
- }
-
- return false;
- }
-
- public boolean isBusy() {
- for (Profile profile : mProfiles) {
- int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
- .getConnectionStatus(mAddress);
- if (SettingsBtStatus.isConnectionStatusBusy(status)) {
- return true;
- }
- }
-
- if (getBondState() == BluetoothDevice.BOND_BONDING) {
- return true;
- }
-
- return false;
- }
-
- public int getBtClassDrawable() {
-
- // First try looking at profiles
- if (mProfiles.contains(Profile.A2DP)) {
- return R.drawable.ic_bt_headphones_a2dp;
- } else if (mProfiles.contains(Profile.HEADSET)) {
- return R.drawable.ic_bt_headset_hfp;
- }
-
- // Fallback on class
- switch (BluetoothClass.Device.Major.getDeviceMajor(mBtClass)) {
- case BluetoothClass.Device.Major.COMPUTER:
- return R.drawable.ic_bt_laptop;
-
- case BluetoothClass.Device.Major.PHONE:
- return R.drawable.ic_bt_cellphone;
-
- default:
- return 0;
- }
- }
-
- /**
- * Fetches a new value for the cached BT class.
- */
- private void fetchBtClass() {
- mBtClass = mLocalManager.getBluetoothManager().getRemoteClass(mAddress);
- mProfiles.clear();
- LocalBluetoothProfileManager.fill(mBtClass, mProfiles);
- }
-
- /**
- * Refreshes the UI for the BT class, including fetching the latest value
- * for the class.
- */
- public void refreshBtClass() {
- fetchBtClass();
- dispatchAttributesChanged();
- }
-
- public int getSummary() {
- // TODO: clean up
- int oneOffSummary = getOneOffSummary();
- if (oneOffSummary != 0) {
- return oneOffSummary;
- }
-
- for (Profile profile : mProfiles) {
- LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
- .getProfileManager(mLocalManager, profile);
- int connectionStatus = profileManager.getConnectionStatus(mAddress);
-
- if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus) ||
- connectionStatus == SettingsBtStatus.CONNECTION_STATUS_CONNECTING ||
- connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING) {
- return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
- }
- }
-
- return SettingsBtStatus.getPairingStatusSummary(getBondState());
- }
-
- /**
- * We have special summaries when particular profiles are connected. This
- * checks for those states and returns an applicable summary.
- *
- * @return A one-off summary that is applicable for the current state, or 0.
- */
- private int getOneOffSummary() {
- boolean isA2dpConnected = false, isHeadsetConnected = false, isConnecting = false;
-
- if (mProfiles.contains(Profile.A2DP)) {
- LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
- .getProfileManager(mLocalManager, Profile.A2DP);
- isConnecting = profileManager.getConnectionStatus(mAddress) ==
- SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
- isA2dpConnected = profileManager.isConnected(mAddress);
- }
-
- if (mProfiles.contains(Profile.HEADSET)) {
- LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
- .getProfileManager(mLocalManager, Profile.HEADSET);
- isConnecting |= profileManager.getConnectionStatus(mAddress) ==
- SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
- isHeadsetConnected = profileManager.isConnected(mAddress);
- }
-
- if (isConnecting) {
- // If any of these important profiles is connecting, prefer that
- return SettingsBtStatus.getConnectionStatusSummary(
- SettingsBtStatus.CONNECTION_STATUS_CONNECTING);
- } else if (isA2dpConnected && isHeadsetConnected) {
- return R.string.bluetooth_summary_connected_to_a2dp_headset;
- } else if (isA2dpConnected) {
- return R.string.bluetooth_summary_connected_to_a2dp;
- } else if (isHeadsetConnected) {
- return R.string.bluetooth_summary_connected_to_headset;
- } else {
- return 0;
- }
- }
-
- public List<Profile> getProfiles() {
- return new ArrayList<Profile>(mProfiles);
- }
-
- public void onCreateContextMenu(ContextMenu menu) {
- // No context menu if it is busy (none of these items are applicable if busy)
- if (isBusy()) return;
-
- int bondState = getBondState();
- boolean isConnected = isConnected();
- boolean hasProfiles = mProfiles.size() > 0;
-
- menu.setHeaderTitle(getName());
-
- if (isConnected) {
- menu.add(0, CONTEXT_ITEM_DISCONNECT, 0, R.string.bluetooth_device_context_disconnect);
- } else if (hasProfiles) {
- // For connection action, show either "Connect" or "Pair & connect"
- int connectString = (bondState == BluetoothDevice.BOND_NOT_BONDED)
- ? R.string.bluetooth_device_context_pair_connect
- : R.string.bluetooth_device_context_connect;
- menu.add(0, CONTEXT_ITEM_CONNECT, 0, connectString);
- }
-
- if (bondState == BluetoothDevice.BOND_BONDED) {
- // For unpair action, show either "Unpair" or "Disconnect & unpair"
- int unpairString = isConnected
- ? R.string.bluetooth_device_context_disconnect_unpair
- : R.string.bluetooth_device_context_unpair;
- menu.add(0, CONTEXT_ITEM_UNPAIR, 0, unpairString);
-
- // Show the connection options item
- menu.add(0, CONTEXT_ITEM_CONNECT_ADVANCED, 0,
- R.string.bluetooth_device_context_connect_advanced);
- }
- }
-
- /**
- * Called when a context menu item is clicked.
- *
- * @param item The item that was clicked.
- */
- public void onContextItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case CONTEXT_ITEM_DISCONNECT:
- disconnect();
- break;
-
- case CONTEXT_ITEM_CONNECT:
- connect();
- break;
-
- case CONTEXT_ITEM_UNPAIR:
- mLocalManager.getBluetoothManager().disconnectRemoteDeviceAcl(mAddress);
- unpair();
- break;
-
- case CONTEXT_ITEM_CONNECT_ADVANCED:
- Intent intent = new Intent();
- // Need an activity context to open this in our task
- Context context = mLocalManager.getForegroundActivity();
- if (context == null) {
- // Fallback on application context, and open in a new task
- context = mLocalManager.getContext();
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- }
- intent.setClass(context, ConnectSpecificProfilesActivity.class);
- intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_ADDRESS, mAddress);
- context.startActivity(intent);
- break;
- }
- }
-
- public void registerCallback(Callback callback) {
- synchronized (mCallbacks) {
- mCallbacks.add(callback);
- }
- }
-
- public void unregisterCallback(Callback callback) {
- synchronized (mCallbacks) {
- mCallbacks.remove(callback);
- }
- }
-
- private void dispatchAttributesChanged() {
- synchronized (mCallbacks) {
- for (Callback callback : mCallbacks) {
- callback.onDeviceAttributesChanged(this);
- }
- }
- }
-
- @Override
- public String toString() {
- return mAddress;
- }
-
- @Override
- public boolean equals(Object o) {
- if ((o == null) || !(o instanceof LocalBluetoothDevice)) {
- throw new ClassCastException();
- }
-
- return mAddress.equals(((LocalBluetoothDevice) o).mAddress);
- }
-
- @Override
- public int hashCode() {
- return mAddress.hashCode();
- }
-
- public int compareTo(LocalBluetoothDevice another) {
- int comparison;
-
- // Connected above not connected
- comparison = (another.isConnected() ? 1 : 0) - (isConnected() ? 1 : 0);
- if (comparison != 0) return comparison;
-
- // Paired above not paired
- comparison = (another.getBondState() == BluetoothDevice.BOND_BONDED ? 1 : 0) -
- (getBondState() == BluetoothDevice.BOND_BONDED ? 1 : 0);
- if (comparison != 0) return comparison;
-
- // Visible above not visible
- comparison = (another.mVisible ? 1 : 0) - (mVisible ? 1 : 0);
- if (comparison != 0) return comparison;
-
- // Stronger signal above weaker signal
- comparison = another.mRssi - mRssi;
- if (comparison != 0) return comparison;
-
- // Fallback on name
- return getName().compareTo(another.getName());
- }
-
- public interface Callback {
- void onDeviceAttributesChanged(LocalBluetoothDevice device);
- }
-}