1/*
2 * Copyright (C) 2008 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 com.android.settings.R;
20
21import android.app.Notification;
22import android.app.NotificationManager;
23import android.app.PendingIntent;
24import android.bluetooth.BluetoothDevice;
25import android.content.BroadcastReceiver;
26import android.content.Context;
27import android.content.Intent;
28import android.content.res.Resources;
29import android.text.TextUtils;
30import android.os.PowerManager;
31
32/**
33 * BluetoothPairingRequest is a receiver for any Bluetooth pairing request. It
34 * checks if the Bluetooth Settings is currently visible and brings up the PIN, the passkey or a
35 * confirmation entry dialog. Otherwise it puts a Notification in the status bar, which can
36 * be clicked to bring up the Pairing entry dialog.
37 */
38public final class BluetoothPairingRequest extends BroadcastReceiver {
39
40    private static final int NOTIFICATION_ID = android.R.drawable.stat_sys_data_bluetooth;
41
42    @Override
43    public void onReceive(Context context, Intent intent) {
44        String action = intent.getAction();
45        if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
46            // convert broadcast intent into activity intent (same action string)
47            BluetoothDevice device =
48                    intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
49            int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
50                    BluetoothDevice.ERROR);
51            Intent pairingIntent = new Intent();
52            pairingIntent.setClass(context, BluetoothPairingDialog.class);
53            pairingIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
54            pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, type);
55            if (type == BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION ||
56                    type == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY ||
57                    type == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN) {
58                int pairingKey = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY,
59                        BluetoothDevice.ERROR);
60                pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, pairingKey);
61            }
62            pairingIntent.setAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
63            pairingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
64
65            PowerManager powerManager =
66                    (PowerManager)context.getSystemService(Context.POWER_SERVICE);
67            String deviceAddress = device != null ? device.getAddress() : null;
68            if (powerManager.isScreenOn() &&
69                    LocalBluetoothPreferences.shouldShowDialogInForeground(context, deviceAddress)) {
70                // Since the screen is on and the BT-related activity is in the foreground,
71                // just open the dialog
72                context.startActivity(pairingIntent);
73            } else {
74                // Put up a notification that leads to the dialog
75                Resources res = context.getResources();
76                Notification.Builder builder = new Notification.Builder(context)
77                        .setSmallIcon(android.R.drawable.stat_sys_data_bluetooth)
78                        .setTicker(res.getString(R.string.bluetooth_notif_ticker));
79
80                PendingIntent pending = PendingIntent.getActivity(context, 0,
81                        pairingIntent, PendingIntent.FLAG_ONE_SHOT);
82
83                String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
84                if (TextUtils.isEmpty(name)) {
85                    name = device != null ? device.getAliasName() :
86                            context.getString(android.R.string.unknownName);
87                }
88
89                builder.setContentTitle(res.getString(R.string.bluetooth_notif_title))
90                        .setContentText(res.getString(R.string.bluetooth_notif_message, name))
91                        .setContentIntent(pending)
92                        .setAutoCancel(true)
93                        .setDefaults(Notification.DEFAULT_SOUND);
94
95                NotificationManager manager = (NotificationManager)
96                        context.getSystemService(Context.NOTIFICATION_SERVICE);
97                manager.notify(NOTIFICATION_ID, builder.getNotification());
98            }
99
100        } else if (action.equals(BluetoothDevice.ACTION_PAIRING_CANCEL)) {
101
102            // Remove the notification
103            NotificationManager manager = (NotificationManager) context
104                    .getSystemService(Context.NOTIFICATION_SERVICE);
105            manager.cancel(NOTIFICATION_ID);
106        }
107    }
108}
109