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 com.android.settings.R;
20afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
21afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.Notification;
22afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.NotificationManager;
23afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.PendingIntent;
24afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.bluetooth.BluetoothDevice;
25afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.BroadcastReceiver;
26afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Context;
27afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent;
28afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.res.Resources;
29afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.text.TextUtils;
3083c3b64ff7235e1382712a899ab0a269ce8a28d6Erik Ljungbergimport android.os.PowerManager;
31afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
32afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/**
333a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh * BluetoothPairingRequest is a receiver for any Bluetooth pairing request. It
343a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh * checks if the Bluetooth Settings is currently visible and brings up the PIN, the passkey or a
353a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh * confirmation entry dialog. Otherwise it puts a Notification in the status bar, which can
363a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh * be clicked to bring up the Pairing entry dialog.
37afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
38436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambypublic final class BluetoothPairingRequest extends BroadcastReceiver {
39afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
40436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final int NOTIFICATION_ID = android.R.drawable.stat_sys_data_bluetooth;
413a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh
42afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
43afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onReceive(Context context, Intent intent) {
44afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        String action = intent.getAction();
4516cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly        if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
46436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            // convert broadcast intent into activity intent (same action string)
47d63c0112251ab4e4e977545368dd703d875012a4Nick Pelly            BluetoothDevice device =
4816cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly                    intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
4916cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly            int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
5016cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly                    BluetoothDevice.ERROR);
513a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh            Intent pairingIntent = new Intent();
523a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh            pairingIntent.setClass(context, BluetoothPairingDialog.class);
5316cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly            pairingIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
5416cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly            pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, type);
555f23cb39a1bd9c319383108c209fca7f0256894bJaikumar Ganesh            if (type == BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION ||
56da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh                    type == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY ||
57da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh                    type == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN) {
58da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh                int pairingKey = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY,
59da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh                        BluetoothDevice.ERROR);
60da23ae88d110dce585b19581a180feefbb0be4c8Jaikumar Ganesh                pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, pairingKey);
613a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh            }
6216cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly            pairingIntent.setAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
633a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh            pairingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
643a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh
6583c3b64ff7235e1382712a899ab0a269ce8a28d6Erik Ljungberg            PowerManager powerManager =
6683c3b64ff7235e1382712a899ab0a269ce8a28d6Erik Ljungberg                    (PowerManager)context.getSystemService(Context.POWER_SERVICE);
675469ff8b3f9966c6f141078b37da5f178b7825e4Michael Chan            String deviceAddress = device != null ? device.getAddress() : null;
6883c3b64ff7235e1382712a899ab0a269ce8a28d6Erik Ljungberg            if (powerManager.isScreenOn() &&
69436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    LocalBluetoothPreferences.shouldShowDialogInForeground(context, deviceAddress)) {
7083c3b64ff7235e1382712a899ab0a269ce8a28d6Erik Ljungberg                // Since the screen is on and the BT-related activity is in the foreground,
7183c3b64ff7235e1382712a899ab0a269ce8a28d6Erik Ljungberg                // just open the dialog
723a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh                context.startActivity(pairingIntent);
73afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            } else {
74afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // Put up a notification that leads to the dialog
75afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Resources res = context.getResources();
76436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                Notification.Builder builder = new Notification.Builder(context)
77436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        .setSmallIcon(android.R.drawable.stat_sys_data_bluetooth)
78436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        .setTicker(res.getString(R.string.bluetooth_notif_ticker));
79afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
803a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh                PendingIntent pending = PendingIntent.getActivity(context, 0,
813a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh                        pairingIntent, PendingIntent.FLAG_ONE_SHOT);
823a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh
8316cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly                String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
84afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if (TextUtils.isEmpty(name)) {
852036ebd8896bbabbbe04db34c9e7d8a1be6fe32aMatthew Xie                    name = device != null ? device.getAliasName() :
86436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                            context.getString(android.R.string.unknownName);
87afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
883a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh
89436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                builder.setContentTitle(res.getString(R.string.bluetooth_notif_title))
90436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        .setContentText(res.getString(R.string.bluetooth_notif_message, name))
91436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        .setContentIntent(pending)
92436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        .setAutoCancel(true)
934ce62f3fab5b0b74f3d5839579b795d360e32272Selim Cinek                        .setDefaults(Notification.DEFAULT_SOUND)
944ce62f3fab5b0b74f3d5839579b795d360e32272Selim Cinek                        .setColor(res.getColor(
954ce62f3fab5b0b74f3d5839579b795d360e32272Selim Cinek                                com.android.internal.R.color.system_notification_accent_color));
963a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh
973a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh                NotificationManager manager = (NotificationManager)
98afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        context.getSystemService(Context.NOTIFICATION_SERVICE);
99436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                manager.notify(NOTIFICATION_ID, builder.getNotification());
100afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1013a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh
10216cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly        } else if (action.equals(BluetoothDevice.ACTION_PAIRING_CANCEL)) {
1033a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh
104afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Remove the notification
105afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            NotificationManager manager = (NotificationManager) context
106afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    .getSystemService(Context.NOTIFICATION_SERVICE);
107afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            manager.cancel(NOTIFICATION_ID);
10868926914213742311fbab28da7883f9ea3f341b6Srinu Jella
10968926914213742311fbab28da7883f9ea3f341b6Srinu Jella        } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
11068926914213742311fbab28da7883f9ea3f341b6Srinu Jella            int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
11168926914213742311fbab28da7883f9ea3f341b6Srinu Jella                    BluetoothDevice.ERROR);
11268926914213742311fbab28da7883f9ea3f341b6Srinu Jella            int oldState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
11368926914213742311fbab28da7883f9ea3f341b6Srinu Jella                    BluetoothDevice.ERROR);
11468926914213742311fbab28da7883f9ea3f341b6Srinu Jella            if((oldState == BluetoothDevice.BOND_BONDING) &&
11568926914213742311fbab28da7883f9ea3f341b6Srinu Jella                    (bondState == BluetoothDevice.BOND_NONE)) {
11668926914213742311fbab28da7883f9ea3f341b6Srinu Jella                // Remove the notification
11768926914213742311fbab28da7883f9ea3f341b6Srinu Jella                NotificationManager manager = (NotificationManager) context
11868926914213742311fbab28da7883f9ea3f341b6Srinu Jella                    .getSystemService(Context.NOTIFICATION_SERVICE);
11968926914213742311fbab28da7883f9ea3f341b6Srinu Jella                manager.cancel(NOTIFICATION_ID);
12068926914213742311fbab28da7883f9ea3f341b6Srinu Jella            }
121afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
122afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
123afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
124