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