1afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/* 2afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * 4afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * you may not use this file except in compliance with the License. 6afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * You may obtain a copy of the License at 7afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * 8afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * 10afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * See the License for the specific language governing permissions and 14afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * limitations under the License. 15afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */ 16afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 17afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectpackage com.android.settings.bluetooth; 18afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 19afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.bluetooth.BluetoothDevice; 20afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.BroadcastReceiver; 21afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Context; 22afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.DialogInterface; 23afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent; 24afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.IntentFilter; 25afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Bundle; 26afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.text.Editable; 27ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hambyimport android.text.Html; 28afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.text.InputFilter; 293a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganeshimport android.text.InputType; 30ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hambyimport android.text.Spanned; 31afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.text.TextWatcher; 32afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.text.InputFilter.LengthFilter; 33afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.util.Log; 34afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.View; 35afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.Button; 36ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hambyimport android.widget.CheckBox; 37ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hambyimport android.widget.CompoundButton; 38afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.EditText; 39afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.TextView; 40afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 41afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport com.android.internal.app.AlertActivity; 42afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport com.android.internal.app.AlertController; 43afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport com.android.settings.R; 44aaf8ffff79a73c71d3fb77a31950e344f4c7eab5jhtop.kimimport android.view.KeyEvent; 45afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 46ae8d5bdc5bfabb457135dbe9c30084bffdc16a7cFabrice Di Meglioimport java.util.Locale; 47ae8d5bdc5bfabb457135dbe9c30084bffdc16a7cFabrice Di Meglio 48afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/** 493a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh * BluetoothPairingDialog asks the user to enter a PIN / Passkey / simple confirmation 503a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh * for pairing with a remote Bluetooth device. It is an activity that appears as a dialog. 51afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */ 52ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hambypublic final class BluetoothPairingDialog extends AlertActivity implements 53ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby CompoundButton.OnCheckedChangeListener, DialogInterface.OnClickListener, TextWatcher { 543a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh private static final String TAG = "BluetoothPairingDialog"; 55afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 56e79f990490de49b39097433707c2bae6d8238330Jake Hamby private static final int BLUETOOTH_PIN_MAX_LENGTH = 16; 57e79f990490de49b39097433707c2bae6d8238330Jake Hamby private static final int BLUETOOTH_PASSKEY_MAX_LENGTH = 6; 58d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly private BluetoothDevice mDevice; 593a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh private int mType; 60da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh private String mPairingKey; 613a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh private EditText mPairingView; 62afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project private Button mOkButton; 63afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 64436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby /** 65436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * Dismiss the dialog if the bond state changes to bonded or none, 66436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * or if pairing was canceled for {@link #mDevice}. 67436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby */ 68436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 69afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project @Override 70afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project public void onReceive(Context context, Intent intent) { 71436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby String action = intent.getAction(); 72436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) { 73435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, 74435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh BluetoothDevice.ERROR); 75435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh if (bondState == BluetoothDevice.BOND_BONDED || 76435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh bondState == BluetoothDevice.BOND_NONE) { 77436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby dismiss(); 78435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh } 79436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } else if (BluetoothDevice.ACTION_PAIRING_CANCEL.equals(action)) { 80435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 81435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh if (device == null || device.equals(mDevice)) { 82436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby dismiss(); 83435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh } 84afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 85afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 86afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project }; 873a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh 88afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project @Override 89afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project protected void onCreate(Bundle savedInstanceState) { 90afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project super.onCreate(savedInstanceState); 91afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 92afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project Intent intent = getIntent(); 9316cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly if (!intent.getAction().equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) 94afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project { 95436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby Log.e(TAG, "Error: this activity may be started only with intent " + 9616cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly BluetoothDevice.ACTION_PAIRING_REQUEST); 97afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project finish(); 98436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return; 99afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 1003a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh 101436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby LocalBluetoothManager manager = LocalBluetoothManager.getInstance(this); 102436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (manager == null) { 103436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby Log.e(TAG, "Error: BluetoothAdapter not supported by system"); 104436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby finish(); 105436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return; 106436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 107436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby CachedBluetoothDeviceManager deviceManager = manager.getCachedDeviceManager(); 108436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 10916cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 11016cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly mType = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR); 111436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 112436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby switch (mType) { 113436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_PIN: 114436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_PASSKEY: 115436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby createUserEntryDialog(deviceManager); 116436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 117436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 118436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION: 119436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby int passkey = 120436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR); 121436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (passkey == BluetoothDevice.ERROR) { 122436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby Log.e(TAG, "Invalid Confirmation Passkey received, not showing any dialog"); 123436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return; 124436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 125ae8d5bdc5bfabb457135dbe9c30084bffdc16a7cFabrice Di Meglio mPairingKey = String.format(Locale.US, "%06d", passkey); 126436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby createConfirmationDialog(deviceManager); 127436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 128436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 129436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_CONSENT: 130436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT: 131436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby createConsentDialog(deviceManager); 132436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 133436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 134436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY: 135436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN: 136436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby int pairingKey = 137436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR); 138436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (pairingKey == BluetoothDevice.ERROR) { 139436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby Log.e(TAG, "Invalid Confirmation Passkey or PIN received, not showing any dialog"); 140436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return; 141436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 142436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY) { 143436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mPairingKey = String.format("%06d", pairingKey); 144436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } else { 145436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mPairingKey = String.format("%04d", pairingKey); 146436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 147436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby createDisplayPasskeyOrPinDialog(deviceManager); 148436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 149436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 150436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby default: 151436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby Log.e(TAG, "Incorrect pairing type received, not showing any dialog"); 1523a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh } 1533a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh 1543a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh /* 1553a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh * Leave this registered through pause/resume since we still want to 1563a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh * finish the activity in the background if pairing is canceled. 1573a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh */ 15816cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_PAIRING_CANCEL)); 159435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED)); 1603a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh } 1613a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh 162436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private void createUserEntryDialog(CachedBluetoothDeviceManager deviceManager) { 163afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project final AlertController.AlertParams p = mAlertParams; 164afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project p.mIconId = android.R.drawable.ic_dialog_info; 165435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh p.mTitle = getString(R.string.bluetooth_pairing_request); 166ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby p.mView = createPinEntryView(deviceManager.getName(mDevice)); 167afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project p.mPositiveButtonText = getString(android.R.string.ok); 168afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project p.mPositiveButtonListener = this; 169afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project p.mNegativeButtonText = getString(android.R.string.cancel); 170afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project p.mNegativeButtonListener = this; 171afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project setupAlert(); 1723a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh 173436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mOkButton = mAlert.getButton(BUTTON_POSITIVE); 174afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project mOkButton.setEnabled(false); 1753a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh } 176afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 177ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby private View createPinEntryView(String deviceName) { 1783a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh View view = getLayoutInflater().inflate(R.layout.bluetooth_pin_entry, null); 1793a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh TextView messageView = (TextView) view.findViewById(R.id.message); 180ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby TextView messageView2 = (TextView) view.findViewById(R.id.message_below_pin); 181ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby CheckBox alphanumericPin = (CheckBox) view.findViewById(R.id.alphanumeric_pin); 1823a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh mPairingView = (EditText) view.findViewById(R.id.text); 1833a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh mPairingView.addTextChangedListener(this); 184ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby alphanumericPin.setOnCheckedChangeListener(this); 1853a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh 186ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby int messageId1; 187ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby int messageId2; 188ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby int maxLength; 189436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby switch (mType) { 190436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_PIN: 191ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby messageId1 = R.string.bluetooth_enter_pin_msg; 192ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby messageId2 = R.string.bluetooth_enter_pin_other_device; 193ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby // Maximum of 16 characters in a PIN 194ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby maxLength = BLUETOOTH_PIN_MAX_LENGTH; 195436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 196436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 197436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_PASSKEY: 198ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby messageId1 = R.string.bluetooth_enter_passkey_msg; 199ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby messageId2 = R.string.bluetooth_enter_passkey_other_device; 200436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby // Maximum of 6 digits for passkey 201ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby maxLength = BLUETOOTH_PASSKEY_MAX_LENGTH; 202ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby alphanumericPin.setVisibility(View.GONE); 203436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 204436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 205ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby default: 206ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby Log.e(TAG, "Incorrect pairing type for createPinEntryView: " + mType); 207ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby return null; 208ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby } 209ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby 210ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby // Format the message string, then parse HTML style tags 211ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby String messageText = getString(messageId1, deviceName); 212ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby messageView.setText(Html.fromHtml(messageText)); 213ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby messageView2.setText(messageId2); 214ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby mPairingView.setInputType(InputType.TYPE_CLASS_NUMBER); 215ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby mPairingView.setFilters(new InputFilter[] { 216ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby new LengthFilter(maxLength) }); 217ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby 218ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby return view; 219ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby } 220ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby 221ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby private View createView(CachedBluetoothDeviceManager deviceManager) { 222ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby View view = getLayoutInflater().inflate(R.layout.bluetooth_pin_confirm, null); 223ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby String name = deviceManager.getName(mDevice); 224ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby TextView messageView = (TextView) view.findViewById(R.id.message); 225ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby 226ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby String messageText; // formatted string containing HTML style tags 227ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby switch (mType) { 228436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION: 229ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby messageText = getString(R.string.bluetooth_confirm_passkey_msg, 230ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby name, mPairingKey); 231436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 232436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 233436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_CONSENT: 234ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT: 235ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby messageText = getString(R.string.bluetooth_incoming_pairing_msg, name); 236436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 237436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 238436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY: 239436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN: 240ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby messageText = getString(R.string.bluetooth_display_passkey_pin_msg, name, 241ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby mPairingKey); 242436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 243436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 244436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby default: 245436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby Log.e(TAG, "Incorrect pairing type received, not creating view"); 246ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby return null; 2473a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh } 248ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby messageView.setText(Html.fromHtml(messageText)); 2493a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh return view; 2503a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh } 2513a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh 252436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private void createConfirmationDialog(CachedBluetoothDeviceManager deviceManager) { 2533a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh final AlertController.AlertParams p = mAlertParams; 2543a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh p.mIconId = android.R.drawable.ic_dialog_info; 255435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh p.mTitle = getString(R.string.bluetooth_pairing_request); 256436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby p.mView = createView(deviceManager); 257e41a4ca695db12308006fe1a6d061642b7d3f1a1Michael Chan p.mPositiveButtonText = getString(R.string.bluetooth_pairing_accept); 2583a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh p.mPositiveButtonListener = this; 259e41a4ca695db12308006fe1a6d061642b7d3f1a1Michael Chan p.mNegativeButtonText = getString(R.string.bluetooth_pairing_decline); 2603a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh p.mNegativeButtonListener = this; 2613a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh setupAlert(); 262afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 263afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 264436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private void createConsentDialog(CachedBluetoothDeviceManager deviceManager) { 265435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh final AlertController.AlertParams p = mAlertParams; 266435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh p.mIconId = android.R.drawable.ic_dialog_info; 267435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh p.mTitle = getString(R.string.bluetooth_pairing_request); 268436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby p.mView = createView(deviceManager); 269435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh p.mPositiveButtonText = getString(R.string.bluetooth_pairing_accept); 270435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh p.mPositiveButtonListener = this; 271435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh p.mNegativeButtonText = getString(R.string.bluetooth_pairing_decline); 272435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh p.mNegativeButtonListener = this; 273435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh setupAlert(); 274afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 275afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 276436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private void createDisplayPasskeyOrPinDialog( 277436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby CachedBluetoothDeviceManager deviceManager) { 278435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh final AlertController.AlertParams p = mAlertParams; 279435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh p.mIconId = android.R.drawable.ic_dialog_info; 280435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh p.mTitle = getString(R.string.bluetooth_pairing_request); 281436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby p.mView = createView(deviceManager); 282da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh p.mNegativeButtonText = getString(android.R.string.cancel); 283da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh p.mNegativeButtonListener = this; 284435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh setupAlert(); 2853a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh 286435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh // Since its only a notification, send an OK to the framework, 287435ad270b5f4e31e94a2bba204769660bbd4b3caJaikumar Ganesh // indicating that the dialog has been displayed. 288da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh if (mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY) { 289da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh mDevice.setPairingConfirmation(true); 290da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh } else if (mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN) { 291da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh byte[] pinBytes = BluetoothDevice.convertPinToBytes(mPairingKey); 292da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh mDevice.setPin(pinBytes); 293da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh } 294afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 295afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 296afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project @Override 297afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project protected void onDestroy() { 298afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project super.onDestroy(); 299afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project unregisterReceiver(mReceiver); 300afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 301afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 302afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project public void afterTextChanged(Editable s) { 3032affa6b28ddacc87f0f95f2ddd124b256ff61850jhtop.kim if (mOkButton != null) { 3042affa6b28ddacc87f0f95f2ddd124b256ff61850jhtop.kim mOkButton.setEnabled(s.length() > 0); 305afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 306afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 307afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 3083a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh private void onPair(String value) { 309436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby switch (mType) { 310436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_PIN: 311436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby byte[] pinBytes = BluetoothDevice.convertPinToBytes(value); 312436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (pinBytes == null) { 313436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return; 314436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby } 315436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mDevice.setPin(pinBytes); 316436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 317436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 318436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_PASSKEY: 319436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby int passkey = Integer.parseInt(value); 320436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mDevice.setPasskey(passkey); 321436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 322436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 323436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION: 324436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_CONSENT: 325436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mDevice.setPairingConfirmation(true); 326436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 327436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 328436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY: 329436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN: 330436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby // Do nothing. 331436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 332436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 333436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT: 334436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby mDevice.setRemoteOutOfBandData(); 335436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby break; 336436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby 337436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby default: 338436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby Log.e(TAG, "Incorrect pairing type received"); 339afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 340afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 341afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 342afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project private void onCancel() { 343cb6a3b3d9e39d63bbf10d947579989e44bcc0b98Jaikumar Ganesh mDevice.cancelPairingUserInput(); 344afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 345aaf8ffff79a73c71d3fb77a31950e344f4c7eab5jhtop.kim 346aaf8ffff79a73c71d3fb77a31950e344f4c7eab5jhtop.kim public boolean onKeyDown(int keyCode, KeyEvent event) { 347aaf8ffff79a73c71d3fb77a31950e344f4c7eab5jhtop.kim if (keyCode == KeyEvent.KEYCODE_BACK) { 348aaf8ffff79a73c71d3fb77a31950e344f4c7eab5jhtop.kim onCancel(); 349aaf8ffff79a73c71d3fb77a31950e344f4c7eab5jhtop.kim } 350aaf8ffff79a73c71d3fb77a31950e344f4c7eab5jhtop.kim return super.onKeyDown(keyCode,event); 351aaf8ffff79a73c71d3fb77a31950e344f4c7eab5jhtop.kim } 3523a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh 353afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project public void onClick(DialogInterface dialog, int which) { 354afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project switch (which) { 355436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BUTTON_POSITIVE: 356ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby if (mPairingView != null) { 357ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby onPair(mPairingView.getText().toString()); 358ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby } else { 359ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby onPair(null); 360ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby } 361afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project break; 3623a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh 363436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby case BUTTON_NEGATIVE: 364436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby default: 365afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project onCancel(); 366afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project break; 367afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 368afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 369afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 370afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project /* Not used */ 371afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project public void beforeTextChanged(CharSequence s, int start, int count, int after) { 372afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 373afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 374afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project /* Not used */ 375afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project public void onTextChanged(CharSequence s, int start, int before, int count) { 376afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 377afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 378ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 379ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby // change input type for soft keyboard to numeric or alphanumeric 380ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby if (isChecked) { 381ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby mPairingView.setInputType(InputType.TYPE_CLASS_TEXT); 382ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby } else { 383ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby mPairingView.setInputType(InputType.TYPE_CLASS_NUMBER); 384ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby } 385ca9812a8521fcc483e821fd5a88ec421de0b8f66Jake Hamby } 386afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project} 387