summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/bluetooth/LocalBluetoothManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/settings/bluetooth/LocalBluetoothManager.java')
-rw-r--r--src/com/android/settings/bluetooth/LocalBluetoothManager.java382
1 files changed, 51 insertions, 331 deletions
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothManager.java b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
index f3c5e6f30..0c04e2273 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,376 +16,96 @@
package com.android.settings.bluetooth;
-import com.android.settings.R;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.ParcelUuid;
-import android.util.Config;
import android.util.Log;
-import android.widget.Toast;
-
-import java.util.ArrayList;
-import java.util.List;
-// TODO: have some notion of shutting down. Maybe a minute after they leave BT settings?
/**
* LocalBluetoothManager provides a simplified interface on top of a subset of
- * the Bluetooth API.
+ * the Bluetooth API. Note that {@link #getInstance} will return null
+ * if there is no Bluetooth adapter on this device, and callers must be
+ * prepared to handle this case.
*/
-public class LocalBluetoothManager {
+public final class LocalBluetoothManager {
private static final String TAG = "LocalBluetoothManager";
- static final boolean V = Config.LOGV;
- static final boolean D = Config.LOGD;
-
- private static final String SHARED_PREFERENCES_NAME = "bluetooth_settings";
/** Singleton instance. */
private static LocalBluetoothManager sInstance;
- private Context mContext;
- /** If a BT-related activity is in the foreground, this will be it. */
- private Activity mForegroundActivity;
- private AlertDialog mErrorDialog = null;
-
- private BluetoothAdapter mAdapter;
-
- private CachedBluetoothDeviceManager mCachedDeviceManager;
- private BluetoothA2dp mBluetoothA2dp;
-
- private int mState = BluetoothAdapter.ERROR;
+ private final Context mContext;
- private final List<Callback> mCallbacks = new ArrayList<Callback>();
-
- private static final int SCAN_EXPIRATION_MS = 5 * 60 * 1000; // 5 mins
-
- // If a device was picked from the device picker or was in discoverable mode
- // in the last 60 seconds, show the pairing dialogs in foreground instead
- // of raising notifications
- private static final int GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND = 60 * 1000;
-
- public static final String SHARED_PREFERENCES_KEY_DISCOVERING_TIMESTAMP =
- "last_discovering_time";
-
- private static final String SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE =
- "last_selected_device";
+ /** If a BT-related activity is in the foreground, this will be it. */
+ private Context mForegroundActivity;
- private static final String SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE_TIME =
- "last_selected_device_time";
+ private final LocalBluetoothAdapter mLocalAdapter;
- private static final String SHARED_PREFERENCES_KEY_DOCK_AUTO_CONNECT = "auto_connect_to_dock";
+ private final CachedBluetoothDeviceManager mCachedDeviceManager;
- private long mLastScan;
+ /** The Bluetooth profile manager. */
+ private final LocalBluetoothProfileManager mProfileManager;
- private LocalBluetoothManager() { }
+ /** The broadcast receiver event manager. */
+ private final BluetoothEventManager mEventManager;
- public static LocalBluetoothManager getInstance(Context context) {
- synchronized (LocalBluetoothManager.class) {
- if (sInstance == null) {
- sInstance = new LocalBluetoothManager();
- if (!sInstance.init(context)) {
- return null;
- }
- LocalBluetoothProfileManager.init(sInstance);
+ public static synchronized LocalBluetoothManager getInstance(Context context) {
+ if (sInstance == null) {
+ LocalBluetoothAdapter adapter = LocalBluetoothAdapter.getInstance();
+ if (adapter == null) {
+ return null;
}
-
- return sInstance;
- }
- }
-
- private boolean init(Context context) {
- // This will be around as long as this process is
- mContext = context.getApplicationContext();
-
- mAdapter = BluetoothAdapter.getDefaultAdapter();
- if (mAdapter == null) {
- return false;
+ // This will be around as long as this process is
+ Context appContext = context.getApplicationContext();
+ sInstance = new LocalBluetoothManager(adapter, appContext);
}
- mCachedDeviceManager = new CachedBluetoothDeviceManager(this);
-
- new BluetoothEventRedirector(this).registerReceiver();
+ return sInstance;
+ }
- mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP);
+ private LocalBluetoothManager(LocalBluetoothAdapter adapter, Context context) {
+ mContext = context;
+ mLocalAdapter = adapter;
- return true;
+ mCachedDeviceManager = new CachedBluetoothDeviceManager();
+ mEventManager = new BluetoothEventManager(mLocalAdapter,
+ mCachedDeviceManager);
+ mProfileManager = new LocalBluetoothProfileManager(context,
+ mLocalAdapter, mCachedDeviceManager, mEventManager);
}
- private final BluetoothProfile.ServiceListener mProfileListener =
- new BluetoothProfile.ServiceListener() {
- public void onServiceConnected(int profile, BluetoothProfile proxy) {
- mBluetoothA2dp = (BluetoothA2dp) proxy;
- }
- public void onServiceDisconnected(int profile) {
- mBluetoothA2dp = null;
- }
- };
-
- public BluetoothAdapter getBluetoothAdapter() {
- return mAdapter;
+ public LocalBluetoothAdapter getBluetoothAdapter() {
+ return mLocalAdapter;
}
public Context getContext() {
return mContext;
}
- public Activity getForegroundActivity() {
- return mForegroundActivity;
- }
-
- public void setForegroundActivity(Activity activity) {
- if (mErrorDialog != null) {
- mErrorDialog.dismiss();
- mErrorDialog = null;
- }
- mForegroundActivity = activity;
+ boolean isForegroundActivity() {
+ return mForegroundActivity != null;
}
- public SharedPreferences getSharedPreferences() {
- return mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
- }
-
- public CachedBluetoothDeviceManager getCachedDeviceManager() {
- return mCachedDeviceManager;
- }
-
- List<Callback> getCallbacks() {
- return mCallbacks;
- }
-
- public void registerCallback(Callback callback) {
- synchronized (mCallbacks) {
- mCallbacks.add(callback);
- }
- }
-
- public void unregisterCallback(Callback callback) {
- synchronized (mCallbacks) {
- mCallbacks.remove(callback);
- }
- }
-
- public void startScanning(boolean force) {
- if (mAdapter.isDiscovering()) {
- /*
- * Already discovering, but give the callback that information.
- * Note: we only call the callbacks, not the same path as if the
- * scanning state had really changed (in that case the device
- * manager would clear its list of unpaired scanned devices).
- */
- dispatchScanningStateChanged(true);
+ synchronized void setForegroundActivity(Context context) {
+ if (context != null) {
+ Log.d(TAG, "setting foreground activity to non-null context");
+ mForegroundActivity = context;
+ mEventManager.resume(context);
} else {
- if (!force) {
- // Don't scan more than frequently than SCAN_EXPIRATION_MS,
- // unless forced
- if (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) {
- return;
- }
-
- // If we are playing music, don't scan unless forced.
- if (mBluetoothA2dp != null) {
- List<BluetoothDevice> sinks = mBluetoothA2dp.getConnectedDevices();
- if (sinks.size() > 0) {
- if (mBluetoothA2dp.isA2dpPlaying(sinks.get(0))) return;
- }
- }
+ if (mForegroundActivity != null) {
+ Log.d(TAG, "setting foreground activity to null");
+ mEventManager.pause(mForegroundActivity);
+ mForegroundActivity = null;
}
-
- if (mAdapter.startDiscovery()) {
- mLastScan = System.currentTimeMillis();
- }
- }
- }
-
- public void stopScanning() {
- if (mAdapter.isDiscovering()) {
- mAdapter.cancelDiscovery();
- }
- }
-
- public int getBluetoothState() {
-
- if (mState == BluetoothAdapter.ERROR) {
- syncBluetoothState();
}
-
- return mState;
}
- void setBluetoothStateInt(int state) {
- mState = state;
-
- if (state == BluetoothAdapter.STATE_ON) {
- ParcelUuid[] uuids = mAdapter.getUuids();
- LocalBluetoothProfileManager.updateLocalProfiles(getInstance(mContext), uuids);
- }
-
- if (state == BluetoothAdapter.STATE_ON ||
- state == BluetoothAdapter.STATE_OFF) {
- mCachedDeviceManager.onBluetoothStateChanged(state ==
- BluetoothAdapter.STATE_ON);
- }
- }
-
- private void syncBluetoothState() {
- int bluetoothState;
-
- if (mAdapter != null) {
- bluetoothState = mAdapter.isEnabled()
- ? BluetoothAdapter.STATE_ON
- : BluetoothAdapter.STATE_OFF;
- } else {
- bluetoothState = BluetoothAdapter.ERROR;
- }
-
- setBluetoothStateInt(bluetoothState);
- }
-
- public void setBluetoothEnabled(boolean enabled) {
- boolean wasSetStateSuccessful = enabled
- ? mAdapter.enable()
- : mAdapter.disable();
-
- if (wasSetStateSuccessful) {
- setBluetoothStateInt(enabled
- ? BluetoothAdapter.STATE_TURNING_ON
- : BluetoothAdapter.STATE_TURNING_OFF);
- } else {
- if (V) {
- Log.v(TAG,
- "setBluetoothEnabled call, manager didn't return success for enabled: "
- + enabled);
- }
-
- syncBluetoothState();
- }
- }
-
- /**
- * @param started True if scanning started, false if scanning finished.
- */
- void onScanningStateChanged(boolean started) {
- // TODO: have it be a callback (once we switch bluetooth state changed to callback)
- mCachedDeviceManager.onScanningStateChanged(started);
- dispatchScanningStateChanged(started);
- }
-
- private void dispatchScanningStateChanged(boolean started) {
- synchronized (mCallbacks) {
- for (Callback callback : mCallbacks) {
- callback.onScanningStateChanged(started);
- }
- }
- }
-
- public void showError(BluetoothDevice device, int messageResId) {
- CachedBluetoothDevice cachedDevice = mCachedDeviceManager.findDevice(device);
- String name = null;
- if (cachedDevice == null) {
- if (device != null) name = device.getName();
-
- if (name == null) {
- name = mContext.getString(R.string.bluetooth_remote_device);
- }
- } else {
- name = cachedDevice.getName();
- }
- String message = mContext.getString(messageResId, name);
-
- if (mForegroundActivity != null) {
- // Need an activity context to show a dialog
- mErrorDialog = new AlertDialog.Builder(mForegroundActivity)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setTitle(R.string.bluetooth_error_title)
- .setMessage(message)
- .setPositiveButton(android.R.string.ok, null)
- .show();
- } else {
- // Fallback on a toast
- Toast.makeText(mContext, message, Toast.LENGTH_LONG).show();
- }
- }
-
- public interface Callback {
- void onScanningStateChanged(boolean started);
- void onDeviceAdded(CachedBluetoothDevice cachedDevice);
- void onDeviceDeleted(CachedBluetoothDevice cachedDevice);
- void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState);
- }
-
- public boolean shouldShowDialogInForeground(String deviceAddress) {
- // If Bluetooth Settings is visible
- if (mForegroundActivity != null) return true;
-
- long currentTimeMillis = System.currentTimeMillis();
- SharedPreferences sharedPreferences = getSharedPreferences();
-
- // If the device was in discoverABLE mode recently
- long lastDiscoverableEndTime = sharedPreferences.getLong(
- BluetoothDiscoverableEnabler.SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP, 0);
- if ((lastDiscoverableEndTime + GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND)
- > currentTimeMillis) {
- return true;
- }
-
- // If the device was discoverING recently
- if (mAdapter != null && mAdapter.isDiscovering()) {
- return true;
- } else if ((sharedPreferences.getLong(SHARED_PREFERENCES_KEY_DISCOVERING_TIMESTAMP, 0) +
- GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND) > currentTimeMillis) {
- return true;
- }
-
- // If the device was picked in the device picker recently
- if (deviceAddress != null) {
- String lastSelectedDevice = sharedPreferences.getString(
- SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE, null);
-
- if (deviceAddress.equals(lastSelectedDevice)) {
- long lastDeviceSelectedTime = sharedPreferences.getLong(
- SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE_TIME, 0);
- if ((lastDeviceSelectedTime + GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND)
- > currentTimeMillis) {
- return true;
- }
- }
- }
- return false;
- }
-
- void persistSelectedDeviceInPicker(String deviceAddress) {
- SharedPreferences.Editor editor = getSharedPreferences().edit();
- editor.putString(LocalBluetoothManager.SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE,
- deviceAddress);
- editor.putLong(LocalBluetoothManager.SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE_TIME,
- System.currentTimeMillis());
- editor.apply();
- }
-
- public boolean hasDockAutoConnectSetting(String addr) {
- return getSharedPreferences().contains(SHARED_PREFERENCES_KEY_DOCK_AUTO_CONNECT + addr);
- }
-
- public boolean getDockAutoConnectSetting(String addr) {
- return getSharedPreferences().getBoolean(SHARED_PREFERENCES_KEY_DOCK_AUTO_CONNECT + addr,
- false);
+ CachedBluetoothDeviceManager getCachedDeviceManager() {
+ return mCachedDeviceManager;
}
- public void saveDockAutoConnectSetting(String addr, boolean autoConnect) {
- SharedPreferences.Editor editor = getSharedPreferences().edit();
- editor.putBoolean(SHARED_PREFERENCES_KEY_DOCK_AUTO_CONNECT + addr, autoConnect);
- editor.apply();
+ BluetoothEventManager getEventManager() {
+ return mEventManager;
}
- public void removeDockAutoConnectSetting(String addr) {
- SharedPreferences.Editor editor = getSharedPreferences().edit();
- editor.remove(SHARED_PREFERENCES_KEY_DOCK_AUTO_CONNECT + addr);
- editor.apply();
+ LocalBluetoothProfileManager getProfileManager() {
+ return mProfileManager;
}
}