1436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby/*
2436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * Copyright (C) 2008 The Android Open Source Project
3436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby *
4436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * Licensed under the Apache License, Version 2.0 (the "License");
5436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * you may not use this file except in compliance with the License.
6436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * You may obtain a copy of the License at
7436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby *
8436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby *      http://www.apache.org/licenses/LICENSE-2.0
9436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby *
10436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * Unless required by applicable law or agreed to in writing, software
11436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * distributed under the License is distributed on an "AS IS" BASIS,
12436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * See the License for the specific language governing permissions and
14436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * limitations under the License.
15436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby */
16436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
17436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambypackage com.android.settings.bluetooth;
18436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
19436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.app.QueuedWork;
20436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.content.Context;
21436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyimport android.content.SharedPreferences;
22519dda9c572309182cb29e247adafe2cd475a594Justin Kohimport android.content.res.Configuration;
23436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
24436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby/**
25436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * LocalBluetoothPreferences provides an interface to the preferences
26436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby * related to Bluetooth.
27436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby */
28436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hambyfinal class LocalBluetoothPreferences {
29436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby//    private static final String TAG = "LocalBluetoothPreferences";
30436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
31436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final String SHARED_PREFERENCES_NAME = "bluetooth_settings";
32436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
33436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    // If a device was picked from the device picker or was in discoverable mode
34436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    // in the last 60 seconds, show the pairing dialogs in foreground instead
35436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    // of raising notifications
36436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final int GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND = 60 * 1000;
37436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
38436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final String KEY_DISCOVERING_TIMESTAMP = "last_discovering_time";
39436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
40436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final String KEY_LAST_SELECTED_DEVICE = "last_selected_device";
41436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
42436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final String KEY_LAST_SELECTED_DEVICE_TIME = "last_selected_device_time";
43436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
44436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final String KEY_DOCK_AUTO_CONNECT = "auto_connect_to_dock";
45436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
46436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static final String KEY_DISCOVERABLE_END_TIMESTAMP = "discoverable_end_timestamp";
47436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
48436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private LocalBluetoothPreferences() {
49436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
50436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
51436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    private static SharedPreferences getSharedPreferences(Context context) {
52436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        return context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
53436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
54436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
55436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    static long getDiscoverableEndTimestamp(Context context) {
56436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        return getSharedPreferences(context).getLong(
57436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                KEY_DISCOVERABLE_END_TIMESTAMP, 0);
58436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
59436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
60436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    static boolean shouldShowDialogInForeground(Context context,
61436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            String deviceAddress) {
62436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        LocalBluetoothManager manager = LocalBluetoothManager.getInstance(context);
63436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        if (manager == null) {
64436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return false;
65436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        }
66436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
677b065464c996b792c1ecdd9d8c93db1bf0538b8dJustin Koh        // If Bluetooth Settings is visible
687b065464c996b792c1ecdd9d8c93db1bf0538b8dJustin Koh        if (manager.isForegroundActivity()) {
697b065464c996b792c1ecdd9d8c93db1bf0538b8dJustin Koh            return true;
707b065464c996b792c1ecdd9d8c93db1bf0538b8dJustin Koh        }
717b065464c996b792c1ecdd9d8c93db1bf0538b8dJustin Koh
72519dda9c572309182cb29e247adafe2cd475a594Justin Koh        // If in appliance mode, do not show dialog in foreground.
73519dda9c572309182cb29e247adafe2cd475a594Justin Koh        if ((context.getResources().getConfiguration().uiMode &
74519dda9c572309182cb29e247adafe2cd475a594Justin Koh                Configuration.UI_MODE_TYPE_APPLIANCE) == Configuration.UI_MODE_TYPE_APPLIANCE) {
75519dda9c572309182cb29e247adafe2cd475a594Justin Koh            return false;
76519dda9c572309182cb29e247adafe2cd475a594Justin Koh        }
77519dda9c572309182cb29e247adafe2cd475a594Justin Koh
78436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        long currentTimeMillis = System.currentTimeMillis();
79436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        SharedPreferences sharedPreferences = getSharedPreferences(context);
80436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
81436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        // If the device was in discoverABLE mode recently
82436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        long lastDiscoverableEndTime = sharedPreferences.getLong(
83436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                KEY_DISCOVERABLE_END_TIMESTAMP, 0);
84436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        if ((lastDiscoverableEndTime + GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND)
85436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                > currentTimeMillis) {
86436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return true;
87436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        }
88436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
89436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        // If the device was discoverING recently
90436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        LocalBluetoothAdapter adapter = manager.getBluetoothAdapter();
91436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        if (adapter != null && adapter.isDiscovering()) {
92436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return true;
93436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        } else if ((sharedPreferences.getLong(KEY_DISCOVERING_TIMESTAMP, 0) +
94436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND) > currentTimeMillis) {
95436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            return true;
96436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        }
97436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
98436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        // If the device was picked in the device picker recently
99436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        if (deviceAddress != null) {
100436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            String lastSelectedDevice = sharedPreferences.getString(
101436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    KEY_LAST_SELECTED_DEVICE, null);
102436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
103436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            if (deviceAddress.equals(lastSelectedDevice)) {
104436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                long lastDeviceSelectedTime = sharedPreferences.getLong(
105436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        KEY_LAST_SELECTED_DEVICE_TIME, 0);
106436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                if ((lastDeviceSelectedTime + GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND)
107436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        > currentTimeMillis) {
108436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    return true;
109436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                }
110436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            }
111436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        }
112436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        return false;
113436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
114436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
115436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    static void persistSelectedDeviceInPicker(Context context, String deviceAddress) {
116436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        SharedPreferences.Editor editor = getSharedPreferences(context).edit();
117436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        editor.putString(KEY_LAST_SELECTED_DEVICE,
118436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                deviceAddress);
119436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        editor.putLong(KEY_LAST_SELECTED_DEVICE_TIME,
120436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                System.currentTimeMillis());
121436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        editor.apply();
122436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
123436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
124436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    static void persistDiscoverableEndTimestamp(Context context, long endTimestamp) {
125436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        SharedPreferences.Editor editor = getSharedPreferences(context).edit();
126436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        editor.putLong(KEY_DISCOVERABLE_END_TIMESTAMP, endTimestamp);
127436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        editor.apply();
128436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
129436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
130436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    static void persistDiscoveringTimestamp(final Context context) {
131436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        // Load the shared preferences and edit it on a background
132436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        // thread (but serialized!).
133436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        QueuedWork.singleThreadExecutor().submit(new Runnable() {
134436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                public void run() {
135436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    SharedPreferences.Editor editor = getSharedPreferences(context).edit();
136436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    editor.putLong(
137436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                            KEY_DISCOVERING_TIMESTAMP,
138436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                        System.currentTimeMillis());
139436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                    editor.apply();
140436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                }
141436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby            });
142436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
143436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
144436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    static boolean hasDockAutoConnectSetting(Context context, String addr) {
145436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        return getSharedPreferences(context).contains(KEY_DOCK_AUTO_CONNECT + addr);
146436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
147436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
148436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    static boolean getDockAutoConnectSetting(Context context, String addr) {
149436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        return getSharedPreferences(context).getBoolean(KEY_DOCK_AUTO_CONNECT + addr,
150436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby                false);
151436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
152436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
153436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    static void saveDockAutoConnectSetting(Context context, String addr, boolean autoConnect) {
154436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        SharedPreferences.Editor editor = getSharedPreferences(context).edit();
155436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        editor.putBoolean(KEY_DOCK_AUTO_CONNECT + addr, autoConnect);
156436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        editor.apply();
157436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
158436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby
159436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    static void removeDockAutoConnectSetting(Context context, String addr) {
160436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        SharedPreferences.Editor editor = getSharedPreferences(context).edit();
161436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        editor.remove(KEY_DOCK_AUTO_CONNECT + addr);
162436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby        editor.apply();
163436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby    }
164436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby}
165