1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.settings.bluetooth; 18 19import android.annotation.Nullable; 20import android.app.Activity; 21import android.bluetooth.BluetoothDevice; 22import android.content.BroadcastReceiver; 23import android.content.Context; 24import android.content.Intent; 25import android.content.IntentFilter; 26import android.os.Bundle; 27import android.support.annotation.VisibleForTesting; 28 29/** 30 * BluetoothPairingDialog asks the user to enter a PIN / Passkey / simple confirmation 31 * for pairing with a remote Bluetooth device. It is an activity that appears as a dialog. 32 */ 33public class BluetoothPairingDialog extends Activity { 34 public static final String FRAGMENT_TAG = "bluetooth.pairing.fragment"; 35 36 private BluetoothPairingController mBluetoothPairingController; 37 private boolean mReceiverRegistered = false; 38 39 /** 40 * Dismiss the dialog if the bond state changes to bonded or none, 41 * or if pairing was canceled for {@link BluetoothPairingController#mDevice}. 42 */ 43 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 44 @Override 45 public void onReceive(Context context, Intent intent) { 46 String action = intent.getAction(); 47 if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) { 48 int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, 49 BluetoothDevice.ERROR); 50 if (bondState == BluetoothDevice.BOND_BONDED || 51 bondState == BluetoothDevice.BOND_NONE) { 52 dismiss(); 53 } 54 } else if (BluetoothDevice.ACTION_PAIRING_CANCEL.equals(action)) { 55 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 56 if (device == null || mBluetoothPairingController.deviceEquals(device)) { 57 dismiss(); 58 } 59 } 60 } 61 }; 62 63 @Override 64 protected void onCreate(@Nullable Bundle savedInstanceState) { 65 super.onCreate(savedInstanceState); 66 Intent intent = getIntent(); 67 mBluetoothPairingController = new BluetoothPairingController(intent, this); 68 // build the dialog fragment 69 boolean fragmentFound = true; 70 // check if the fragment has been preloaded 71 BluetoothPairingDialogFragment bluetoothFragment = 72 (BluetoothPairingDialogFragment) getFragmentManager().findFragmentByTag(FRAGMENT_TAG); 73 // dismiss the fragment if it is already used 74 if (bluetoothFragment != null && (bluetoothFragment.isPairingControllerSet() 75 || bluetoothFragment.isPairingDialogActivitySet())) { 76 bluetoothFragment.dismiss(); 77 bluetoothFragment = null; 78 } 79 // build a new fragment if it is null 80 if (bluetoothFragment == null) { 81 fragmentFound = false; 82 bluetoothFragment = new BluetoothPairingDialogFragment(); 83 } 84 bluetoothFragment.setPairingController(mBluetoothPairingController); 85 bluetoothFragment.setPairingDialogActivity(this); 86 // pass the fragment to the manager when it is created from scratch 87 if (!fragmentFound) { 88 bluetoothFragment.show(getFragmentManager(), FRAGMENT_TAG); 89 } 90 /* 91 * Leave this registered through pause/resume since we still want to 92 * finish the activity in the background if pairing is canceled. 93 */ 94 registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_PAIRING_CANCEL)); 95 registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED)); 96 mReceiverRegistered = true; 97 } 98 99 @Override 100 protected void onDestroy() { 101 super.onDestroy(); 102 if (mReceiverRegistered) { 103 mReceiverRegistered = false; 104 unregisterReceiver(mReceiver); 105 } 106 } 107 108 @VisibleForTesting 109 void dismiss() { 110 if (!isFinishing()) { 111 BluetoothPairingDialogFragment bluetoothFragment = 112 (BluetoothPairingDialogFragment) getFragmentManager() 113 .findFragmentByTag(FRAGMENT_TAG); 114 if (bluetoothFragment != null) { 115 bluetoothFragment.dismiss(); 116 } 117 finish(); 118 } 119 } 120} 121