eclair snapshot
This commit is contained in:
@@ -18,22 +18,21 @@ package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.bluetooth.BluetoothA2dp;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothError;
|
||||
import android.bluetooth.BluetoothIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.util.Config;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
// 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
|
||||
@@ -42,43 +41,57 @@ import android.widget.Toast;
|
||||
public class LocalBluetoothManager {
|
||||
private static final String TAG = "LocalBluetoothManager";
|
||||
static final boolean V = Config.LOGV;
|
||||
static final boolean D = Config.LOGD && false;
|
||||
|
||||
static final boolean D = Config.LOGD;
|
||||
|
||||
private static final String SHARED_PREFERENCES_NAME = "bluetooth_settings";
|
||||
|
||||
|
||||
private static LocalBluetoothManager INSTANCE;
|
||||
/** Used when obtaining a reference to the singleton instance. */
|
||||
private static Object INSTANCE_LOCK = new Object();
|
||||
private boolean mInitialized;
|
||||
|
||||
|
||||
private Context mContext;
|
||||
/** If a BT-related activity is in the foreground, this will be it. */
|
||||
private Activity mForegroundActivity;
|
||||
private AlertDialog mErrorDialog = null;
|
||||
|
||||
private BluetoothDevice mManager;
|
||||
private BluetoothAdapter mAdapter;
|
||||
|
||||
private LocalBluetoothDeviceManager mLocalDeviceManager;
|
||||
private CachedBluetoothDeviceManager mCachedDeviceManager;
|
||||
private BluetoothEventRedirector mEventRedirector;
|
||||
private BluetoothA2dp mBluetoothA2dp;
|
||||
|
||||
private int mState = BluetoothError.ERROR;
|
||||
|
||||
private int mState = BluetoothAdapter.ERROR;
|
||||
|
||||
private 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 long GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND = 60 * 1000;
|
||||
|
||||
private static final String SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE =
|
||||
"last_selected_device";
|
||||
|
||||
private static final String SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE_TIME =
|
||||
"last_selected_device_time";
|
||||
|
||||
private long mLastScan;
|
||||
|
||||
|
||||
public static LocalBluetoothManager getInstance(Context context) {
|
||||
synchronized (INSTANCE_LOCK) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new LocalBluetoothManager();
|
||||
}
|
||||
|
||||
|
||||
if (!INSTANCE.init(context)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
LocalBluetoothProfileManager.init(INSTANCE);
|
||||
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
@@ -86,16 +99,16 @@ public class LocalBluetoothManager {
|
||||
private boolean init(Context context) {
|
||||
if (mInitialized) return true;
|
||||
mInitialized = true;
|
||||
|
||||
|
||||
// This will be around as long as this process is
|
||||
mContext = context.getApplicationContext();
|
||||
|
||||
mManager = (BluetoothDevice) context.getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
if (mManager == null) {
|
||||
|
||||
mAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
if (mAdapter == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mLocalDeviceManager = new LocalBluetoothDeviceManager(this);
|
||||
|
||||
mCachedDeviceManager = new CachedBluetoothDeviceManager(this);
|
||||
|
||||
mEventRedirector = new BluetoothEventRedirector(this);
|
||||
mEventRedirector.start();
|
||||
@@ -104,11 +117,11 @@ public class LocalBluetoothManager {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public BluetoothDevice getBluetoothManager() {
|
||||
return mManager;
|
||||
|
||||
public BluetoothAdapter getBluetoothAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
@@ -116,7 +129,7 @@ public class LocalBluetoothManager {
|
||||
public Activity getForegroundActivity() {
|
||||
return mForegroundActivity;
|
||||
}
|
||||
|
||||
|
||||
public void setForegroundActivity(Activity activity) {
|
||||
if (mErrorDialog != null) {
|
||||
mErrorDialog.dismiss();
|
||||
@@ -124,39 +137,39 @@ public class LocalBluetoothManager {
|
||||
}
|
||||
mForegroundActivity = activity;
|
||||
}
|
||||
|
||||
|
||||
public SharedPreferences getSharedPreferences() {
|
||||
return mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public LocalBluetoothDeviceManager getLocalDeviceManager() {
|
||||
return mLocalDeviceManager;
|
||||
|
||||
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 (mManager.isDiscovering()) {
|
||||
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);
|
||||
} else {
|
||||
if (!force) {
|
||||
@@ -167,48 +180,49 @@ public class LocalBluetoothManager {
|
||||
}
|
||||
|
||||
// If we are playing music, don't scan unless forced.
|
||||
List<String> sinks = mBluetoothA2dp.listConnectedSinks();
|
||||
Set<BluetoothDevice> sinks = mBluetoothA2dp.getConnectedSinks();
|
||||
if (sinks != null) {
|
||||
for (String address : sinks) {
|
||||
if (mBluetoothA2dp.getSinkState(address) == BluetoothA2dp.STATE_PLAYING) {
|
||||
for (BluetoothDevice sink : sinks) {
|
||||
if (mBluetoothA2dp.getSinkState(sink) == BluetoothA2dp.STATE_PLAYING) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mManager.startDiscovery(true)) {
|
||||
|
||||
if (mAdapter.startDiscovery()) {
|
||||
mLastScan = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int getBluetoothState() {
|
||||
|
||||
if (mState == BluetoothError.ERROR) {
|
||||
|
||||
if (mState == BluetoothAdapter.ERROR) {
|
||||
syncBluetoothState();
|
||||
}
|
||||
|
||||
|
||||
return mState;
|
||||
}
|
||||
|
||||
|
||||
void setBluetoothStateInt(int state) {
|
||||
mState = state;
|
||||
if (state == BluetoothDevice.BLUETOOTH_STATE_ON ||
|
||||
state == BluetoothDevice.BLUETOOTH_STATE_OFF) {
|
||||
mLocalDeviceManager.onBluetoothStateChanged(state == BluetoothDevice.BLUETOOTH_STATE_ON);
|
||||
if (state == BluetoothAdapter.STATE_ON ||
|
||||
state == BluetoothAdapter.STATE_OFF) {
|
||||
mCachedDeviceManager.onBluetoothStateChanged(state ==
|
||||
BluetoothAdapter.STATE_ON);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void syncBluetoothState() {
|
||||
int bluetoothState;
|
||||
|
||||
if (mManager != null) {
|
||||
bluetoothState = mManager.isEnabled()
|
||||
? BluetoothDevice.BLUETOOTH_STATE_ON
|
||||
: BluetoothDevice.BLUETOOTH_STATE_OFF;
|
||||
if (mAdapter != null) {
|
||||
bluetoothState = mAdapter.isEnabled()
|
||||
? BluetoothAdapter.STATE_ON
|
||||
: BluetoothAdapter.STATE_OFF;
|
||||
} else {
|
||||
bluetoothState = BluetoothError.ERROR;
|
||||
bluetoothState = BluetoothAdapter.ERROR;
|
||||
}
|
||||
|
||||
setBluetoothStateInt(bluetoothState);
|
||||
@@ -216,33 +230,33 @@ public class LocalBluetoothManager {
|
||||
|
||||
public void setBluetoothEnabled(boolean enabled) {
|
||||
boolean wasSetStateSuccessful = enabled
|
||||
? mManager.enable()
|
||||
: mManager.disable();
|
||||
|
||||
? mAdapter.enable()
|
||||
: mAdapter.disable();
|
||||
|
||||
if (wasSetStateSuccessful) {
|
||||
setBluetoothStateInt(enabled
|
||||
? BluetoothDevice.BLUETOOTH_STATE_TURNING_ON
|
||||
: BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF);
|
||||
? 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)
|
||||
mLocalDeviceManager.onScanningStateChanged(started);
|
||||
mCachedDeviceManager.onScanningStateChanged(started);
|
||||
dispatchScanningStateChanged(started);
|
||||
}
|
||||
|
||||
|
||||
private void dispatchScanningStateChanged(boolean started) {
|
||||
synchronized (mCallbacks) {
|
||||
for (Callback callback : mCallbacks) {
|
||||
@@ -251,11 +265,18 @@ public class LocalBluetoothManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void showError(String address, int titleResId, int messageResId) {
|
||||
LocalBluetoothDevice device = mLocalDeviceManager.findDevice(address);
|
||||
if (device == null) return;
|
||||
public void showError(BluetoothDevice device, int titleResId, int messageResId) {
|
||||
CachedBluetoothDevice cachedDevice = mCachedDeviceManager.findDevice(device);
|
||||
String name = null;
|
||||
if (cachedDevice == null) {
|
||||
if (device != null) name = device.getName();
|
||||
|
||||
String 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) {
|
||||
@@ -267,15 +288,55 @@ public class LocalBluetoothManager {
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.show();
|
||||
} else {
|
||||
// Fallback on a toast
|
||||
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
|
||||
// Fallback on a toast
|
||||
Toast.makeText(mContext, message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
void onScanningStateChanged(boolean started);
|
||||
void onDeviceAdded(LocalBluetoothDevice device);
|
||||
void onDeviceDeleted(LocalBluetoothDevice device);
|
||||
void onDeviceAdded(CachedBluetoothDevice cachedDevice);
|
||||
void onDeviceDeleted(CachedBluetoothDevice cachedDevice);
|
||||
}
|
||||
|
||||
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 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.commit();
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user