CachedBluetoothDevice.java revision e79f990490de49b39097433707c2bae6d8238330
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
1948e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasaniimport com.android.settings.R;
2048e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani
2148e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasaniimport com.android.settings.SettingsPreferenceFragment;
2248e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasaniimport com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
2348e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani
24afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.AlertDialog;
25d63c0112251ab4e4e977545368dd703d875012a4Nick Pellyimport android.bluetooth.BluetoothAdapter;
262aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chanimport android.bluetooth.BluetoothClass;
27e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Projectimport android.bluetooth.BluetoothDevice;
28afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Context;
29afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.DialogInterface;
30afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.res.Resources;
3148e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasaniimport android.graphics.drawable.Drawable;
32e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chanimport android.os.ParcelUuid;
332aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chanimport android.os.SystemClock;
3448e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasaniimport android.preference.Preference;
3548e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasaniimport android.preference.PreferenceActivity;
36afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.text.TextUtils;
37afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.util.Log;
38afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.ContextMenu;
39afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.Menu;
40afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.MenuItem;
41afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
42afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.ArrayList;
43afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.List;
44afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
45afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/**
46d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly * CachedBluetoothDevice represents a remote Bluetooth device. It contains
47afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * attributes of the device (such as the address, name, RSSI, etc.) and
48afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * functionality that can be performed on the device (connect, pair, disconnect,
49afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * etc.).
50afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
51d63c0112251ab4e4e977545368dd703d875012a4Nick Pellypublic class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> {
52d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    private static final String TAG = "CachedBluetoothDevice";
53f25063aee3d8eeaf3767b3a4bf43e1895f2deb2dMichael Chan    private static final boolean D = LocalBluetoothManager.D;
54f25063aee3d8eeaf3767b3a4bf43e1895f2deb2dMichael Chan    private static final boolean V = LocalBluetoothManager.V;
55293867bd109383a1a26b35bf6accb92c0bad264cMichael Chan    private static final boolean DEBUG = false;
56afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
57afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int CONTEXT_ITEM_CONNECT = Menu.FIRST + 1;
58afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int CONTEXT_ITEM_DISCONNECT = Menu.FIRST + 2;
59afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int CONTEXT_ITEM_UNPAIR = Menu.FIRST + 3;
60afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int CONTEXT_ITEM_CONNECT_ADVANCED = Menu.FIRST + 4;
61afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
6232711b6752eb73324e1b10db975ac956888eda96Danica Chang    public static final int PAN_PROFILE = 1;
6332711b6752eb73324e1b10db975ac956888eda96Danica Chang    public static final int OTHER_PROFILES = 2;
6432711b6752eb73324e1b10db975ac956888eda96Danica Chang
65d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    private final BluetoothDevice mDevice;
66afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private String mName;
67afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private short mRssi;
6816cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly    private BluetoothClass mBtClass;
6948e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani    private Context mContext;
70afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
71afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private List<Profile> mProfiles = new ArrayList<Profile>();
72afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
73afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean mVisible;
74afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
75afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private final LocalBluetoothManager mLocalManager;
76afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
7720108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai    private AlertDialog mDialog = null;
7820108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai
79afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private List<Callback> mCallbacks = new ArrayList<Callback>();
80afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
81afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
82afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * When we connect to multiple profiles, we only want to display a single
83afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * error even if they all fail. This tracks that state.
84afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
85afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean mIsConnectingErrorPossible;
86afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
872aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    /**
88eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan     * Last time a bt profile auto-connect was attempted.
89eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan     * If an ACTION_UUID intent comes in within
902aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan     * MAX_UUID_DELAY_FOR_AUTO_CONNECT milliseconds, we will try auto-connect
912aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan     * again with the new UUIDs
922aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan     */
93eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    private long mConnectAttempted;
942aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
95eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    // See mConnectAttempted
962aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    private static final long MAX_UUID_DELAY_FOR_AUTO_CONNECT = 5000;
972aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
98dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby    /** Auto-connect after pairing only if locally initiated. */
99dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby    private boolean mConnectAfterPairing;
10084905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh
101e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project    /**
102f907e0bb891eca4d498871a1cc862117a462a076Adam Powell     * Describes the current device and profile for logging.
10384905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh     *
104f907e0bb891eca4d498871a1cc862117a462a076Adam Powell     * @param profile Profile to describe
105f907e0bb891eca4d498871a1cc862117a462a076Adam Powell     * @return Description of the device and profile
106e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project     */
107e79f990490de49b39097433707c2bae6d8238330Jake Hamby    private String describe(Profile profile) {
108f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        StringBuilder sb = new StringBuilder();
109e79f990490de49b39097433707c2bae6d8238330Jake Hamby        sb.append("Address:").append(mDevice);
110f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        if (profile != null) {
111f907e0bb891eca4d498871a1cc862117a462a076Adam Powell            sb.append(" Profile:").append(profile.name());
112097ed6c671ed733c0967acc32e017020ede4575bMichael Chan        }
113e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
114f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        return sb.toString();
115f907e0bb891eca4d498871a1cc862117a462a076Adam Powell    }
11684905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh
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;
14148e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        mContext = context;
142afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
143afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fillData();
144afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
145afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
146afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onClicked() {
147afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int bondState = getBondState();
148afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
149afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (isConnected()) {
150afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            askDisconnect();
151afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (bondState == BluetoothDevice.BOND_BONDED) {
152afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            connect();
15316cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly        } else if (bondState == BluetoothDevice.BOND_NONE) {
154afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            pair();
155afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
156afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
157afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
158afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void disconnect() {
159afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
160afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            disconnect(profile);
161afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
162afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
163afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
164afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void disconnect(Profile profile) {
165afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        LocalBluetoothProfileManager profileManager =
166afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
167e79f990490de49b39097433707c2bae6d8238330Jake Hamby        if (profileManager.disconnect(mDevice)) {
168d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh            if (D) {
169d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh                Log.d(TAG, "Command sent successfully:DISCONNECT " + describe(profile));
170f907e0bb891eca4d498871a1cc862117a462a076Adam Powell            }
171afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
172afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
173afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
174afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void askDisconnect() {
175afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Context context = mLocalManager.getForegroundActivity();
176afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (context == null) {
177afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Cannot ask, since we need an activity context
178afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            disconnect();
179afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return;
180afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
181afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
182afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Resources res = context.getResources();
183afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
184afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        String name = getName();
185afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (TextUtils.isEmpty(name)) {
186afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            name = res.getString(R.string.bluetooth_device);
187afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
188afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        String message = res.getString(R.string.bluetooth_disconnect_blank, name);
189afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
190afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        DialogInterface.OnClickListener disconnectListener = new DialogInterface.OnClickListener() {
191afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            public void onClick(DialogInterface dialog, int which) {
192afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                disconnect();
193afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
194afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        };
195afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
196e79f990490de49b39097433707c2bae6d8238330Jake Hamby        showDisconnectDialog(context, disconnectListener, message);
197e79f990490de49b39097433707c2bae6d8238330Jake Hamby    }
198e79f990490de49b39097433707c2bae6d8238330Jake Hamby
199e79f990490de49b39097433707c2bae6d8238330Jake Hamby    public void askDisconnect(final Profile profile) {
200e79f990490de49b39097433707c2bae6d8238330Jake Hamby        Context context = mLocalManager.getForegroundActivity();
201e79f990490de49b39097433707c2bae6d8238330Jake Hamby        if (context == null) {
202e79f990490de49b39097433707c2bae6d8238330Jake Hamby            // Cannot ask, since we need an activity context
203e79f990490de49b39097433707c2bae6d8238330Jake Hamby            disconnect(profile);
204e79f990490de49b39097433707c2bae6d8238330Jake Hamby            return;
205e79f990490de49b39097433707c2bae6d8238330Jake Hamby        }
206e79f990490de49b39097433707c2bae6d8238330Jake Hamby
207e79f990490de49b39097433707c2bae6d8238330Jake Hamby        Resources res = context.getResources();
208e79f990490de49b39097433707c2bae6d8238330Jake Hamby
209e79f990490de49b39097433707c2bae6d8238330Jake Hamby        String name = getName();
210e79f990490de49b39097433707c2bae6d8238330Jake Hamby        if (TextUtils.isEmpty(name)) {
211e79f990490de49b39097433707c2bae6d8238330Jake Hamby            name = res.getString(R.string.bluetooth_device);
212e79f990490de49b39097433707c2bae6d8238330Jake Hamby        }
213e79f990490de49b39097433707c2bae6d8238330Jake Hamby        int disconnectMessage;
214e79f990490de49b39097433707c2bae6d8238330Jake Hamby        switch (profile) {
215e79f990490de49b39097433707c2bae6d8238330Jake Hamby            case A2DP:
216e79f990490de49b39097433707c2bae6d8238330Jake Hamby                disconnectMessage = R.string.bluetooth_disconnect_a2dp_profile;
217e79f990490de49b39097433707c2bae6d8238330Jake Hamby                break;
218e79f990490de49b39097433707c2bae6d8238330Jake Hamby            case HEADSET:
219e79f990490de49b39097433707c2bae6d8238330Jake Hamby                disconnectMessage = R.string.bluetooth_disconnect_headset_profile;
220e79f990490de49b39097433707c2bae6d8238330Jake Hamby                break;
221e79f990490de49b39097433707c2bae6d8238330Jake Hamby            case HID:
222e79f990490de49b39097433707c2bae6d8238330Jake Hamby                disconnectMessage = R.string.bluetooth_disconnect_hid_profile;
223e79f990490de49b39097433707c2bae6d8238330Jake Hamby                break;
224e79f990490de49b39097433707c2bae6d8238330Jake Hamby            case PAN:
225e79f990490de49b39097433707c2bae6d8238330Jake Hamby                disconnectMessage = R.string.bluetooth_disconnect_pan_profile;
226e79f990490de49b39097433707c2bae6d8238330Jake Hamby                break;
227e79f990490de49b39097433707c2bae6d8238330Jake Hamby            default:
228e79f990490de49b39097433707c2bae6d8238330Jake Hamby                Log.w(TAG, "askDisconnect: unexpected profile " + profile);
229e79f990490de49b39097433707c2bae6d8238330Jake Hamby                disconnectMessage = R.string.bluetooth_disconnect_blank;
230e79f990490de49b39097433707c2bae6d8238330Jake Hamby                break;
231e79f990490de49b39097433707c2bae6d8238330Jake Hamby        }
232e79f990490de49b39097433707c2bae6d8238330Jake Hamby        String message = res.getString(disconnectMessage, name);
233e79f990490de49b39097433707c2bae6d8238330Jake Hamby
234e79f990490de49b39097433707c2bae6d8238330Jake Hamby        DialogInterface.OnClickListener disconnectListener =
235e79f990490de49b39097433707c2bae6d8238330Jake Hamby                new DialogInterface.OnClickListener() {
236e79f990490de49b39097433707c2bae6d8238330Jake Hamby            public void onClick(DialogInterface dialog, int which) {
237e79f990490de49b39097433707c2bae6d8238330Jake Hamby                disconnect(profile);
238e79f990490de49b39097433707c2bae6d8238330Jake Hamby            }
239e79f990490de49b39097433707c2bae6d8238330Jake Hamby        };
240e79f990490de49b39097433707c2bae6d8238330Jake Hamby
241e79f990490de49b39097433707c2bae6d8238330Jake Hamby        showDisconnectDialog(context, disconnectListener, message);
242e79f990490de49b39097433707c2bae6d8238330Jake Hamby    }
243e79f990490de49b39097433707c2bae6d8238330Jake Hamby
244e79f990490de49b39097433707c2bae6d8238330Jake Hamby    private void showDisconnectDialog(Context context,
245e79f990490de49b39097433707c2bae6d8238330Jake Hamby            DialogInterface.OnClickListener disconnectListener,
246e79f990490de49b39097433707c2bae6d8238330Jake Hamby            String message) {
24720108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        if (mDialog == null) {
24820108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai            mDialog = new AlertDialog.Builder(context)
24920108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai                    .setPositiveButton(android.R.string.ok, disconnectListener)
25020108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai                    .setNegativeButton(android.R.string.cancel, null)
25120108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai                    .create();
25220108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        } else {
25320108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai            if (mDialog.isShowing()) {
25420108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai                mDialog.dismiss();
25520108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai            }
256e79f990490de49b39097433707c2bae6d8238330Jake Hamby            // use disconnectListener for the correct profile(s)
257e79f990490de49b39097433707c2bae6d8238330Jake Hamby            CharSequence okText = context.getText(android.R.string.ok);
258e79f990490de49b39097433707c2bae6d8238330Jake Hamby            mDialog.setButton(DialogInterface.BUTTON_POSITIVE,
259e79f990490de49b39097433707c2bae6d8238330Jake Hamby                    okText, disconnectListener);
26020108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        }
26120108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        mDialog.setTitle(getName());
26220108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        mDialog.setMessage(message);
26320108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        mDialog.show();
26420108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai    }
26520108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai
26620108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai    @Override
26720108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai    protected void finalize() throws Throwable {
26820108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        if (mDialog != null) {
26920108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai            mDialog.dismiss();
27020108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai            mDialog = null;
27120108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        }
27220108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai
27320108e2ed6d7fdc889d85702f7cbda906db141cfJiehua.Dai        super.finalize();
274afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
275afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
276afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void connect() {
277afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!ensurePaired()) return;
278afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
279eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        mConnectAttempted = SystemClock.elapsedRealtime();
280eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan
281eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        connectWithoutResettingTimer();
282eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    }
283eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan
284b172cd5d232bd650d6efbb7d8b5e4cf9c213952fJaikumar Ganesh    /*package*/ void onBondingDockConnect() {
285582f1f84bb0ad4315ce17826672298c68f1c3b38Jake Hamby        // Attempt to connect if UUIDs are available. Otherwise,
286582f1f84bb0ad4315ce17826672298c68f1c3b38Jake Hamby        // we will connect when the ACTION_UUID intent arrives.
287582f1f84bb0ad4315ce17826672298c68f1c3b38Jake Hamby        connect();
288b172cd5d232bd650d6efbb7d8b5e4cf9c213952fJaikumar Ganesh    }
289b172cd5d232bd650d6efbb7d8b5e4cf9c213952fJaikumar Ganesh
290eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    private void connectWithoutResettingTimer() {
2912aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        // Try to initialize the profiles if there were not.
2922aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        if (mProfiles.size() == 0) {
2932aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            if (!updateProfiles()) {
2942aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                // If UUIDs are not available yet, connect will be happen
2952aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                // upon arrival of the ACTION_UUID intent.
296eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan                if (DEBUG) Log.d(TAG, "No profiles. Maybe we will connect later");
2972aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                return;
2982aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            }
2992aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        }
3002aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
301afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Reset the only-show-one-error-dialog tracking variable
302afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mIsConnectingErrorPossible = true;
303afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
304eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        int preferredProfiles = 0;
305afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
306b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan            if (isConnectableProfile(profile)) {
307b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
308b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                        .getProfileManager(mLocalManager, profile);
309b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                if (profileManager.isPreferred(mDevice)) {
310b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                    ++preferredProfiles;
31184905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh                    disconnectConnected(this, profile);
312f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                    connectInt(this, profile);
313b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                }
314afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
315afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
316eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        if (DEBUG) Log.d(TAG, "Preferred profiles = " + preferredProfiles);
317afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
318eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        if (preferredProfiles == 0) {
319eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan            connectAllProfiles();
320afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
321afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
322afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
323eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    private void connectAllProfiles() {
324afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!ensurePaired()) return;
325afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
326afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Reset the only-show-one-error-dialog tracking variable
327afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mIsConnectingErrorPossible = true;
328afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
329afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
330b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan            if (isConnectableProfile(profile)) {
331b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
332b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                        .getProfileManager(mLocalManager, profile);
333b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan                profileManager.setPreferred(mDevice, false);
33484905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh                disconnectConnected(this, profile);
335f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                connectInt(this, profile);
336b547dda338f1b135076c8be59c50a12d843cebf8Michael Chan            }
337afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
338afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
339afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
340afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void connect(Profile profile) {
341eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        mConnectAttempted = SystemClock.elapsedRealtime();
342afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Reset the only-show-one-error-dialog tracking variable
343afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mIsConnectingErrorPossible = true;
34484905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh        disconnectConnected(this, profile);
345f907e0bb891eca4d498871a1cc862117a462a076Adam Powell        connectInt(this, profile);
346afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
347afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
34884905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh    private void disconnectConnected(CachedBluetoothDevice device, Profile profile) {
3493327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan        LocalBluetoothProfileManager profileManager =
3503327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan            LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
3513327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan        CachedBluetoothDeviceManager cachedDeviceManager = mLocalManager.getCachedDeviceManager();
352659b39abf8580a49bd77f194c9ac30359f610709Jaikumar Ganesh        List<BluetoothDevice> devices = profileManager.getConnectedDevices();
3533327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan        if (devices == null) return;
35484905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh        for (BluetoothDevice btDevice : devices) {
35584905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh            CachedBluetoothDevice cachedDevice = cachedDeviceManager.findDevice(btDevice);
35684905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh
35784905edb6315ac0af53141cf2f91591443d7422aJaikumar Ganesh            if (cachedDevice != null && !cachedDevice.equals(device)) {
358e79f990490de49b39097433707c2bae6d8238330Jake Hamby                cachedDevice.disconnect(profile);
3593327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan            }
3603327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan        }
3613327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan    }
3623327f7887328c55ef2d837a8e2a07cea2070c744Michael Chan
363d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    private boolean connectInt(CachedBluetoothDevice cachedDevice, Profile profile) {
364d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        if (!cachedDevice.ensurePaired()) return false;
365afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
366afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        LocalBluetoothProfileManager profileManager =
367afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
368e79f990490de49b39097433707c2bae6d8238330Jake Hamby
369d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh        if (profileManager.connect(cachedDevice.mDevice)) {
370d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh            if (D) {
371d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh                Log.d(TAG, "Command sent successfully:CONNECT " + describe(profile));
372afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
373d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh            return true;
374afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
375d3a460cce7b6a4f1e81f3c15b5f7949d28fdc929Jaikumar Ganesh        Log.i(TAG, "Failed to connect " + profile.toString() + " to " + cachedDevice.mName);
376f907e0bb891eca4d498871a1cc862117a462a076Adam Powell
377e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project        return false;
378afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
379afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
380afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void showConnectingError() {
381afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!mIsConnectingErrorPossible) return;
382afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mIsConnectingErrorPossible = false;
383afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
384d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        mLocalManager.showError(mDevice, R.string.bluetooth_error_title,
385afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                R.string.bluetooth_connecting_error_message);
386afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
387afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
388afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private boolean ensurePaired() {
38916cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly        if (getBondState() == BluetoothDevice.BOND_NONE) {
390afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            pair();
391afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return false;
392afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
393afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return true;
394afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
395afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
396afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
397afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void pair() {
398d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        BluetoothAdapter adapter = mLocalManager.getBluetoothAdapter();
399afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
400afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Pairing is unreliable while scanning, so cancel discovery
401d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        if (adapter.isDiscovering()) {
402d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            adapter.cancelDiscovery();
403afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
404afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
405d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        if (!mDevice.createBond()) {
406d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            mLocalManager.showError(mDevice, R.string.bluetooth_error_title,
407afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    R.string.bluetooth_pairing_error_message);
408dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby            return;
409afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
410dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby
411dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby        mConnectAfterPairing = true;  // auto-connect after pairing
412afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
413afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
414afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void unpair() {
41596b0c1dc0813f7e8c957ec17dc7751693926c6aeMichael Chan        disconnect();
416e6dd1fa1851302710ac7845d25d8ad8a5b6ee438The Android Open Source Project
41796b0c1dc0813f7e8c957ec17dc7751693926c6aeMichael Chan        int state = getBondState();
418afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
41996b0c1dc0813f7e8c957ec17dc7751693926c6aeMichael Chan        if (state == BluetoothDevice.BOND_BONDING) {
420d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            mDevice.cancelBondProcess();
42196b0c1dc0813f7e8c957ec17dc7751693926c6aeMichael Chan        }
42296b0c1dc0813f7e8c957ec17dc7751693926c6aeMichael Chan
42396b0c1dc0813f7e8c957ec17dc7751693926c6aeMichael Chan        if (state != BluetoothDevice.BOND_NONE) {
424f907e0bb891eca4d498871a1cc862117a462a076Adam Powell            final BluetoothDevice dev = getDevice();
425f907e0bb891eca4d498871a1cc862117a462a076Adam Powell            if (dev != null) {
426f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                final boolean successful = dev.removeBond();
427f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                if (successful) {
428f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                    if (D) {
429f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                        Log.d(TAG, "Command sent successfully:REMOVE_BOND " + describe(null));
430f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                    }
431f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                } else if (V) {
432f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                    Log.v(TAG, "Framework rejected command immediately:REMOVE_BOND " +
433f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                            describe(null));
434f907e0bb891eca4d498871a1cc862117a462a076Adam Powell                }
435f907e0bb891eca4d498871a1cc862117a462a076Adam Powell            }
436afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
437afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
438afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
439afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void fillData() {
440afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fetchName();
441afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fetchBtClass();
4422aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        updateProfiles();
443afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
444afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mVisible = false;
445afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
446afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        dispatchAttributesChanged();
447afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
448afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
449d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    public BluetoothDevice getDevice() {
450d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        return mDevice;
451afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
452afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
453afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public String getName() {
454afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return mName;
455afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
456afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
457d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh    public void setName(String name) {
458d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh        if (!mName.equals(name)) {
459d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh            if (TextUtils.isEmpty(name)) {
460d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly                mName = mDevice.getAddress();
461d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh            } else {
462d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh                mName = name;
463d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh            }
464d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh            dispatchAttributesChanged();
465d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh        }
466d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh    }
467d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh
468afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void refreshName() {
469afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fetchName();
470afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        dispatchAttributesChanged();
471afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
472afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
473afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void fetchName() {
474d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        mName = mDevice.getName();
475afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
476afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (TextUtils.isEmpty(mName)) {
477d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            mName = mDevice.getAddress();
478eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan            if (DEBUG) Log.d(TAG, "Default to address. Device has no name (yet) " + mName);
479afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
480afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
481afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
482afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void refresh() {
483afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        dispatchAttributesChanged();
484afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
485afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
486afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean isVisible() {
487afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return mVisible;
488afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
489afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
490afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    void setVisible(boolean visible) {
491afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mVisible != visible) {
492afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mVisible = visible;
493afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            dispatchAttributesChanged();
494afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
495afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
496afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
497afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public int getBondState() {
498d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        return mDevice.getBondState();
499afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
500afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
501afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    void setRssi(short rssi) {
502afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mRssi != rssi) {
503afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mRssi = rssi;
504afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            dispatchAttributesChanged();
505afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
506afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
507afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
508afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
509afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Checks whether we are connected to this device (any profile counts).
510afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     *
511afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * @return Whether it is connected.
512afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
513afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean isConnected() {
514afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
515afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
516d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly                    .getConnectionStatus(mDevice);
517afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (SettingsBtStatus.isConnectionStatusConnected(status)) {
518afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return true;
519afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
520afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
521afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
522afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return false;
523afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
524afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
525afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean isBusy() {
526afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
527afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
528d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly                    .getConnectionStatus(mDevice);
529afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (SettingsBtStatus.isConnectionStatusBusy(status)) {
530afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return true;
531afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
532afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
533afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
534afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (getBondState() == BluetoothDevice.BOND_BONDING) {
535afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return true;
536afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
537afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
538afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return false;
539afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
540afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
541afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public int getBtClassDrawable() {
5424d004e910732565ddd449c7c525f7d6cbd353392Michael Chan        if (mBtClass != null) {
5434d004e910732565ddd449c7c525f7d6cbd353392Michael Chan            switch (mBtClass.getMajorDeviceClass()) {
5444d004e910732565ddd449c7c525f7d6cbd353392Michael Chan            case BluetoothClass.Device.Major.COMPUTER:
5454d004e910732565ddd449c7c525f7d6cbd353392Michael Chan                return R.drawable.ic_bt_laptop;
546afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
5474d004e910732565ddd449c7c525f7d6cbd353392Michael Chan            case BluetoothClass.Device.Major.PHONE:
5484d004e910732565ddd449c7c525f7d6cbd353392Michael Chan                return R.drawable.ic_bt_cellphone;
5494d004e910732565ddd449c7c525f7d6cbd353392Michael Chan            }
5504d004e910732565ddd449c7c525f7d6cbd353392Michael Chan        } else {
5514d004e910732565ddd449c7c525f7d6cbd353392Michael Chan            Log.w(TAG, "mBtClass is null");
5523e1c1d19201e625888cdd07e06ea9502d7c4dafbMichael Chan        }
553afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
554cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan        if (mProfiles.size() > 0) {
555cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            if (mProfiles.contains(Profile.A2DP)) {
556cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan                return R.drawable.ic_bt_headphones_a2dp;
557cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            } else if (mProfiles.contains(Profile.HEADSET)) {
558cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan                return R.drawable.ic_bt_headset_hfp;
559cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            }
5604d004e910732565ddd449c7c525f7d6cbd353392Michael Chan        } else if (mBtClass != null) {
561cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            if (mBtClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) {
562cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan                return R.drawable.ic_bt_headphones_a2dp;
563cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan
564cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            }
565cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            if (mBtClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) {
566cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan                return R.drawable.ic_bt_headset_hfp;
567cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan            }
568afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
569cb844e2eab4efa03513c0e0a2de7bc18c79dd128Michael Chan        return 0;
570afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
571afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
572afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
573afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Fetches a new value for the cached BT class.
574afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
575afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void fetchBtClass() {
576d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        mBtClass = mDevice.getBluetoothClass();
5772aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    }
5782aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
5792aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    private boolean updateProfiles() {
5802aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        ParcelUuid[] uuids = mDevice.getUuids();
5812aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        if (uuids == null) return false;
5822aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
5832aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        LocalBluetoothProfileManager.updateProfiles(uuids, mProfiles);
5842aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
5852aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        if (DEBUG) {
5862aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            Log.e(TAG, "updating profiles for " + mDevice.getName());
5872aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
5882aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            boolean printUuids = true;
5892aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            BluetoothClass bluetoothClass = mDevice.getBluetoothClass();
5902aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
591a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan            if (bluetoothClass != null) {
592a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET) !=
593a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    mProfiles.contains(Profile.HEADSET)) {
594a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    Log.v(TAG, "headset classbits != uuid");
595a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    printUuids = true;
596a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                }
5972aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
598a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_A2DP) !=
599a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    mProfiles.contains(Profile.A2DP)) {
600a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    Log.v(TAG, "a2dp classbits != uuid");
601a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    printUuids = true;
602a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                }
6032aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
604a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_OPP) !=
605a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    mProfiles.contains(Profile.OPP)) {
606a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    Log.v(TAG, "opp classbits != uuid");
607a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                    printUuids = true;
608a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                }
609792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell
610792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_HID) !=
611792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                    mProfiles.contains(Profile.HID)) {
612792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                    Log.v(TAG, "hid classbits != uuid");
613792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                    printUuids = true;
614792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                }
6152aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            }
6162aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
6172aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            if (printUuids) {
618a87f2fd7d82e5055e0f9ea2c93704ed0b58f27efMichael Chan                if (bluetoothClass != null) Log.v(TAG, "Class: " + bluetoothClass.toString());
6192aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                Log.v(TAG, "UUID:");
6202aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                for (int i = 0; i < uuids.length; i++) {
6212aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                    Log.v(TAG, "  " + uuids[i]);
6222aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                }
6232aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan            }
624b20dd917e2d29045225985baa980a2a8e22e10fcNick Pelly        }
6252aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        return true;
626afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
627afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
628afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
629afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Refreshes the UI for the BT class, including fetching the latest value
630afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * for the class.
631afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
632afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void refreshBtClass() {
633afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        fetchBtClass();
634afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        dispatchAttributesChanged();
635afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
636afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
6372aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    /**
6382aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan     * Refreshes the UI when framework alerts us of a UUID change.
6392aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan     */
6402aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    public void onUuidChanged() {
6412aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        updateProfiles();
6422aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
643eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        if (DEBUG) {
644eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan            Log.e(TAG, "onUuidChanged: Time since last connect"
645eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan                    + (SystemClock.elapsedRealtime() - mConnectAttempted));
646eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        }
6472aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
6482aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        /*
6492aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan         * If a connect was attempted earlier without any UUID, we will do the
6502aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan         * connect now.
6512aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan         */
6522aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        if (mProfiles.size() > 0
653eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan                && (mConnectAttempted + MAX_UUID_DELAY_FOR_AUTO_CONNECT) > SystemClock
6542aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan                        .elapsedRealtime()) {
655eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan            connectWithoutResettingTimer();
6562aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        }
6572aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan        dispatchAttributesChanged();
6582aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan    }
6592aef1f3c814b1f8aa00aeefff35caf293c738702Michael Chan
660eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    public void onBondingStateChanged(int bondState) {
661eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        if (bondState == BluetoothDevice.BOND_NONE) {
662eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan            mProfiles.clear();
663dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby            mConnectAfterPairing = false;  // cancel auto-connect
664eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        }
6651308453b16c2ca85a456bd4bb7f3c71c916bd83eMichael Chan
666eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan        refresh();
667dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby
668dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby        if (bondState == BluetoothDevice.BOND_BONDED) {
669dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby            if (mDevice.isBluetoothDock()) {
670dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby                onBondingDockConnect();
671dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby            } else if (mConnectAfterPairing) {
672dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby                connect();
673dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby            }
674dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby            mConnectAfterPairing = false;
675dd79a33ba53fec530094f4d2fe37f0538530d9f8Jake Hamby        }
676eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan    }
677eaf13a2c154a0c7bf7559b45d33fb589b5bcf3d4Michael Chan
67816cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly    public void setBtClass(BluetoothClass btClass) {
67916cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly        if (btClass != null && mBtClass != btClass) {
680d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh            mBtClass = btClass;
681d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh            dispatchAttributesChanged();
682d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh        }
683d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh    }
684d97daa064b35ee0c2b73547d46f97fa88d2da4e9Jaikumar Ganesh
68532711b6752eb73324e1b10db975ac956888eda96Danica Chang    public int getSummary(int accessibleProfile) {
686afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // TODO: clean up
68732711b6752eb73324e1b10db975ac956888eda96Danica Chang        int oneOffSummary = getOneOffSummary(accessibleProfile);
688afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (oneOffSummary != 0) {
689afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return oneOffSummary;
690afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
691afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
692afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (Profile profile : mProfiles) {
693afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
694afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    .getProfileManager(mLocalManager, profile);
695d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            int connectionStatus = profileManager.getConnectionStatus(mDevice);
696afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
697afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus) ||
698afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    connectionStatus == SettingsBtStatus.CONNECTION_STATUS_CONNECTING ||
699afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING) {
700afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
701afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
702afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
703afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
704afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return SettingsBtStatus.getPairingStatusSummary(getBondState());
705afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
706afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
70748e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani    public List<Drawable> getProfileIcons() {
70848e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        ArrayList<Drawable> drawables = new ArrayList<Drawable>();
70948e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani
71048e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        for (Profile profile : mProfiles) {
71148e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
71248e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani                    .getProfileManager(mLocalManager, profile);
71348e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani            int iconResource = profileManager.getDrawableResource();
71448e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani            if (iconResource != 0) {
71548e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani                drawables.add(mContext.getResources().getDrawable(iconResource));
71648e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani            }
71748e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        }
71848e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani
71948e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        return drawables;
72048e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani    }
721afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
722afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * We have special summaries when particular profiles are connected. This
723afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * checks for those states and returns an applicable summary.
724afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     *
725afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * @return A one-off summary that is applicable for the current state, or 0.
726afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
72732711b6752eb73324e1b10db975ac956888eda96Danica Chang    private int getOneOffSummary(int accessibleProfile) {
728792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        boolean isA2dpConnected = false;
729792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        boolean isHeadsetConnected = false;
730792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        boolean isHidConnected = false;
73132711b6752eb73324e1b10db975ac956888eda96Danica Chang        boolean isPanConnected = false;
732792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        boolean isConnecting = false;
733afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
73432711b6752eb73324e1b10db975ac956888eda96Danica Chang        if (accessibleProfile == OTHER_PROFILES) {
73532711b6752eb73324e1b10db975ac956888eda96Danica Chang            if (mProfiles.contains(Profile.A2DP)) {
73632711b6752eb73324e1b10db975ac956888eda96Danica Chang                LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
73732711b6752eb73324e1b10db975ac956888eda96Danica Chang                        .getProfileManager(mLocalManager, Profile.A2DP);
73832711b6752eb73324e1b10db975ac956888eda96Danica Chang                isConnecting = profileManager.getConnectionStatus(mDevice) ==
73932711b6752eb73324e1b10db975ac956888eda96Danica Chang                        SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
74032711b6752eb73324e1b10db975ac956888eda96Danica Chang                isA2dpConnected = profileManager.isConnected(mDevice);
74132711b6752eb73324e1b10db975ac956888eda96Danica Chang            }
742afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
74332711b6752eb73324e1b10db975ac956888eda96Danica Chang            if (mProfiles.contains(Profile.HEADSET)) {
74432711b6752eb73324e1b10db975ac956888eda96Danica Chang                LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
74532711b6752eb73324e1b10db975ac956888eda96Danica Chang                        .getProfileManager(mLocalManager, Profile.HEADSET);
74632711b6752eb73324e1b10db975ac956888eda96Danica Chang                isConnecting |= profileManager.getConnectionStatus(mDevice) ==
74732711b6752eb73324e1b10db975ac956888eda96Danica Chang                        SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
74832711b6752eb73324e1b10db975ac956888eda96Danica Chang                isHeadsetConnected = profileManager.isConnected(mDevice);
74932711b6752eb73324e1b10db975ac956888eda96Danica Chang            }
750afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
75132711b6752eb73324e1b10db975ac956888eda96Danica Chang            if (mProfiles.contains(Profile.HID)) {
75232711b6752eb73324e1b10db975ac956888eda96Danica Chang                LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
75332711b6752eb73324e1b10db975ac956888eda96Danica Chang                        .getProfileManager(mLocalManager, Profile.HID);
75432711b6752eb73324e1b10db975ac956888eda96Danica Chang                isConnecting |= profileManager.getConnectionStatus(mDevice) ==
75532711b6752eb73324e1b10db975ac956888eda96Danica Chang                        SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
75632711b6752eb73324e1b10db975ac956888eda96Danica Chang                isHidConnected = profileManager.isConnected(mDevice);
75732711b6752eb73324e1b10db975ac956888eda96Danica Chang            }
75832711b6752eb73324e1b10db975ac956888eda96Danica Chang        } else if (accessibleProfile == PAN_PROFILE && mProfiles.contains(Profile.PAN)) {
759792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
76032711b6752eb73324e1b10db975ac956888eda96Danica Chang                    .getProfileManager(mLocalManager, Profile.PAN);
761792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell            isConnecting |= profileManager.getConnectionStatus(mDevice) ==
762792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                    SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
76332711b6752eb73324e1b10db975ac956888eda96Danica Chang            isPanConnected = profileManager.isConnected(mDevice);
764792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        }
765792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell
766afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (isConnecting) {
767afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // If any of these important profiles is connecting, prefer that
768afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return SettingsBtStatus.getConnectionStatusSummary(
769afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    SettingsBtStatus.CONNECTION_STATUS_CONNECTING);
770afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (isA2dpConnected && isHeadsetConnected) {
771afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return R.string.bluetooth_summary_connected_to_a2dp_headset;
772afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (isA2dpConnected) {
773afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return R.string.bluetooth_summary_connected_to_a2dp;
774afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else if (isHeadsetConnected) {
775afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return R.string.bluetooth_summary_connected_to_headset;
776792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        } else if (isHidConnected) {
777792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell            return R.string.bluetooth_summary_connected_to_hid;
77832711b6752eb73324e1b10db975ac956888eda96Danica Chang        } else if (isPanConnected) {
77932711b6752eb73324e1b10db975ac956888eda96Danica Chang            return R.string.bluetooth_summary_connected_to_pan;
780afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
781afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return 0;
782afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
783afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
784afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
785e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan    public List<Profile> getConnectableProfiles() {
786e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        ArrayList<Profile> connectableProfiles = new ArrayList<Profile>();
787e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        for (Profile profile : mProfiles) {
788e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan            if (isConnectableProfile(profile)) {
789e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan                connectableProfiles.add(profile);
790e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan            }
791e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        }
792e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        return connectableProfiles;
793e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan    }
794e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan
795e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan    private boolean isConnectableProfile(Profile profile) {
796792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell        return profile.equals(Profile.HEADSET) || profile.equals(Profile.A2DP) ||
797792d2132e408ded2b2d56646ba263808dd51fc31Adam Powell                profile.equals(Profile.HID);
798afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
799afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
800afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu) {
801afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // No context menu if it is busy (none of these items are applicable if busy)
802ca564d6bdaa56fba60f499e092e1024fff5d1abaNick Pelly        if (mLocalManager.getBluetoothState() != BluetoothAdapter.STATE_ON || isBusy()) {
803487843886dc1c822ee568bb0d77e3f78356dfb87Michael Chan            return;
804487843886dc1c822ee568bb0d77e3f78356dfb87Michael Chan        }
805afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
806afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int bondState = getBondState();
807afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        boolean isConnected = isConnected();
808e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        boolean hasConnectableProfiles = false;
809e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan
810e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        for (Profile profile : mProfiles) {
811e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan            if (isConnectableProfile(profile)) {
812e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan                hasConnectableProfiles = true;
813e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan                break;
814e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan            }
815e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan        }
816afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
817afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        menu.setHeaderTitle(getName());
818afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
81916cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly        if (bondState == BluetoothDevice.BOND_NONE) { // Not paired and not connected
820fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan            menu.add(0, CONTEXT_ITEM_CONNECT, 0, R.string.bluetooth_device_context_pair_connect);
821fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan        } else { // Paired
822fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan            if (isConnected) { // Paired and connected
823fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                menu.add(0, CONTEXT_ITEM_DISCONNECT, 0,
824fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                        R.string.bluetooth_device_context_disconnect);
825fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                menu.add(0, CONTEXT_ITEM_UNPAIR, 0,
826fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                        R.string.bluetooth_device_context_disconnect_unpair);
827fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan            } else { // Paired but not connected
828e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan                if (hasConnectableProfiles) {
829fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                    menu.add(0, CONTEXT_ITEM_CONNECT, 0, R.string.bluetooth_device_context_connect);
830fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                }
831fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                menu.add(0, CONTEXT_ITEM_UNPAIR, 0, R.string.bluetooth_device_context_unpair);
832fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan            }
833afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
834afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Show the connection options item
835e6531e253bf646324d3a68de0e9cc612c5e1c8acMichael Chan            if (hasConnectableProfiles) {
836fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                menu.add(0, CONTEXT_ITEM_CONNECT_ADVANCED, 0,
837fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan                        R.string.bluetooth_device_context_connect_advanced);
838fdfb90f9e8207702700093888d0de6dea9a198ebMichael Chan            }
839afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
840afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
841afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
842afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /**
843afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * Called when a context menu item is clicked.
844afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     *
845afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     * @param item The item that was clicked.
846afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project     */
84748e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani    public void onContextItemSelected(MenuItem item, SettingsPreferenceFragment fragment) {
848afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        switch (item.getItemId()) {
849afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case CONTEXT_ITEM_DISCONNECT:
850afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                disconnect();
851afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
852afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
853afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case CONTEXT_ITEM_CONNECT:
854afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                connect();
855afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
856afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
857afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case CONTEXT_ITEM_UNPAIR:
858afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                unpair();
859afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
860afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
861afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case CONTEXT_ITEM_CONNECT_ADVANCED:
86248e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani            onClickedAdvancedOptions(fragment);
863afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                break;
864afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
865afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
866afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
86748e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani    public void onClickedAdvancedOptions(SettingsPreferenceFragment fragment) {
86848e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // TODO: Verify if there really is a case when there's no foreground
86948e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // activity
87048e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani
87148e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // Intent intent = new Intent();
87248e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // // Need an activity context to open this in our task
87348e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // Context context = mLocalManager.getForegroundActivity();
87448e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // if (context == null) {
87548e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // // Fallback on application context, and open in a new task
87648e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // context = mLocalManager.getContext();
87748e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
87848e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // }
87948e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // intent.setClass(context, ConnectSpecificProfilesActivity.class);
88048e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_DEVICE,
88148e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // mDevice);
88248e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        // context.startActivity(intent);
88348e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        Preference pref = new Preference(fragment.getActivity());
88448e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        pref.setTitle(getName());
88548e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        pref.setFragment(DeviceProfilesSettings.class.getName());
88648e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        pref.getExtras().putParcelable(DeviceProfilesSettings.EXTRA_DEVICE, mDevice);
88748e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani        ((PreferenceActivity) fragment.getActivity()).onPreferenceStartFragment(fragment, pref);
88848e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani    }
88948e90002839e662eb1667471aebeb0483e9fb7dbAmith Yamasani
890afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void registerCallback(Callback callback) {
891afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        synchronized (mCallbacks) {
892afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mCallbacks.add(callback);
893afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
894afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
895afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
896afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void unregisterCallback(Callback callback) {
897afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        synchronized (mCallbacks) {
898afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            mCallbacks.remove(callback);
899afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
900afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
901afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
902afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void dispatchAttributesChanged() {
903afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        synchronized (mCallbacks) {
904afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            for (Callback callback : mCallbacks) {
905afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                callback.onDeviceAttributesChanged(this);
906afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
907afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
908afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
909afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
910afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
911afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public String toString() {
912d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        return mDevice.toString();
913afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
914afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
915afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
916afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean equals(Object o) {
917d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        if ((o == null) || !(o instanceof CachedBluetoothDevice)) {
918afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            throw new ClassCastException();
919afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
920afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
921d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        return mDevice.equals(((CachedBluetoothDevice) o).mDevice);
922afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
923afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
924afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
925afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public int hashCode() {
926d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        return mDevice.getAddress().hashCode();
927afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
928afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
929d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly    public int compareTo(CachedBluetoothDevice another) {
930afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        int comparison;
931afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
932afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Connected above not connected
933afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        comparison = (another.isConnected() ? 1 : 0) - (isConnected() ? 1 : 0);
934afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (comparison != 0) return comparison;
935afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
936afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Paired above not paired
937afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        comparison = (another.getBondState() == BluetoothDevice.BOND_BONDED ? 1 : 0) -
938afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            (getBondState() == BluetoothDevice.BOND_BONDED ? 1 : 0);
939afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (comparison != 0) return comparison;
940afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
941afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Visible above not visible
942afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        comparison = (another.mVisible ? 1 : 0) - (mVisible ? 1 : 0);
943afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (comparison != 0) return comparison;
944afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
945afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Stronger signal above weaker signal
946afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        comparison = another.mRssi - mRssi;
947afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (comparison != 0) return comparison;
948afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
949afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Fallback on name
950afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return getName().compareTo(another.getName());
951afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
952afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
953afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public interface Callback {
954d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly        void onDeviceAttributesChanged(CachedBluetoothDevice cachedDevice);
955afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
956afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
957