CachedBluetoothDevice.java revision afc4ab2ffbb8327ddce9907961295a32cbf49d0f
1afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/*
2afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
4afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * you may not use this file except in compliance with the License.
6afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * You may obtain a copy of the License at
7afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
8afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
10afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * See the License for the specific language governing permissions and
14afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * limitations under the License.
15afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
16afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
17afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectpackage com.android.settings.bluetooth;
18afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
19afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport com.android.settings.R;
20afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
21afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
22afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.AlertDialog;
23afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.bluetooth.BluetoothDevice;
24afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.bluetooth.BluetoothClass;
25afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.bluetooth.IBluetoothDeviceCallback;
26afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Context;
27afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.DialogInterface;
28afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent;
29afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.res.Resources;
30afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.IBinder;
31afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.RemoteException;
32afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.text.TextUtils;
33afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.util.Log;
34afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.ContextMenu;
35afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.Menu;
36afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.MenuItem;
37afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
38afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.ArrayList;
39afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.List;
40afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
41afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/**
42afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * LocalBluetoothDevice represents a remote Bluetooth device. It contains
43afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * attributes of the device (such as the address, name, RSSI, etc.) and
44afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * functionality that can be performed on the device (connect, pair, disconnect,
45afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * etc.).
46afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
47afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectpublic class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
48afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final String TAG = "LocalBluetoothDevice";
49afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
50afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int CONTEXT_ITEM_CONNECT = Menu.FIRST + 1;
51afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int CONTEXT_ITEM_DISCONNECT = Menu.FIRST + 2;
52afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int CONTEXT_ITEM_UNPAIR = Menu.FIRST + 3;
53afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int CONTEXT_ITEM_CONNECT_ADVANCED = Menu.FIRST + 4;
54afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
55afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private final String mAddress;
56afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private String mName;
57afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private short mRssi;
58afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private int mBtClass = BluetoothClass.ERROR;
59afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
60afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private List<Profile> mProfiles = new ArrayList<Profile>();
61afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
62afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean mVisible;
63afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
64afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private final LocalBluetoothManager mLocalManager;
65afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
66afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private List<Callback> mCallbacks = new ArrayList<Callback>();
67afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
68afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
69afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * When we connect to multiple profiles, we only want to display a single
70afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * error even if they all fail. This tracks that state.
71afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
72afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean mIsConnectingErrorPossible;
73afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
74afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    LocalBluetoothDevice(Context context, String address) {
75afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mLocalManager = LocalBluetoothManager.getInstance(context);
76afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mLocalManager == null) {
77afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            throw new IllegalStateException(
78afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    "Cannot use LocalBluetoothDevice without Bluetooth hardware");
79afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
80afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
81afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mAddress = address;
82afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
83afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fillData();
84afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
85afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
86afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onClicked() {
87afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int bondState = getBondState();
88afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
89afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (isConnected()) {
90afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            askDisconnect();
91afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (bondState == BluetoothDevice.BOND_BONDED) {
92afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            connect();
93afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (bondState == BluetoothDevice.BOND_NOT_BONDED) {
94afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            pair();
95afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
96afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
97afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
98afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void disconnect() {
99afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
100afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            disconnect(profile);
101afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
102afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
103afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
104afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void disconnect(Profile profile) {
105afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        LocalBluetoothProfileManager profileManager =
106afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
107afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int status = profileManager.getConnectionStatus(mAddress);
108afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (SettingsBtStatus.isConnectionStatusConnected(status)) {
109afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            profileManager.disconnect(mAddress);
110afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
111afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
112afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
113afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void askDisconnect() {
114afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Context context = mLocalManager.getForegroundActivity();
115afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (context == null) {
116afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Cannot ask, since we need an activity context
117afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            disconnect();
118afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return;
119afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
120afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
121afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Resources res = context.getResources();
122afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
123afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        String name = getName();
124afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (TextUtils.isEmpty(name)) {
125afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            name = res.getString(R.string.bluetooth_device);
126afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
127afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        String message = res.getString(R.string.bluetooth_disconnect_blank, name);
128afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
129afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        DialogInterface.OnClickListener disconnectListener = new DialogInterface.OnClickListener() {
130afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            public void onClick(DialogInterface dialog, int which) {
131afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                disconnect();
132afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
133afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        };
134afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
135afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        AlertDialog ad = new AlertDialog.Builder(context)
136afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                .setTitle(getName())
137afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                .setMessage(message)
138afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                .setPositiveButton(android.R.string.ok, disconnectListener)
139afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                .setNegativeButton(android.R.string.cancel, null)
140afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                .show();
141afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
142afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
143afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void connect() {
144afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!ensurePaired()) return;
145afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
146afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Reset the only-show-one-error-dialog tracking variable
147afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mIsConnectingErrorPossible = true;
148afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
149afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Context context = mLocalManager.getContext();
150afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        boolean hasAtLeastOnePreferredProfile = false;
151afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
152afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            LocalBluetoothProfileManager profileManager =
153afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
154afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (profileManager.isPreferred(mAddress)) {
155afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                hasAtLeastOnePreferredProfile = true;
156afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                connectInt(profile);
157afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
158afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
159afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
160afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!hasAtLeastOnePreferredProfile) {
161afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            connectAndPreferAllProfiles();
162afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
163afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
164afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
165afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void connectAndPreferAllProfiles() {
166afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!ensurePaired()) return;
167afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
168afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Reset the only-show-one-error-dialog tracking variable
169afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mIsConnectingErrorPossible = true;
170afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
171afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Context context = mLocalManager.getContext();
172afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
173afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            LocalBluetoothProfileManager profileManager =
174afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
175afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            profileManager.setPreferred(mAddress, true);
176afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            connectInt(profile);
177afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
178afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
179afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
180afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void connect(Profile profile) {
181afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Reset the only-show-one-error-dialog tracking variable
182afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mIsConnectingErrorPossible = true;
183afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        connectInt(profile);
184afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
185afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
186afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void connectInt(Profile profile) {
187afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!ensurePaired()) return;
188afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
189afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        LocalBluetoothProfileManager profileManager =
190afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
191afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int status = profileManager.getConnectionStatus(mAddress);
192afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!SettingsBtStatus.isConnectionStatusConnected(status)) {
193afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (profileManager.connect(mAddress) != BluetoothDevice.RESULT_SUCCESS) {
194afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Log.i(TAG, "Failed to connect " + profile.toString() + " to " + mName);
195afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
196afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
197afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
198afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
199afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void showConnectingError() {
200afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!mIsConnectingErrorPossible) return;
201afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mIsConnectingErrorPossible = false;
202afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
203afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mLocalManager.showError(mAddress, R.string.bluetooth_error_title,
204afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                R.string.bluetooth_connecting_error_message);
205afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
206afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
207afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean ensurePaired() {
208afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (getBondState() == BluetoothDevice.BOND_NOT_BONDED) {
209afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            pair();
210afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return false;
211afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
212afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return true;
213afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
214afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
215afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
216afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void pair() {
217afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        BluetoothDevice manager = mLocalManager.getBluetoothManager();
218afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
219afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Pairing is unreliable while scanning, so cancel discovery
220afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (manager.isDiscovering()) {
221afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            manager.cancelDiscovery();
222afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
223afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
224afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!mLocalManager.getBluetoothManager().createBond(mAddress)) {
225afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mLocalManager.showError(mAddress, R.string.bluetooth_error_title,
226afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    R.string.bluetooth_pairing_error_message);
227afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
228afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
229afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
230afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void unpair() {
231afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        BluetoothDevice manager = mLocalManager.getBluetoothManager();
232afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
233afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        switch (getBondState()) {
234afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        case BluetoothDevice.BOND_BONDED:
235afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            manager.removeBond(mAddress);
236afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            break;
237afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
238afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        case BluetoothDevice.BOND_BONDING:
239afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            manager.cancelBondProcess(mAddress);
240afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            break;
241afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
242afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
243afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
244afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void fillData() {
245afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        BluetoothDevice manager = mLocalManager.getBluetoothManager();
246afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
247afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fetchName();
248afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fetchBtClass();
249afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
250afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mVisible = false;
251afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
252afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        dispatchAttributesChanged();
253afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
254afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
255afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public String getAddress() {
256afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return mAddress;
257afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
258afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
259afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public String getName() {
260afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return mName;
261afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
262afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
263afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void refreshName() {
264afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fetchName();
265afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        dispatchAttributesChanged();
266afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
267afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
268afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void fetchName() {
269afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mName = mLocalManager.getBluetoothManager().getRemoteName(mAddress);
270afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
271afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (TextUtils.isEmpty(mName)) {
272afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mName = mAddress;
273afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
274afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
275afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
276afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void refresh() {
277afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        dispatchAttributesChanged();
278afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
279afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
280afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean isVisible() {
281afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return mVisible;
282afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
283afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
284afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    void setVisible(boolean visible) {
285afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mVisible != visible) {
286afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mVisible = visible;
287afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            dispatchAttributesChanged();
288afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
289afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
290afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
291afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public int getBondState() {
292afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return mLocalManager.getBluetoothManager().getBondState(mAddress);
293afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
294afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
295afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    void setRssi(short rssi) {
296afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mRssi != rssi) {
297afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mRssi = rssi;
298afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            dispatchAttributesChanged();
299afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
300afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
301afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
302afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
303afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Checks whether we are connected to this device (any profile counts).
304afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     *
305afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * @return Whether it is connected.
306afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
307afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean isConnected() {
308afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
309afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
310afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    .getConnectionStatus(mAddress);
311afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (SettingsBtStatus.isConnectionStatusConnected(status)) {
312afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return true;
313afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
314afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
315afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
316afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return false;
317afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
318afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
319afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean isBusy() {
320afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
321afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
322afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    .getConnectionStatus(mAddress);
323afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (SettingsBtStatus.isConnectionStatusBusy(status)) {
324afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return true;
325afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
326afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
327afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
328afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (getBondState() == BluetoothDevice.BOND_BONDING) {
329afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return true;
330afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
331afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
332afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return false;
333afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
334afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
335afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public int getBtClassDrawable() {
336afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
337afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // First try looking at profiles
338afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mProfiles.contains(Profile.A2DP)) {
339afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return R.drawable.ic_bt_headphones_a2dp;
340afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (mProfiles.contains(Profile.HEADSET)) {
341afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return R.drawable.ic_bt_headset_hfp;
342afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
343afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
344afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Fallback on class
345afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        switch (BluetoothClass.Device.Major.getDeviceMajor(mBtClass)) {
346afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        case BluetoothClass.Device.Major.COMPUTER:
347afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return R.drawable.ic_bt_laptop;
348afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
349afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        case BluetoothClass.Device.Major.PHONE:
350afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return R.drawable.ic_bt_cellphone;
351afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
352afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        default:
353afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return 0;
354afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
355afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
356afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
357afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
358afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Fetches a new value for the cached BT class.
359afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
360afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void fetchBtClass() {
361afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mBtClass = mLocalManager.getBluetoothManager().getRemoteClass(mAddress);
362afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mProfiles.clear();
363afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        LocalBluetoothProfileManager.fill(mBtClass, mProfiles);
364afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
365afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
366afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
367afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Refreshes the UI for the BT class, including fetching the latest value
368afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * for the class.
369afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
370afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void refreshBtClass() {
371afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fetchBtClass();
372afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        dispatchAttributesChanged();
373afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
374afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
375afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public int getSummary() {
376afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // TODO: clean up
377afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int oneOffSummary = getOneOffSummary();
378afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (oneOffSummary != 0) {
379afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return oneOffSummary;
380afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
381afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
382afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
383afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
384afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    .getProfileManager(mLocalManager, profile);
385afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            int connectionStatus = profileManager.getConnectionStatus(mAddress);
386afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
387afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus) ||
388afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    connectionStatus == SettingsBtStatus.CONNECTION_STATUS_CONNECTING ||
389afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING) {
390afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
391afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
392afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
393afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
394afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return SettingsBtStatus.getPairingStatusSummary(getBondState());
395afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
396afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
397afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
398afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * We have special summaries when particular profiles are connected. This
399afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * checks for those states and returns an applicable summary.
400afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     *
401afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * @return A one-off summary that is applicable for the current state, or 0.
402afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
403afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private int getOneOffSummary() {
404afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        boolean isA2dpConnected = false, isHeadsetConnected = false, isConnecting = false;
405afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
406afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mProfiles.contains(Profile.A2DP)) {
407afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
408afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    .getProfileManager(mLocalManager, Profile.A2DP);
409afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            isConnecting = profileManager.getConnectionStatus(mAddress) ==
410afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
411afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            isA2dpConnected = profileManager.isConnected(mAddress);
412afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
413afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
414afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mProfiles.contains(Profile.HEADSET)) {
415afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
416afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    .getProfileManager(mLocalManager, Profile.HEADSET);
417afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            isConnecting |= profileManager.getConnectionStatus(mAddress) ==
418afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
419afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            isHeadsetConnected = profileManager.isConnected(mAddress);
420afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
421afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
422afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (isConnecting) {
423afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // If any of these important profiles is connecting, prefer that
424afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return SettingsBtStatus.getConnectionStatusSummary(
425afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    SettingsBtStatus.CONNECTION_STATUS_CONNECTING);
426afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (isA2dpConnected && isHeadsetConnected) {
427afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return R.string.bluetooth_summary_connected_to_a2dp_headset;
428afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (isA2dpConnected) {
429afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return R.string.bluetooth_summary_connected_to_a2dp;
430afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (isHeadsetConnected) {
431afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return R.string.bluetooth_summary_connected_to_headset;
432afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
433afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return 0;
434afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
435afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
436afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
437afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public List<Profile> getProfiles() {
438afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return new ArrayList<Profile>(mProfiles);
439afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
440afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
441afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu) {
442afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // No context menu if it is busy (none of these items are applicable if busy)
443afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (isBusy()) return;
444afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
445afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int bondState = getBondState();
446afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        boolean isConnected = isConnected();
447afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        boolean hasProfiles = mProfiles.size() > 0;
448afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
449afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        menu.setHeaderTitle(getName());
450afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
451afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (isConnected) {
452afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            menu.add(0, CONTEXT_ITEM_DISCONNECT, 0, R.string.bluetooth_device_context_disconnect);
453afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (hasProfiles) {
454afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // For connection action, show either "Connect" or "Pair & connect"
455afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            int connectString = (bondState == BluetoothDevice.BOND_NOT_BONDED)
456afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    ? R.string.bluetooth_device_context_pair_connect
457afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    : R.string.bluetooth_device_context_connect;
458afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            menu.add(0, CONTEXT_ITEM_CONNECT, 0, connectString);
459afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
460afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
461afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (bondState == BluetoothDevice.BOND_BONDED) {
462afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // For unpair action, show either "Unpair" or "Disconnect & unpair"
463afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            int unpairString = isConnected
464afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    ? R.string.bluetooth_device_context_disconnect_unpair
465afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    : R.string.bluetooth_device_context_unpair;
466afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            menu.add(0, CONTEXT_ITEM_UNPAIR, 0, unpairString);
467afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
468afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Show the connection options item
469afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            menu.add(0, CONTEXT_ITEM_CONNECT_ADVANCED, 0,
470afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    R.string.bluetooth_device_context_connect_advanced);
471afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
472afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
473afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
474afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
475afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Called when a context menu item is clicked.
476afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     *
477afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * @param item The item that was clicked.
478afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
479afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onContextItemSelected(MenuItem item) {
480afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        switch (item.getItemId()) {
481afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case CONTEXT_ITEM_DISCONNECT:
482afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                disconnect();
483afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
484afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
485afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case CONTEXT_ITEM_CONNECT:
486afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                connect();
487afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
488afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
489afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case CONTEXT_ITEM_UNPAIR:
490afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mLocalManager.getBluetoothManager().disconnectRemoteDeviceAcl(mAddress);
491afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                unpair();
492afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
493afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
494afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case CONTEXT_ITEM_CONNECT_ADVANCED:
495afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Intent intent = new Intent();
496afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // Need an activity context to open this in our task
497afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Context context = mLocalManager.getForegroundActivity();
498afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if (context == null) {
499afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    // Fallback on application context, and open in a new task
500afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    context = mLocalManager.getContext();
501afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
502afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
503afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                intent.setClass(context, ConnectSpecificProfilesActivity.class);
504afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_ADDRESS, mAddress);
505afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                context.startActivity(intent);
506afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
507afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
508afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
509afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
510afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void registerCallback(Callback callback) {
511afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        synchronized (mCallbacks) {
512afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mCallbacks.add(callback);
513afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
514afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
515afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
516afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void unregisterCallback(Callback callback) {
517afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        synchronized (mCallbacks) {
518afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mCallbacks.remove(callback);
519afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
520afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
521afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
522afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void dispatchAttributesChanged() {
523afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        synchronized (mCallbacks) {
524afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            for (Callback callback : mCallbacks) {
525afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                callback.onDeviceAttributesChanged(this);
526afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
527afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
528afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
529afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
530afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
531afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public String toString() {
532afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return mAddress;
533afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
534afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
535afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
536afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean equals(Object o) {
537afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if ((o == null) || !(o instanceof LocalBluetoothDevice)) {
538afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            throw new ClassCastException();
539afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
540afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
541afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return mAddress.equals(((LocalBluetoothDevice) o).mAddress);
542afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
543afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
544afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
545afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public int hashCode() {
546afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return mAddress.hashCode();
547afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
548afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
549afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public int compareTo(LocalBluetoothDevice another) {
550afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int comparison;
551afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
552afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Connected above not connected
553afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        comparison = (another.isConnected() ? 1 : 0) - (isConnected() ? 1 : 0);
554afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (comparison != 0) return comparison;
555afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
556afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Paired above not paired
557afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        comparison = (another.getBondState() == BluetoothDevice.BOND_BONDED ? 1 : 0) -
558afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            (getBondState() == BluetoothDevice.BOND_BONDED ? 1 : 0);
559afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (comparison != 0) return comparison;
560afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
561afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Visible above not visible
562afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        comparison = (another.mVisible ? 1 : 0) - (mVisible ? 1 : 0);
563afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (comparison != 0) return comparison;
564afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
565afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Stronger signal above weaker signal
566afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        comparison = another.mRssi - mRssi;
567afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (comparison != 0) return comparison;
568afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
569afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Fallback on name
570afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return getName().compareTo(another.getName());
571afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
572afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
573afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public interface Callback {
574afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        void onDeviceAttributesChanged(LocalBluetoothDevice device);
575afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
576afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
577