CachedBluetoothDevice.java revision 659b39abf8580a49bd77f194c9ac30359f610709
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 android.app.AlertDialog;
20d63c0112251ab4e4e977545368dd703d875012a4Nick Pellyimport android.bluetooth.BluetoothAdapter;
212aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chanimport android.bluetooth.BluetoothClass;
22e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Projectimport android.bluetooth.BluetoothDevice;
23afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Context;
24afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.DialogInterface;
25afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent;
26afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.res.Resources;
27e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chanimport android.os.ParcelUuid;
282aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chanimport android.os.SystemClock;
29afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.text.TextUtils;
30afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.util.Log;
31afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.ContextMenu;
32afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.Menu;
33afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.MenuItem;
34afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
356c97742c88303c65e68fe08257a7ccf841f03866Michael Chanimport com.android.settings.R;
366c97742c88303c65e68fe08257a7ccf841f03866Michael Chanimport com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
376c97742c88303c65e68fe08257a7ccf841f03866Michael Chan
38afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.ArrayList;
39afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.List;
403327f7887328c55ef2d837a8e2a07cea2070c744Michael Chanimport java.util.Set;
41afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
42afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/**
43d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly * CachedBluetoothDevice represents a remote Bluetooth device. It contains
44afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * attributes of the device (such as the address, name, RSSI, etc.) and
45afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * functionality that can be performed on the device (connect, pair, disconnect,
46afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * etc.).
47afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
48d63c0112251ab4e4e977545368dd703d875012a4Nick Pellypublic class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> {
49d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    private static final String TAG = "CachedBluetoothDevice";
50f25063aee3d8eeaf3767b3a4bf43e1895f2deb2dMichael Chan    private static final boolean D = LocalBluetoothManager.D;
51f25063aee3d8eeaf3767b3a4bf43e1895f2deb2dMichael Chan    private static final boolean V = LocalBluetoothManager.V;
52293867bd109383a1a26b35bf6accb92c0bad264cMichael Chan    private static final boolean DEBUG = false;
53afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
54afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int CONTEXT_ITEM_CONNECT = Menu.FIRST + 1;
55afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int CONTEXT_ITEM_DISCONNECT = Menu.FIRST + 2;
56afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int CONTEXT_ITEM_UNPAIR = Menu.FIRST + 3;
57afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int CONTEXT_ITEM_CONNECT_ADVANCED = Menu.FIRST + 4;
58afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
5932711b6752eb73324e1b10db975ac956888eda96Danica Chang    public static final int PAN_PROFILE = 1;
6032711b6752eb73324e1b10db975ac956888eda96Danica Chang    public static final int OTHER_PROFILES = 2;
6132711b6752eb73324e1b10db975ac956888eda96Danica Chang
62d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    private final BluetoothDevice mDevice;
63afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private String mName;
64afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private short mRssi;
6516cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly    private BluetoothClass mBtClass;
66afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
67afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private List<Profile> mProfiles = new ArrayList<Profile>();
68afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
69afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean mVisible;
70afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
71afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private final LocalBluetoothManager mLocalManager;
72afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
7320108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai    private AlertDialog mDialog = null;
7420108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai
75afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private List<Callback> mCallbacks = new ArrayList<Callback>();
76afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
77afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
78afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * When we connect to multiple profiles, we only want to display a single
79afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * error even if they all fail. This tracks that state.
80afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
81afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean mIsConnectingErrorPossible;
82afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
832aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    /**
84eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan     * Last time a bt profile auto-connect was attempted.
85eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan     * If an ACTION_UUID intent comes in within
862aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan     * MAX_UUID_DELAY_FOR_AUTO_CONNECT milliseconds, we will try auto-connect
872aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan     * again with the new UUIDs
882aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan     */
89eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    private long mConnectAttempted;
902aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
91eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    // See mConnectAttempted
922aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    private static final long MAX_UUID_DELAY_FOR_AUTO_CONNECT = 5000;
932aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
94dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby    /** Auto-connect after pairing only if locally initiated. */
95dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby    private boolean mConnectAfterPairing;
9684905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh
97e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project    /**
98f907e0bb891eca4d498871a1cc862117a462a076Adam Powell     * Describes the current device and profile for logging.
9984905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh     *
100f907e0bb891eca4d498871a1cc862117a462a076Adam Powell     * @param profile Profile to describe
101f907e0bb891eca4d498871a1cc862117a462a076Adam Powell     * @return Description of the device and profile
102e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project     */
103f907e0bb891eca4d498871a1cc862117a462a076Adam Powell    private String describe(CachedBluetoothDevice cachedDevice, Profile profile) {
104f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        StringBuilder sb = new StringBuilder();
105f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        sb.append("Address:").append(cachedDevice.mDevice);
106f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        if (profile != null) {
107f907e0bb891eca4d498871a1cc862117a462a076Adam Powell            sb.append(" Profile:").append(profile.name());
108097ed6c671ed733c0967acc32e017020ede4575bMichael Chan        }
109e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
110f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        return sb.toString();
111f907e0bb891eca4d498871a1cc862117a462a076Adam Powell    }
11284905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh
113f907e0bb891eca4d498871a1cc862117a462a076Adam Powell    private String describe(Profile profile) {
114f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        return describe(this, profile);
115e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project    }
116e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
1176c97742c88303c65e68fe08257a7ccf841f03866Michael Chan    public void onProfileStateChanged(Profile profile, int newProfileState) {
118f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        if (D) {
119f907e0bb891eca4d498871a1cc862117a462a076Adam Powell            Log.d(TAG, "onProfileStateChanged: profile " + profile.toString() +
120f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                    " newProfileState " + newProfileState);
1216c97742c88303c65e68fe08257a7ccf841f03866Michael Chan        }
122e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
123f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        int newState = LocalBluetoothProfileManager.getProfileManager(mLocalManager,
124f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                profile).convertState(newProfileState);
125f907e0bb891eca4d498871a1cc862117a462a076Adam Powell
126f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        if (newState == SettingsBtStatus.CONNECTION_STATUS_CONNECTED) {
127f907e0bb891eca4d498871a1cc862117a462a076Adam Powell            if (!mProfiles.contains(profile)) {
128f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                mProfiles.add(profile);
129e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project            }
130e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        }
131e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project    }
132e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
133d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    CachedBluetoothDevice(Context context, BluetoothDevice device) {
134afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mLocalManager = LocalBluetoothManager.getInstance(context);
135afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mLocalManager == null) {
136afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            throw new IllegalStateException(
137d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly                    "Cannot use CachedBluetoothDevice without Bluetooth hardware");
138afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
139afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
140d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        mDevice = device;
141afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
142afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fillData();
143afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
144afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
145afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onClicked() {
146afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int bondState = getBondState();
147afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
148afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (isConnected()) {
149afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            askDisconnect();
150afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (bondState == BluetoothDevice.BOND_BONDED) {
151afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            connect();
15216cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly        } else if (bondState == BluetoothDevice.BOND_NONE) {
153afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            pair();
154afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
155afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
156afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
157afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void disconnect() {
158afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
159afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            disconnect(profile);
160afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
161afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
162afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
163afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void disconnect(Profile profile) {
164f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        disconnectInt(this, profile);
165e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project    }
166e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
167d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    private boolean disconnectInt(CachedBluetoothDevice cachedDevice, Profile profile) {
168afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        LocalBluetoothProfileManager profileManager =
169afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
170d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        int status = profileManager.getConnectionStatus(cachedDevice.mDevice);
171d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh        if (profileManager.disconnect(cachedDevice.mDevice)) {
172d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh            if (D) {
173d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh                Log.d(TAG, "Command sent successfully:DISCONNECT " + describe(profile));
174f907e0bb891eca4d498871a1cc862117a462a076Adam Powell            }
175d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh            return true;
176afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
177e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        return false;
178afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
179afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
180afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void askDisconnect() {
181afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Context context = mLocalManager.getForegroundActivity();
182afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (context == null) {
183afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Cannot ask, since we need an activity context
184afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            disconnect();
185afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return;
186afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
187afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
188afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Resources res = context.getResources();
189afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
190afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        String name = getName();
191afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (TextUtils.isEmpty(name)) {
192afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            name = res.getString(R.string.bluetooth_device);
193afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
194afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        String message = res.getString(R.string.bluetooth_disconnect_blank, name);
195afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
196afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        DialogInterface.OnClickListener disconnectListener = new DialogInterface.OnClickListener() {
197afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            public void onClick(DialogInterface dialog, int which) {
198afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                disconnect();
199afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
200afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        };
201afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
20220108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        if (mDialog == null) {
20320108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai            mDialog = new AlertDialog.Builder(context)
20420108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai                    .setPositiveButton(android.R.string.ok, disconnectListener)
20520108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai                    .setNegativeButton(android.R.string.cancel, null)
20620108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai                    .create();
20720108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        } else {
20820108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai            if (mDialog.isShowing()) {
20920108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai                mDialog.dismiss();
21020108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai            }
21120108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        }
21220108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        mDialog.setTitle(getName());
21320108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        mDialog.setMessage(message);
21420108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        mDialog.show();
21520108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai    }
21620108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai
21720108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai    @Override
21820108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai    protected void finalize() throws Throwable {
21920108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        if (mDialog != null) {
22020108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai            mDialog.dismiss();
22120108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai            mDialog = null;
22220108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        }
22320108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai
22420108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        super.finalize();
225afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
226afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
227afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void connect() {
228afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!ensurePaired()) return;
229afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
230eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        mConnectAttempted = SystemClock.elapsedRealtime();
231eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan
232eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        connectWithoutResettingTimer();
233eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    }
234eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan
235b172cd5d232bd650d6efbb7d8b5e4cf9c213952fJaikumar Ganesh    /*package*/ void onBondingDockConnect() {
236582f1f84bb0ad4315ce17826672298c68f1c3b38Jake Hamby        // Attempt to connect if UUIDs are available. Otherwise,
237582f1f84bb0ad4315ce17826672298c68f1c3b38Jake Hamby        // we will connect when the ACTION_UUID intent arrives.
238582f1f84bb0ad4315ce17826672298c68f1c3b38Jake Hamby        connect();
239b172cd5d232bd650d6efbb7d8b5e4cf9c213952fJaikumar Ganesh    }
240b172cd5d232bd650d6efbb7d8b5e4cf9c213952fJaikumar Ganesh
241eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    private void connectWithoutResettingTimer() {
2422aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        // Try to initialize the profiles if there were not.
2432aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        if (mProfiles.size() == 0) {
2442aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            if (!updateProfiles()) {
2452aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                // If UUIDs are not available yet, connect will be happen
2462aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                // upon arrival of the ACTION_UUID intent.
247eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan                if (DEBUG) Log.d(TAG, "No profiles. Maybe we will connect later");
2482aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                return;
2492aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            }
2502aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        }
2512aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
252afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Reset the only-show-one-error-dialog tracking variable
253afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mIsConnectingErrorPossible = true;
254afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
255eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        int preferredProfiles = 0;
256afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
257b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan            if (isConnectableProfile(profile)) {
258b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
259b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                        .getProfileManager(mLocalManager, profile);
260b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                if (profileManager.isPreferred(mDevice)) {
261b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                    ++preferredProfiles;
26284905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh                    disconnectConnected(this, profile);
263f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                    connectInt(this, profile);
264b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                }
265afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
266afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
267eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        if (DEBUG) Log.d(TAG, "Preferred profiles = " + preferredProfiles);
268afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
269eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        if (preferredProfiles == 0) {
270eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan            connectAllProfiles();
271afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
272afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
273afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
274eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    private void connectAllProfiles() {
275afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!ensurePaired()) return;
276afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
277afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Reset the only-show-one-error-dialog tracking variable
278afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mIsConnectingErrorPossible = true;
279afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
280afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
281b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan            if (isConnectableProfile(profile)) {
282b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
283b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                        .getProfileManager(mLocalManager, profile);
284b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                profileManager.setPreferred(mDevice, false);
28584905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh                disconnectConnected(this, profile);
286f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                connectInt(this, profile);
287b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan            }
288afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
289afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
290afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
291afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void connect(Profile profile) {
292eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        mConnectAttempted = SystemClock.elapsedRealtime();
293afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Reset the only-show-one-error-dialog tracking variable
294afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mIsConnectingErrorPossible = true;
29584905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh        disconnectConnected(this, profile);
296f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        connectInt(this, profile);
297afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
298afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
29984905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh    private void disconnectConnected(CachedBluetoothDevice device, Profile profile) {
3003327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan        LocalBluetoothProfileManager profileManager =
3013327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan            LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
3023327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan        CachedBluetoothDeviceManager cachedDeviceManager = mLocalManager.getCachedDeviceManager();
303659b39abf8580a49bd77f194c9ac30359f610709Jaikumar Ganesh        List<BluetoothDevice> devices = profileManager.getConnectedDevices();
3043327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan        if (devices == null) return;
30584905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh        for (BluetoothDevice btDevice : devices) {
30684905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh            CachedBluetoothDevice cachedDevice = cachedDeviceManager.findDevice(btDevice);
30784905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh
30884905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh            if (cachedDevice != null && !cachedDevice.equals(device)) {
309f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                disconnectInt(cachedDevice, profile);
3103327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan            }
3113327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan        }
3123327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan    }
3133327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan
314d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    private boolean connectInt(CachedBluetoothDevice cachedDevice, Profile profile) {
315d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        if (!cachedDevice.ensurePaired()) return false;
316afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
317afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        LocalBluetoothProfileManager profileManager =
318afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
319d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        int status = profileManager.getConnectionStatus(cachedDevice.mDevice);
320d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh        if (profileManager.connect(cachedDevice.mDevice)) {
321d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh            if (D) {
322d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh                Log.d(TAG, "Command sent successfully:CONNECT " + describe(profile));
323afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
324d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh            return true;
325afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
326d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh        Log.i(TAG, "Failed to connect " + profile.toString() + " to " + cachedDevice.mName);
327f907e0bb891eca4d498871a1cc862117a462a076Adam Powell
328e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        return false;
329afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
330afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
331afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void showConnectingError() {
332afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!mIsConnectingErrorPossible) return;
333afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mIsConnectingErrorPossible = false;
334afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
335d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        mLocalManager.showError(mDevice, R.string.bluetooth_error_title,
336afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                R.string.bluetooth_connecting_error_message);
337afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
338afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
339afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean ensurePaired() {
34016cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly        if (getBondState() == BluetoothDevice.BOND_NONE) {
341afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            pair();
342afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return false;
343afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
344afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return true;
345afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
346afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
347afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
348afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void pair() {
349d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        BluetoothAdapter adapter = mLocalManager.getBluetoothAdapter();
350afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
351afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Pairing is unreliable while scanning, so cancel discovery
352d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        if (adapter.isDiscovering()) {
353d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            adapter.cancelDiscovery();
354afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
355afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
356d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        if (!mDevice.createBond()) {
357d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            mLocalManager.showError(mDevice, R.string.bluetooth_error_title,
358afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    R.string.bluetooth_pairing_error_message);
359dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby            return;
360afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
361dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby
362dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby        mConnectAfterPairing = true;  // auto-connect after pairing
363afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
364afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
365afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void unpair() {
36696b0c1dc0813f7e8c957ec17dc7751693926c6aeMichael Chan        disconnect();
367e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
36896b0c1dc0813f7e8c957ec17dc7751693926c6aeMichael Chan        int state = getBondState();
369afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
37096b0c1dc0813f7e8c957ec17dc7751693926c6aeMichael Chan        if (state == BluetoothDevice.BOND_BONDING) {
371d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            mDevice.cancelBondProcess();
37296b0c1dc0813f7e8c957ec17dc7751693926c6aeMichael Chan        }
37396b0c1dc0813f7e8c957ec17dc7751693926c6aeMichael Chan
37496b0c1dc0813f7e8c957ec17dc7751693926c6aeMichael Chan        if (state != BluetoothDevice.BOND_NONE) {
375f907e0bb891eca4d498871a1cc862117a462a076Adam Powell            final BluetoothDevice dev = getDevice();
376f907e0bb891eca4d498871a1cc862117a462a076Adam Powell            if (dev != null) {
377f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                final boolean successful = dev.removeBond();
378f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                if (successful) {
379f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                    if (D) {
380f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                        Log.d(TAG, "Command sent successfully:REMOVE_BOND " + describe(null));
381f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                    }
382f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                } else if (V) {
383f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                    Log.v(TAG, "Framework rejected command immediately:REMOVE_BOND " +
384f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                            describe(null));
385f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                }
386f907e0bb891eca4d498871a1cc862117a462a076Adam Powell            }
387afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
388afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
389afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
390afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void fillData() {
391afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fetchName();
392afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fetchBtClass();
3932aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        updateProfiles();
394afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
395afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mVisible = false;
396afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
397afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        dispatchAttributesChanged();
398afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
399afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
400d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    public BluetoothDevice getDevice() {
401d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        return mDevice;
402afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
403afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
404afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public String getName() {
405afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return mName;
406afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
407afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
408d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh    public void setName(String name) {
409d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh        if (!mName.equals(name)) {
410d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh            if (TextUtils.isEmpty(name)) {
411d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly                mName = mDevice.getAddress();
412d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh            } else {
413d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh                mName = name;
414d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh            }
415d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh            dispatchAttributesChanged();
416d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh        }
417d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh    }
418d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh
419afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void refreshName() {
420afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fetchName();
421afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        dispatchAttributesChanged();
422afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
423afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
424afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void fetchName() {
425d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        mName = mDevice.getName();
426afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
427afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (TextUtils.isEmpty(mName)) {
428d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            mName = mDevice.getAddress();
429eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan            if (DEBUG) Log.d(TAG, "Default to address. Device has no name (yet) " + mName);
430afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
431afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
432afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
433afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void refresh() {
434afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        dispatchAttributesChanged();
435afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
436afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
437afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean isVisible() {
438afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return mVisible;
439afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
440afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
441afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    void setVisible(boolean visible) {
442afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mVisible != visible) {
443afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mVisible = visible;
444afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            dispatchAttributesChanged();
445afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
446afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
447afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
448afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public int getBondState() {
449d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        return mDevice.getBondState();
450afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
451afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
452afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    void setRssi(short rssi) {
453afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mRssi != rssi) {
454afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mRssi = rssi;
455afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            dispatchAttributesChanged();
456afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
457afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
458afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
459afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
460afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Checks whether we are connected to this device (any profile counts).
461afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     *
462afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * @return Whether it is connected.
463afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
464afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean isConnected() {
465afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
466afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
467d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly                    .getConnectionStatus(mDevice);
468afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (SettingsBtStatus.isConnectionStatusConnected(status)) {
469afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return true;
470afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
471afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
472afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
473afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return false;
474afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
475afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
476afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean isBusy() {
477afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
478afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
479d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly                    .getConnectionStatus(mDevice);
480afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (SettingsBtStatus.isConnectionStatusBusy(status)) {
481afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return true;
482afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
483afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
484afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
485afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (getBondState() == BluetoothDevice.BOND_BONDING) {
486afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return true;
487afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
488afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
489afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return false;
490afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
491afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
492afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public int getBtClassDrawable() {
4934d004e910732565ddd449c7c525f7d6cbd353392Michael Chan        if (mBtClass != null) {
4944d004e910732565ddd449c7c525f7d6cbd353392Michael Chan            switch (mBtClass.getMajorDeviceClass()) {
4954d004e910732565ddd449c7c525f7d6cbd353392Michael Chan            case BluetoothClass.Device.Major.COMPUTER:
4964d004e910732565ddd449c7c525f7d6cbd353392Michael Chan                return R.drawable.ic_bt_laptop;
497afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
4984d004e910732565ddd449c7c525f7d6cbd353392Michael Chan            case BluetoothClass.Device.Major.PHONE:
4994d004e910732565ddd449c7c525f7d6cbd353392Michael Chan                return R.drawable.ic_bt_cellphone;
5004d004e910732565ddd449c7c525f7d6cbd353392Michael Chan            }
5014d004e910732565ddd449c7c525f7d6cbd353392Michael Chan        } else {
5024d004e910732565ddd449c7c525f7d6cbd353392Michael Chan            Log.w(TAG, "mBtClass is null");
5033e1c1d19201e625888cdd07e06ea9502d7c4dafbMichael Chan        }
504afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
505cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan        if (mProfiles.size() > 0) {
506cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            if (mProfiles.contains(Profile.A2DP)) {
507cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan                return R.drawable.ic_bt_headphones_a2dp;
508cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            } else if (mProfiles.contains(Profile.HEADSET)) {
509cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan                return R.drawable.ic_bt_headset_hfp;
510cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            }
5114d004e910732565ddd449c7c525f7d6cbd353392Michael Chan        } else if (mBtClass != null) {
512cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            if (mBtClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) {
513cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan                return R.drawable.ic_bt_headphones_a2dp;
514cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan
515cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            }
516cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            if (mBtClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) {
517cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan                return R.drawable.ic_bt_headset_hfp;
518cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            }
519afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
520cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan        return 0;
521afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
522afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
523afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
524afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Fetches a new value for the cached BT class.
525afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
526afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void fetchBtClass() {
527d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        mBtClass = mDevice.getBluetoothClass();
5282aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    }
5292aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
5302aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    private boolean updateProfiles() {
5312aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        ParcelUuid[] uuids = mDevice.getUuids();
5322aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        if (uuids == null) return false;
5332aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
5342aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        LocalBluetoothProfileManager.updateProfiles(uuids, mProfiles);
5352aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
5362aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        if (DEBUG) {
5372aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            Log.e(TAG, "updating profiles for " + mDevice.getName());
5382aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
5392aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            boolean printUuids = true;
5402aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            BluetoothClass bluetoothClass = mDevice.getBluetoothClass();
5412aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
542a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan            if (bluetoothClass != null) {
543a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET) !=
544a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    mProfiles.contains(Profile.HEADSET)) {
545a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    Log.v(TAG, "headset classbits != uuid");
546a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    printUuids = true;
547a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                }
5482aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
549a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_A2DP) !=
550a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    mProfiles.contains(Profile.A2DP)) {
551a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    Log.v(TAG, "a2dp classbits != uuid");
552a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    printUuids = true;
553a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                }
5542aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
555a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_OPP) !=
556a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    mProfiles.contains(Profile.OPP)) {
557a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    Log.v(TAG, "opp classbits != uuid");
558a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    printUuids = true;
559a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                }
560792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell
561792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_HID) !=
562792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                    mProfiles.contains(Profile.HID)) {
563792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                    Log.v(TAG, "hid classbits != uuid");
564792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                    printUuids = true;
565792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                }
5662aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            }
5672aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
5682aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            if (printUuids) {
569a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                if (bluetoothClass != null) Log.v(TAG, "Class: " + bluetoothClass.toString());
5702aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                Log.v(TAG, "UUID:");
5712aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                for (int i = 0; i < uuids.length; i++) {
5722aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                    Log.v(TAG, "  " + uuids[i]);
5732aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                }
5742aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            }
575b20dd917e2d29045225985baa980a2a8e22e10fcNick Pelly        }
5762aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        return true;
577afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
578afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
579afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
580afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Refreshes the UI for the BT class, including fetching the latest value
581afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * for the class.
582afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
583afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void refreshBtClass() {
584afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fetchBtClass();
585afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        dispatchAttributesChanged();
586afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
587afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
5882aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    /**
5892aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan     * Refreshes the UI when framework alerts us of a UUID change.
5902aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan     */
5912aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    public void onUuidChanged() {
5922aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        updateProfiles();
5932aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
594eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        if (DEBUG) {
595eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan            Log.e(TAG, "onUuidChanged: Time since last connect"
596eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan                    + (SystemClock.elapsedRealtime() - mConnectAttempted));
597eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        }
5982aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
5992aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        /*
6002aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan         * If a connect was attempted earlier without any UUID, we will do the
6012aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan         * connect now.
6022aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan         */
6032aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        if (mProfiles.size() > 0
604eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan                && (mConnectAttempted + MAX_UUID_DELAY_FOR_AUTO_CONNECT) > SystemClock
6052aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                        .elapsedRealtime()) {
606eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan            connectWithoutResettingTimer();
6072aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        }
6082aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        dispatchAttributesChanged();
6092aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    }
6102aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
611eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    public void onBondingStateChanged(int bondState) {
612eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        if (bondState == BluetoothDevice.BOND_NONE) {
613eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan            mProfiles.clear();
614dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby            mConnectAfterPairing = false;  // cancel auto-connect
615eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        }
6161308453b16c2ca85a456bd4bb7f3c71c916bd83eMichael Chan
617eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        refresh();
618dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby
619dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby        if (bondState == BluetoothDevice.BOND_BONDED) {
620dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby            if (mDevice.isBluetoothDock()) {
621dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby                onBondingDockConnect();
622dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby            } else if (mConnectAfterPairing) {
623dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby                connect();
624dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby            }
625dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby            mConnectAfterPairing = false;
626dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby        }
627eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    }
628eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan
62916cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly    public void setBtClass(BluetoothClass btClass) {
63016cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly        if (btClass != null && mBtClass != btClass) {
631d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh            mBtClass = btClass;
632d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh            dispatchAttributesChanged();
633d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh        }
634d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh    }
635d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh
63632711b6752eb73324e1b10db975ac956888eda96Danica Chang    public int getSummary(int accessibleProfile) {
637afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // TODO: clean up
63832711b6752eb73324e1b10db975ac956888eda96Danica Chang        int oneOffSummary = getOneOffSummary(accessibleProfile);
639afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (oneOffSummary != 0) {
640afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return oneOffSummary;
641afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
642afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
643afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
644afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
645afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    .getProfileManager(mLocalManager, profile);
646d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            int connectionStatus = profileManager.getConnectionStatus(mDevice);
647afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
648afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus) ||
649afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    connectionStatus == SettingsBtStatus.CONNECTION_STATUS_CONNECTING ||
650afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING) {
651afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
652afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
653afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
654afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
655afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return SettingsBtStatus.getPairingStatusSummary(getBondState());
656afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
657afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
658afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
659afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * We have special summaries when particular profiles are connected. This
660afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * checks for those states and returns an applicable summary.
661afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     *
662afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * @return A one-off summary that is applicable for the current state, or 0.
663afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
66432711b6752eb73324e1b10db975ac956888eda96Danica Chang    private int getOneOffSummary(int accessibleProfile) {
665792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        boolean isA2dpConnected = false;
666792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        boolean isHeadsetConnected = false;
667792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        boolean isHidConnected = false;
66832711b6752eb73324e1b10db975ac956888eda96Danica Chang        boolean isPanConnected = false;
669792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        boolean isConnecting = false;
670afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
67132711b6752eb73324e1b10db975ac956888eda96Danica Chang        if (accessibleProfile == OTHER_PROFILES) {
67232711b6752eb73324e1b10db975ac956888eda96Danica Chang            if (mProfiles.contains(Profile.A2DP)) {
67332711b6752eb73324e1b10db975ac956888eda96Danica Chang                LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
67432711b6752eb73324e1b10db975ac956888eda96Danica Chang                        .getProfileManager(mLocalManager, Profile.A2DP);
67532711b6752eb73324e1b10db975ac956888eda96Danica Chang                isConnecting = profileManager.getConnectionStatus(mDevice) ==
67632711b6752eb73324e1b10db975ac956888eda96Danica Chang                        SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
67732711b6752eb73324e1b10db975ac956888eda96Danica Chang                isA2dpConnected = profileManager.isConnected(mDevice);
67832711b6752eb73324e1b10db975ac956888eda96Danica Chang            }
679afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
68032711b6752eb73324e1b10db975ac956888eda96Danica Chang            if (mProfiles.contains(Profile.HEADSET)) {
68132711b6752eb73324e1b10db975ac956888eda96Danica Chang                LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
68232711b6752eb73324e1b10db975ac956888eda96Danica Chang                        .getProfileManager(mLocalManager, Profile.HEADSET);
68332711b6752eb73324e1b10db975ac956888eda96Danica Chang                isConnecting |= profileManager.getConnectionStatus(mDevice) ==
68432711b6752eb73324e1b10db975ac956888eda96Danica Chang                        SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
68532711b6752eb73324e1b10db975ac956888eda96Danica Chang                isHeadsetConnected = profileManager.isConnected(mDevice);
68632711b6752eb73324e1b10db975ac956888eda96Danica Chang            }
687afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
68832711b6752eb73324e1b10db975ac956888eda96Danica Chang            if (mProfiles.contains(Profile.HID)) {
68932711b6752eb73324e1b10db975ac956888eda96Danica Chang                LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
69032711b6752eb73324e1b10db975ac956888eda96Danica Chang                        .getProfileManager(mLocalManager, Profile.HID);
69132711b6752eb73324e1b10db975ac956888eda96Danica Chang                isConnecting |= profileManager.getConnectionStatus(mDevice) ==
69232711b6752eb73324e1b10db975ac956888eda96Danica Chang                        SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
69332711b6752eb73324e1b10db975ac956888eda96Danica Chang                isHidConnected = profileManager.isConnected(mDevice);
69432711b6752eb73324e1b10db975ac956888eda96Danica Chang            }
69532711b6752eb73324e1b10db975ac956888eda96Danica Chang        } else if (accessibleProfile == PAN_PROFILE && mProfiles.contains(Profile.PAN)) {
696792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
69732711b6752eb73324e1b10db975ac956888eda96Danica Chang                    .getProfileManager(mLocalManager, Profile.PAN);
698792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell            isConnecting |= profileManager.getConnectionStatus(mDevice) ==
699792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                    SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
70032711b6752eb73324e1b10db975ac956888eda96Danica Chang            isPanConnected = profileManager.isConnected(mDevice);
701792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        }
702792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell
703afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (isConnecting) {
704afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // If any of these important profiles is connecting, prefer that
705afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return SettingsBtStatus.getConnectionStatusSummary(
706afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    SettingsBtStatus.CONNECTION_STATUS_CONNECTING);
707afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (isA2dpConnected && isHeadsetConnected) {
708afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return R.string.bluetooth_summary_connected_to_a2dp_headset;
709afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (isA2dpConnected) {
710afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return R.string.bluetooth_summary_connected_to_a2dp;
711afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (isHeadsetConnected) {
712afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return R.string.bluetooth_summary_connected_to_headset;
713792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        } else if (isHidConnected) {
714792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell            return R.string.bluetooth_summary_connected_to_hid;
71532711b6752eb73324e1b10db975ac956888eda96Danica Chang        } else if (isPanConnected) {
71632711b6752eb73324e1b10db975ac956888eda96Danica Chang            return R.string.bluetooth_summary_connected_to_pan;
717afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
718afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return 0;
719afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
720afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
721afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
722e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan    public List<Profile> getConnectableProfiles() {
723e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        ArrayList<Profile> connectableProfiles = new ArrayList<Profile>();
724e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        for (Profile profile : mProfiles) {
725e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan            if (isConnectableProfile(profile)) {
726e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan                connectableProfiles.add(profile);
727e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan            }
728e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        }
729e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        return connectableProfiles;
730e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan    }
731e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan
732e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan    private boolean isConnectableProfile(Profile profile) {
733792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        return profile.equals(Profile.HEADSET) || profile.equals(Profile.A2DP) ||
734792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                profile.equals(Profile.HID);
735afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
736afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
737afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu) {
738afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // No context menu if it is busy (none of these items are applicable if busy)
739ca564d6bdaa56fba60f499e092e1024fff5d1abaNick Pelly        if (mLocalManager.getBluetoothState() != BluetoothAdapter.STATE_ON || isBusy()) {
740487843886dc1c822ee568bb0d77e3f78356dfb87Michael Chan            return;
741487843886dc1c822ee568bb0d77e3f78356dfb87Michael Chan        }
742afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
743afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int bondState = getBondState();
744afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        boolean isConnected = isConnected();
745e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        boolean hasConnectableProfiles = false;
746e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan
747e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        for (Profile profile : mProfiles) {
748e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan            if (isConnectableProfile(profile)) {
749e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan                hasConnectableProfiles = true;
750e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan                break;
751e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan            }
752e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        }
753afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
754afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        menu.setHeaderTitle(getName());
755afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
75616cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly        if (bondState == BluetoothDevice.BOND_NONE) { // Not paired and not connected
757fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan            menu.add(0, CONTEXT_ITEM_CONNECT, 0, R.string.bluetooth_device_context_pair_connect);
758fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan        } else { // Paired
759fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan            if (isConnected) { // Paired and connected
760fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                menu.add(0, CONTEXT_ITEM_DISCONNECT, 0,
761fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                        R.string.bluetooth_device_context_disconnect);
762fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                menu.add(0, CONTEXT_ITEM_UNPAIR, 0,
763fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                        R.string.bluetooth_device_context_disconnect_unpair);
764fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan            } else { // Paired but not connected
765e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan                if (hasConnectableProfiles) {
766fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                    menu.add(0, CONTEXT_ITEM_CONNECT, 0, R.string.bluetooth_device_context_connect);
767fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                }
768fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                menu.add(0, CONTEXT_ITEM_UNPAIR, 0, R.string.bluetooth_device_context_unpair);
769fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan            }
770afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
771afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Show the connection options item
772e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan            if (hasConnectableProfiles) {
773fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                menu.add(0, CONTEXT_ITEM_CONNECT_ADVANCED, 0,
774fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                        R.string.bluetooth_device_context_connect_advanced);
775fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan            }
776afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
777afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
778afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
779afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
780afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Called when a context menu item is clicked.
781afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     *
782afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * @param item The item that was clicked.
783afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
784afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onContextItemSelected(MenuItem item) {
785afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        switch (item.getItemId()) {
786afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case CONTEXT_ITEM_DISCONNECT:
787afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                disconnect();
788afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
789afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
790afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case CONTEXT_ITEM_CONNECT:
791afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                connect();
792afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
793afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
794afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case CONTEXT_ITEM_UNPAIR:
795afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                unpair();
796afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
797afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
798afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case CONTEXT_ITEM_CONNECT_ADVANCED:
799afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Intent intent = new Intent();
800afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // Need an activity context to open this in our task
801afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Context context = mLocalManager.getForegroundActivity();
802afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if (context == null) {
803afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    // Fallback on application context, and open in a new task
804afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    context = mLocalManager.getContext();
805afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
806afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
807afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                intent.setClass(context, ConnectSpecificProfilesActivity.class);
808d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly                intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_DEVICE, mDevice);
809afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                context.startActivity(intent);
810afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
811afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
812afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
813afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
814afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void registerCallback(Callback callback) {
815afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        synchronized (mCallbacks) {
816afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mCallbacks.add(callback);
817afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
818afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
819afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
820afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void unregisterCallback(Callback callback) {
821afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        synchronized (mCallbacks) {
822afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mCallbacks.remove(callback);
823afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
824afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
825afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
826afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void dispatchAttributesChanged() {
827afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        synchronized (mCallbacks) {
828afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            for (Callback callback : mCallbacks) {
829afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                callback.onDeviceAttributesChanged(this);
830afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
831afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
832afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
833afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
834afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
835afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public String toString() {
836d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        return mDevice.toString();
837afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
838afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
839afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
840afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean equals(Object o) {
841d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        if ((o == null) || !(o instanceof CachedBluetoothDevice)) {
842afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            throw new ClassCastException();
843afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
844afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
845d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        return mDevice.equals(((CachedBluetoothDevice) o).mDevice);
846afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
847afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
848afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
849afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public int hashCode() {
850d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        return mDevice.getAddress().hashCode();
851afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
852afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
853d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    public int compareTo(CachedBluetoothDevice another) {
854afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int comparison;
855afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
856afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Connected above not connected
857afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        comparison = (another.isConnected() ? 1 : 0) - (isConnected() ? 1 : 0);
858afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (comparison != 0) return comparison;
859afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
860afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Paired above not paired
861afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        comparison = (another.getBondState() == BluetoothDevice.BOND_BONDED ? 1 : 0) -
862afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            (getBondState() == BluetoothDevice.BOND_BONDED ? 1 : 0);
863afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (comparison != 0) return comparison;
864afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
865afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Visible above not visible
866afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        comparison = (another.mVisible ? 1 : 0) - (mVisible ? 1 : 0);
867afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (comparison != 0) return comparison;
868afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
869afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Stronger signal above weaker signal
870afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        comparison = another.mRssi - mRssi;
871afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (comparison != 0) return comparison;
872afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
873afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Fallback on name
874afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return getName().compareTo(another.getName());
875afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
876afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
877afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public interface Callback {
878d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        void onDeviceAttributesChanged(CachedBluetoothDevice cachedDevice);
879afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
880afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
881