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.app.Notification;
20afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.NotificationManager;
21afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.PendingIntent;
22afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.bluetooth.BluetoothDevice;
23afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.BroadcastReceiver;
24afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Context;
25afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent;
26afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.res.Resources;
2783c3b64ff7235e1382712a899ab0a269ce8a28d6Erik Ljungbergimport android.os.PowerManager;
2839b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.text.TextUtils;
2939b467482d1bf256a111c757e9b7621c6f523271Jason Monk
3039b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.settings.R;
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;
68dab743b95ce5ee108794751f8c34f9193739c512Michael Wright            String deviceName = device != null ? device.getName() : null;
69dab743b95ce5ee108794751f8c34f9193739c512Michael Wright            boolean shouldShowDialog= LocalBluetoothPreferences.shouldShowDialogInForeground(
70dab743b95ce5ee108794751f8c34f9193739c512Michael Wright                        context, deviceAddress, deviceName);
71dab743b95ce5ee108794751f8c34f9193739c512Michael Wright            if (powerManager.isInteractive() && shouldShowDialog) {
7283c3b64ff7235e1382712a899ab0a269ce8a28d6Erik Ljungberg                // Since the screen is on and the BT-related activity is in the foreground,
7383c3b64ff7235e1382712a899ab0a269ce8a28d6Erik Ljungberg                // just open the dialog
743a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh                context.startActivity(pairingIntent);
75afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            } else {
76afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // Put up a notification that leads to the dialog
77afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Resources res = context.getResources();
78436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                Notification.Builder builder = new Notification.Builder(context)
79436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        .setSmallIcon(android.R.drawable.stat_sys_data_bluetooth)
80436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        .setTicker(res.getString(R.string.bluetooth_notif_ticker));
81afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
823a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh                PendingIntent pending = PendingIntent.getActivity(context, 0,
833a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh                        pairingIntent, PendingIntent.FLAG_ONE_SHOT);
843a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh
8516cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly                String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
86afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if (TextUtils.isEmpty(name)) {
872036ebd8896bbabbbe04db34c9e7d8a1be6fe32aMatthew Xie                    name = device != null ? device.getAliasName() :
88436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                            context.getString(android.R.string.unknownName);
89afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
903a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh
91436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                builder.setContentTitle(res.getString(R.string.bluetooth_notif_title))
92436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        .setContentText(res.getString(R.string.bluetooth_notif_message, name))
93436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        .setContentIntent(pending)
94436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        .setAutoCancel(true)
954ce62f3fab5b0b74f3d5839579b795d360e32272Selim Cinek                        .setDefaults(Notification.DEFAULT_SOUND)
9655eaa96fe44ab473975fd2d9b3d97836935752feAlan Viverette                        .setColor(context.getColor(
974ce62f3fab5b0b74f3d5839579b795d360e32272Selim Cinek                                com.android.internal.R.color.system_notification_accent_color));
983a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh
993a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh                NotificationManager manager = (NotificationManager)
100afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        context.getSystemService(Context.NOTIFICATION_SERVICE);
101436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                manager.notify(NOTIFICATION_ID, builder.getNotification());
102afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
1033a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh
10416cc86315d7a8e1f6a0f3083d0a810a7cb097832Nick Pelly        } else if (action.equals(BluetoothDevice.ACTION_PAIRING_CANCEL)) {
1053a76bcaa83c15f96832f934e67e6f0190e72a3dcJaikumar Ganesh
106afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Remove the notification
107afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            NotificationManager manager = (NotificationManager) context
108afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    .getSystemService(Context.NOTIFICATION_SERVICE);
109afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            manager.cancel(NOTIFICATION_ID);
11068926914213742311fbab28da7883f9ea3f341b6Srinu Jella
11168926914213742311fbab28da7883f9ea3f341b6Srinu Jella        } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
11268926914213742311fbab28da7883f9ea3f341b6Srinu Jella            int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
11368926914213742311fbab28da7883f9ea3f341b6Srinu Jella                    BluetoothDevice.ERROR);
11468926914213742311fbab28da7883f9ea3f341b6Srinu Jella            int oldState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
11568926914213742311fbab28da7883f9ea3f341b6Srinu Jella                    BluetoothDevice.ERROR);
11668926914213742311fbab28da7883f9ea3f341b6Srinu Jella            if((oldState == BluetoothDevice.BOND_BONDING) &&
11768926914213742311fbab28da7883f9ea3f341b6Srinu Jella                    (bondState == BluetoothDevice.BOND_NONE)) {
11868926914213742311fbab28da7883f9ea3f341b6Srinu Jella                // Remove the notification
11968926914213742311fbab28da7883f9ea3f341b6Srinu Jella                NotificationManager manager = (NotificationManager) context
12068926914213742311fbab28da7883f9ea3f341b6Srinu Jella                    .getSystemService(Context.NOTIFICATION_SERVICE);
12168926914213742311fbab28da7883f9ea3f341b6Srinu Jella                manager.cancel(NOTIFICATION_ID);
12268926914213742311fbab28da7883f9ea3f341b6Srinu Jella            }
123afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
124afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
125afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
126