auto import from //depot/cupcake/@135843
This commit is contained in:
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.preference.Preference;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
/**
|
||||
* BluetoothDevicePreference is the preference type used to display each remote
|
||||
* Bluetooth device in the Bluetooth Settings screen.
|
||||
*/
|
||||
public class BluetoothDevicePreference extends Preference implements LocalBluetoothDevice.Callback {
|
||||
private static final String TAG = "BluetoothDevicePreference";
|
||||
|
||||
private static int sDimAlpha = Integer.MIN_VALUE;
|
||||
|
||||
private LocalBluetoothDevice mLocalDevice;
|
||||
|
||||
/**
|
||||
* Cached local copy of whether the device is busy. This is only updated
|
||||
* from {@link #onDeviceAttributesChanged(LocalBluetoothDevice)}.
|
||||
*/
|
||||
private boolean mIsBusy;
|
||||
|
||||
public BluetoothDevicePreference(Context context, LocalBluetoothDevice localDevice) {
|
||||
super(context);
|
||||
|
||||
if (sDimAlpha == Integer.MIN_VALUE) {
|
||||
TypedValue outValue = new TypedValue();
|
||||
context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true);
|
||||
sDimAlpha = (int) (outValue.getFloat() * 255);
|
||||
}
|
||||
|
||||
mLocalDevice = localDevice;
|
||||
|
||||
setLayoutResource(R.layout.preference_bluetooth);
|
||||
|
||||
localDevice.registerCallback(this);
|
||||
|
||||
onDeviceAttributesChanged(localDevice);
|
||||
}
|
||||
|
||||
public LocalBluetoothDevice getDevice() {
|
||||
return mLocalDevice;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPrepareForRemoval() {
|
||||
super.onPrepareForRemoval();
|
||||
mLocalDevice.unregisterCallback(this);
|
||||
}
|
||||
|
||||
public void onDeviceAttributesChanged(LocalBluetoothDevice device) {
|
||||
|
||||
/*
|
||||
* The preference framework takes care of making sure the value has
|
||||
* changed before proceeding.
|
||||
*/
|
||||
|
||||
setTitle(mLocalDevice.getName());
|
||||
|
||||
/*
|
||||
* TODO: Showed "Paired" even though it was "Connected". This may be
|
||||
* related to BluetoothHeadset not bound to the actual
|
||||
* BluetoothHeadsetService when we got here.
|
||||
*/
|
||||
setSummary(mLocalDevice.getSummary());
|
||||
|
||||
// Used to gray out the item
|
||||
mIsBusy = mLocalDevice.isBusy();
|
||||
|
||||
// Data has changed
|
||||
notifyChanged();
|
||||
|
||||
// This could affect ordering, so notify that also
|
||||
notifyHierarchyChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return super.isEnabled() && !mIsBusy;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindView(View view) {
|
||||
super.onBindView(view);
|
||||
|
||||
ImageView btClass = (ImageView) view.findViewById(R.id.btClass);
|
||||
btClass.setImageResource(mLocalDevice.getBtClassDrawable());
|
||||
btClass.setAlpha(isEnabled() ? 255 : sDimAlpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Preference another) {
|
||||
if (!(another instanceof BluetoothDevicePreference)) {
|
||||
// Put other preference types above us
|
||||
return 1;
|
||||
}
|
||||
|
||||
return mLocalDevice.compareTo(((BluetoothDevicePreference) another).mLocalDevice);
|
||||
}
|
||||
|
||||
}
|
@@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothError;
|
||||
import android.bluetooth.BluetoothIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemProperties;
|
||||
import android.preference.Preference;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* BluetoothDiscoverableEnabler is a helper to manage the "Discoverable"
|
||||
* checkbox. It sets/unsets discoverability and keeps track of how much time
|
||||
* until the the discoverability is automatically turned off.
|
||||
*/
|
||||
public class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChangeListener {
|
||||
private static final String TAG = "BluetoothDiscoverableEnabler";
|
||||
private static final boolean V = LocalBluetoothManager.V;
|
||||
|
||||
private static final String SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT =
|
||||
"debug.bt.discoverable_time";
|
||||
private static final int DISCOVERABLE_TIMEOUT = 120;
|
||||
|
||||
private static final String SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP =
|
||||
"discoverable_end_timestamp";
|
||||
|
||||
private final Context mContext;
|
||||
private final Handler mUiHandler;
|
||||
private final CheckBoxPreference mCheckBoxPreference;
|
||||
|
||||
private final LocalBluetoothManager mLocalManager;
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (BluetoothIntent.SCAN_MODE_CHANGED_ACTION.equals(intent.getAction())) {
|
||||
int mode = intent.getIntExtra(BluetoothIntent.SCAN_MODE, BluetoothError.ERROR);
|
||||
if (mode != BluetoothError.ERROR) {
|
||||
handleModeChanged(mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable mUpdateCountdownSummaryRunnable = new Runnable() {
|
||||
public void run() {
|
||||
updateCountdownSummary();
|
||||
}
|
||||
};
|
||||
|
||||
public BluetoothDiscoverableEnabler(Context context, CheckBoxPreference checkBoxPreference) {
|
||||
mContext = context;
|
||||
mUiHandler = new Handler();
|
||||
mCheckBoxPreference = checkBoxPreference;
|
||||
|
||||
checkBoxPreference.setPersistent(false);
|
||||
|
||||
mLocalManager = LocalBluetoothManager.getInstance(context);
|
||||
if (mLocalManager == null) {
|
||||
// Bluetooth not supported
|
||||
checkBoxPreference.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
if (mLocalManager == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
IntentFilter filter = new IntentFilter(BluetoothIntent.SCAN_MODE_CHANGED_ACTION);
|
||||
filter.addAction(BluetoothIntent.DISABLED_ACTION);
|
||||
mContext.registerReceiver(mReceiver, filter);
|
||||
mCheckBoxPreference.setOnPreferenceChangeListener(this);
|
||||
|
||||
handleModeChanged(mLocalManager.getBluetoothManager().getScanMode());
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
if (mLocalManager == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mUiHandler.removeCallbacks(mUpdateCountdownSummaryRunnable);
|
||||
mCheckBoxPreference.setOnPreferenceChangeListener(null);
|
||||
mContext.unregisterReceiver(mReceiver);
|
||||
}
|
||||
|
||||
public boolean onPreferenceChange(Preference preference, Object value) {
|
||||
if (V) {
|
||||
Log.v(TAG, "Preference changed to " + value);
|
||||
}
|
||||
|
||||
// Turn on/off BT discoverability
|
||||
setEnabled((Boolean) value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setEnabled(final boolean enable) {
|
||||
BluetoothDevice manager = mLocalManager.getBluetoothManager();
|
||||
|
||||
if (enable) {
|
||||
|
||||
int timeout = getDiscoverableTimeout();
|
||||
manager.setDiscoverableTimeout(timeout);
|
||||
|
||||
long endTimestamp = System.currentTimeMillis() + timeout * 1000;
|
||||
persistDiscoverableEndTimestamp(endTimestamp);
|
||||
|
||||
manager.setScanMode(BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
|
||||
} else {
|
||||
manager.setScanMode(BluetoothDevice.SCAN_MODE_CONNECTABLE);
|
||||
}
|
||||
}
|
||||
|
||||
private int getDiscoverableTimeout() {
|
||||
int timeout = SystemProperties.getInt(SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT, -1);
|
||||
if (timeout <= 0) {
|
||||
timeout = DISCOVERABLE_TIMEOUT;
|
||||
}
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
||||
private void persistDiscoverableEndTimestamp(long endTimestamp) {
|
||||
SharedPreferences.Editor editor = mLocalManager.getSharedPreferences().edit();
|
||||
editor.putLong(SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP, endTimestamp);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
private void handleModeChanged(int mode) {
|
||||
if (V) {
|
||||
Log.v(TAG, "Got mode changed: " + mode);
|
||||
}
|
||||
|
||||
if (mode == BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
|
||||
mCheckBoxPreference.setChecked(true);
|
||||
updateCountdownSummary();
|
||||
|
||||
} else {
|
||||
mCheckBoxPreference.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCountdownSummary() {
|
||||
int mode = mLocalManager.getBluetoothManager().getScanMode();
|
||||
if (mode != BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
long currentTimestamp = System.currentTimeMillis();
|
||||
long endTimestamp = mLocalManager.getSharedPreferences().getLong(
|
||||
SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP, 0);
|
||||
|
||||
if (currentTimestamp > endTimestamp) {
|
||||
// We're still in discoverable mode, but maybe there isn't a timeout.
|
||||
mCheckBoxPreference.setSummaryOn(null);
|
||||
return;
|
||||
}
|
||||
|
||||
String formattedTimeLeft = String.valueOf((endTimestamp - currentTimestamp) / 1000);
|
||||
|
||||
mCheckBoxPreference.setSummaryOn(
|
||||
mContext.getResources().getString(R.string.bluetooth_is_discoverable,
|
||||
formattedTimeLeft));
|
||||
|
||||
synchronized (this) {
|
||||
mUiHandler.removeCallbacks(mUpdateCountdownSummaryRunnable);
|
||||
mUiHandler.postDelayed(mUpdateCountdownSummaryRunnable, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.LocalBluetoothManager.ExtendedBluetoothState;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.preference.Preference;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Config;
|
||||
|
||||
/**
|
||||
* BluetoothEnabler is a helper to manage the Bluetooth on/off checkbox
|
||||
* preference. It is turns on/off Bluetooth and ensures the summary of the
|
||||
* preference reflects the current state.
|
||||
*/
|
||||
public class BluetoothEnabler implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
private static final boolean LOCAL_LOGD = Config.LOGD || false;
|
||||
private static final String TAG = "BluetoothEnabler";
|
||||
|
||||
private final Context mContext;
|
||||
private final CheckBoxPreference mCheckBoxPreference;
|
||||
private final CharSequence mOriginalSummary;
|
||||
|
||||
private final LocalBluetoothManager mLocalManager;
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
handleStateChanged(mLocalManager.getBluetoothState());
|
||||
}
|
||||
};
|
||||
|
||||
public BluetoothEnabler(Context context, CheckBoxPreference checkBoxPreference) {
|
||||
mContext = context;
|
||||
mCheckBoxPreference = checkBoxPreference;
|
||||
|
||||
mOriginalSummary = checkBoxPreference.getSummary();
|
||||
checkBoxPreference.setPersistent(false);
|
||||
|
||||
mLocalManager = LocalBluetoothManager.getInstance(context);
|
||||
if (mLocalManager == null) {
|
||||
// Bluetooth not supported
|
||||
checkBoxPreference.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
if (mLocalManager == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ExtendedBluetoothState state = mLocalManager.getBluetoothState();
|
||||
// This is the widget enabled state, not the preference toggled state
|
||||
mCheckBoxPreference.setEnabled(state == ExtendedBluetoothState.ENABLED ||
|
||||
state == ExtendedBluetoothState.DISABLED);
|
||||
// BT state is not a sticky broadcast, so set it manually
|
||||
handleStateChanged(state);
|
||||
|
||||
mContext.registerReceiver(mReceiver,
|
||||
new IntentFilter(LocalBluetoothManager.EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION));
|
||||
mCheckBoxPreference.setOnPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
if (mLocalManager == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mContext.unregisterReceiver(mReceiver);
|
||||
mCheckBoxPreference.setOnPreferenceChangeListener(null);
|
||||
}
|
||||
|
||||
public boolean onPreferenceChange(Preference preference, Object value) {
|
||||
// Turn on/off BT
|
||||
setEnabled((Boolean) value);
|
||||
|
||||
// Don't update UI to opposite state until we're sure
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setEnabled(final boolean enable) {
|
||||
// Disable preference
|
||||
mCheckBoxPreference.setEnabled(false);
|
||||
|
||||
mLocalManager.setBluetoothEnabled(enable);
|
||||
}
|
||||
|
||||
private void handleStateChanged(ExtendedBluetoothState state) {
|
||||
|
||||
if (state == ExtendedBluetoothState.DISABLED || state == ExtendedBluetoothState.ENABLED) {
|
||||
mCheckBoxPreference.setChecked(state == ExtendedBluetoothState.ENABLED);
|
||||
mCheckBoxPreference
|
||||
.setSummary(state == ExtendedBluetoothState.DISABLED ? mOriginalSummary : null);
|
||||
|
||||
mCheckBoxPreference.setEnabled(isEnabledByDependency());
|
||||
|
||||
} else if (state == ExtendedBluetoothState.ENABLING ||
|
||||
state == ExtendedBluetoothState.DISABLING) {
|
||||
mCheckBoxPreference.setSummary(state == ExtendedBluetoothState.ENABLING
|
||||
? R.string.wifi_starting
|
||||
: R.string.wifi_stopping);
|
||||
|
||||
} else if (state == ExtendedBluetoothState.UNKNOWN) {
|
||||
mCheckBoxPreference.setChecked(false);
|
||||
mCheckBoxPreference.setSummary(R.string.wifi_error);
|
||||
mCheckBoxPreference.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEnabledByDependency() {
|
||||
Preference dep = getDependencyPreference();
|
||||
if (dep == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !dep.shouldDisableDependents();
|
||||
}
|
||||
|
||||
private Preference getDependencyPreference() {
|
||||
String depKey = mCheckBoxPreference.getDependency();
|
||||
if (TextUtils.isEmpty(depKey)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return mCheckBoxPreference.getPreferenceManager().findPreference(depKey);
|
||||
}
|
||||
|
||||
}
|
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.bluetooth.LocalBluetoothManager.ExtendedBluetoothState;
|
||||
|
||||
import android.bluetooth.BluetoothA2dp;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothHeadset;
|
||||
import android.bluetooth.BluetoothError;
|
||||
import android.bluetooth.BluetoothIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* BluetoothEventRedirector receives broadcasts and callbacks from the Bluetooth
|
||||
* API and dispatches the event on the UI thread to the right class in the
|
||||
* Settings.
|
||||
*/
|
||||
public class BluetoothEventRedirector {
|
||||
private static final String TAG = "BluetoothEventRedirector";
|
||||
private static final boolean V = LocalBluetoothManager.V;
|
||||
|
||||
private LocalBluetoothManager mManager;
|
||||
|
||||
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (V) {
|
||||
Log.v(TAG, "Received " + intent.getAction());
|
||||
}
|
||||
|
||||
String action = intent.getAction();
|
||||
String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
|
||||
|
||||
if (action.equals(BluetoothIntent.ENABLED_ACTION)) {
|
||||
mManager.setBluetoothStateInt(ExtendedBluetoothState.ENABLED);
|
||||
|
||||
} else if (action.equals(BluetoothIntent.DISABLED_ACTION)) {
|
||||
mManager.setBluetoothStateInt(ExtendedBluetoothState.DISABLED);
|
||||
|
||||
} else if (action.equals(BluetoothIntent.DISCOVERY_STARTED_ACTION)) {
|
||||
mManager.onScanningStateChanged(true);
|
||||
|
||||
} else if (action.equals(BluetoothIntent.DISCOVERY_COMPLETED_ACTION)) {
|
||||
mManager.onScanningStateChanged(false);
|
||||
|
||||
} else if (action.equals(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION)) {
|
||||
short rssi = intent.getShortExtra(BluetoothIntent.RSSI, Short.MIN_VALUE);
|
||||
mManager.getLocalDeviceManager().onDeviceAppeared(address, rssi);
|
||||
|
||||
} else if (action.equals(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION)) {
|
||||
mManager.getLocalDeviceManager().onDeviceDisappeared(address);
|
||||
|
||||
} else if (action.equals(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION)) {
|
||||
mManager.getLocalDeviceManager().onDeviceNameUpdated(address);
|
||||
|
||||
} else if (action.equals(BluetoothIntent.BOND_STATE_CHANGED_ACTION)) {
|
||||
int bondState = intent.getIntExtra(BluetoothIntent.BOND_STATE,
|
||||
BluetoothError.ERROR);
|
||||
mManager.getLocalDeviceManager().onBondingStateChanged(address, bondState);
|
||||
if (bondState == BluetoothDevice.BOND_NOT_BONDED) {
|
||||
int reason = intent.getIntExtra(BluetoothIntent.REASON, BluetoothError.ERROR);
|
||||
if (reason == BluetoothDevice.UNBOND_REASON_AUTH_FAILED ||
|
||||
reason == BluetoothDevice.UNBOND_REASON_AUTH_REJECTED ||
|
||||
reason == BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN) {
|
||||
mManager.getLocalDeviceManager().onBondingError(address, reason);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) {
|
||||
mManager.getLocalDeviceManager().onProfileStateChanged(address);
|
||||
|
||||
int newState = intent.getIntExtra(BluetoothIntent.HEADSET_STATE, 0);
|
||||
int oldState = intent.getIntExtra(BluetoothIntent.HEADSET_PREVIOUS_STATE, 0);
|
||||
if (newState == BluetoothHeadset.STATE_DISCONNECTED &&
|
||||
oldState == BluetoothHeadset.STATE_CONNECTING) {
|
||||
Log.i(TAG, "Failed to connect BT headset");
|
||||
}
|
||||
|
||||
} else if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) {
|
||||
mManager.getLocalDeviceManager().onProfileStateChanged(address);
|
||||
|
||||
int newState = intent.getIntExtra(BluetoothA2dp.SINK_STATE, 0);
|
||||
int oldState = intent.getIntExtra(BluetoothA2dp.SINK_PREVIOUS_STATE, 0);
|
||||
if (newState == BluetoothA2dp.STATE_DISCONNECTED &&
|
||||
oldState == BluetoothA2dp.STATE_CONNECTING) {
|
||||
Log.i(TAG, "Failed to connect BT A2DP");
|
||||
}
|
||||
|
||||
} else if (action.equals(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION)) {
|
||||
mManager.getLocalDeviceManager().onBtClassChanged(address);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public BluetoothEventRedirector(LocalBluetoothManager localBluetoothManager) {
|
||||
mManager = localBluetoothManager;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
|
||||
// Bluetooth on/off broadcasts
|
||||
filter.addAction(BluetoothIntent.ENABLED_ACTION);
|
||||
filter.addAction(BluetoothIntent.DISABLED_ACTION);
|
||||
|
||||
// Discovery broadcasts
|
||||
filter.addAction(BluetoothIntent.DISCOVERY_STARTED_ACTION);
|
||||
filter.addAction(BluetoothIntent.DISCOVERY_COMPLETED_ACTION);
|
||||
filter.addAction(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION);
|
||||
filter.addAction(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION);
|
||||
filter.addAction(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION);
|
||||
|
||||
// Pairing broadcasts
|
||||
filter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
|
||||
|
||||
// Fine-grained state broadcasts
|
||||
filter.addAction(BluetoothA2dp.SINK_STATE_CHANGED_ACTION);
|
||||
filter.addAction(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION);
|
||||
filter.addAction(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION);
|
||||
|
||||
mManager.getContext().registerReceiver(mBroadcastReceiver, filter);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
mManager.getContext().unregisterReceiver(mBroadcastReceiver);
|
||||
}
|
||||
}
|
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
/**
|
||||
* BluetoothNamePreference is the preference type for editing the device's
|
||||
* Bluetooth name. It asks the user for a name, and persists it via the
|
||||
* Bluetooth API.
|
||||
*/
|
||||
public class BluetoothNamePreference extends EditTextPreference {
|
||||
private static final String TAG = "BluetoothNamePreference";
|
||||
|
||||
private LocalBluetoothManager mLocalManager;
|
||||
|
||||
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
setSummaryToName();
|
||||
}
|
||||
};
|
||||
|
||||
public BluetoothNamePreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
mLocalManager = LocalBluetoothManager.getInstance(context);
|
||||
|
||||
setSummaryToName();
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(BluetoothIntent.ENABLED_ACTION);
|
||||
filter.addAction(BluetoothIntent.NAME_CHANGED_ACTION);
|
||||
getContext().registerReceiver(mReceiver, filter);
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
getContext().unregisterReceiver(mReceiver);
|
||||
}
|
||||
|
||||
private void setSummaryToName() {
|
||||
BluetoothDevice manager = mLocalManager.getBluetoothManager();
|
||||
if (manager.isEnabled()) {
|
||||
setSummary(manager.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean persistString(String value) {
|
||||
BluetoothDevice manager = mLocalManager.getBluetoothManager();
|
||||
manager.setName(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@@ -1,201 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.InputFilter;
|
||||
import android.text.TextWatcher;
|
||||
import android.text.InputFilter.LengthFilter;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.app.AlertActivity;
|
||||
import com.android.internal.app.AlertController;
|
||||
import com.android.settings.R;
|
||||
|
||||
/**
|
||||
* BluetoothPinDialog asks the user to enter a PIN for pairing with a remote
|
||||
* Bluetooth device. It is an activity that appears as a dialog.
|
||||
*/
|
||||
public class BluetoothPinDialog extends AlertActivity implements DialogInterface.OnClickListener,
|
||||
TextWatcher {
|
||||
private static final String TAG = "BluetoothPinDialog";
|
||||
|
||||
private LocalBluetoothManager mLocalManager;
|
||||
private String mAddress;
|
||||
private EditText mPinView;
|
||||
private Button mOkButton;
|
||||
|
||||
private static final String INSTANCE_KEY_PAIRING_CANCELED = "received_pairing_canceled";
|
||||
private boolean mReceivedPairingCanceled;
|
||||
|
||||
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (!BluetoothIntent.PAIRING_CANCEL_ACTION.equals(intent.getAction())) {
|
||||
return;
|
||||
}
|
||||
|
||||
String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
|
||||
if (address == null || address.equals(mAddress)) {
|
||||
onReceivedPairingCanceled();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Intent intent = getIntent();
|
||||
if (!intent.getAction().equals(BluetoothIntent.PAIRING_REQUEST_ACTION))
|
||||
{
|
||||
Log.e(TAG,
|
||||
"Error: this activity may be started only with intent " +
|
||||
BluetoothIntent.PAIRING_REQUEST_ACTION);
|
||||
finish();
|
||||
}
|
||||
|
||||
mLocalManager = LocalBluetoothManager.getInstance(this);
|
||||
mAddress = intent.getStringExtra(BluetoothIntent.ADDRESS);
|
||||
|
||||
// Set up the "dialog"
|
||||
final AlertController.AlertParams p = mAlertParams;
|
||||
p.mIconId = android.R.drawable.ic_dialog_info;
|
||||
p.mTitle = getString(R.string.bluetooth_pin_entry);
|
||||
p.mView = createView();
|
||||
p.mPositiveButtonText = getString(android.R.string.ok);
|
||||
p.mPositiveButtonListener = this;
|
||||
p.mNegativeButtonText = getString(android.R.string.cancel);
|
||||
p.mNegativeButtonListener = this;
|
||||
setupAlert();
|
||||
|
||||
mOkButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
mOkButton.setEnabled(false);
|
||||
|
||||
/*
|
||||
* Leave this registered through pause/resume since we still want to
|
||||
* finish the activity in the background if pairing is canceled.
|
||||
*/
|
||||
registerReceiver(mReceiver, new IntentFilter(BluetoothIntent.PAIRING_CANCEL_ACTION));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
|
||||
mReceivedPairingCanceled = savedInstanceState.getBoolean(INSTANCE_KEY_PAIRING_CANCELED);
|
||||
if (mReceivedPairingCanceled) {
|
||||
onReceivedPairingCanceled();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
outState.putBoolean(INSTANCE_KEY_PAIRING_CANCELED, mReceivedPairingCanceled);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
unregisterReceiver(mReceiver);
|
||||
}
|
||||
|
||||
private View createView() {
|
||||
View view = getLayoutInflater().inflate(R.layout.bluetooth_pin_entry, null);
|
||||
|
||||
String name = mLocalManager.getLocalDeviceManager().getName(mAddress);
|
||||
TextView messageView = (TextView) view.findViewById(R.id.message);
|
||||
messageView.setText(getString(R.string.bluetooth_enter_pin_msg, name));
|
||||
|
||||
mPinView = (EditText) view.findViewById(R.id.text);
|
||||
mPinView.addTextChangedListener(this);
|
||||
// Maximum of 10 characters in a PIN
|
||||
mPinView.setFilters(new InputFilter[] { new LengthFilter(10) });
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (s.length() > 0) {
|
||||
mOkButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void onReceivedPairingCanceled() {
|
||||
mReceivedPairingCanceled = true;
|
||||
|
||||
TextView messageView = (TextView) findViewById(R.id.message);
|
||||
messageView.setText(getString(R.string.bluetooth_pairing_error_message,
|
||||
mLocalManager.getLocalDeviceManager().getName(mAddress)));
|
||||
|
||||
mPinView.setEnabled(false);
|
||||
mPinView.clearFocus();
|
||||
mPinView.removeTextChangedListener(this);
|
||||
|
||||
mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
|
||||
}
|
||||
|
||||
private void onPair(String pin) {
|
||||
byte[] pinBytes = BluetoothDevice.convertPinToBytes(pin);
|
||||
|
||||
if (pinBytes == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mLocalManager.getBluetoothManager().setPin(mAddress, pinBytes);
|
||||
}
|
||||
|
||||
private void onCancel() {
|
||||
mLocalManager.getBluetoothManager().cancelBondProcess(mAddress);
|
||||
}
|
||||
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
onPair(mPinView.getText().toString());
|
||||
break;
|
||||
|
||||
case DialogInterface.BUTTON_NEGATIVE:
|
||||
onCancel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not used */
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
/* Not used */
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
}
|
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.text.TextUtils;
|
||||
|
||||
/**
|
||||
* BluetoothPinRequest is a receiver for any Bluetooth pairing PIN request. It
|
||||
* checks if the Bluetooth Settings is currently visible and brings up the PIN
|
||||
* entry dialog. Otherwise it puts a Notification in the status bar, which can
|
||||
* be clicked to bring up the PIN entry dialog.
|
||||
*/
|
||||
public class BluetoothPinRequest extends BroadcastReceiver {
|
||||
|
||||
public static final int NOTIFICATION_ID = android.R.drawable.stat_sys_data_bluetooth;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (action.equals(BluetoothIntent.PAIRING_REQUEST_ACTION)) {
|
||||
|
||||
LocalBluetoothManager localManager = LocalBluetoothManager.getInstance(context);
|
||||
|
||||
String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
|
||||
Intent pinIntent = new Intent();
|
||||
pinIntent.setClass(context, BluetoothPinDialog.class);
|
||||
pinIntent.putExtra(BluetoothIntent.ADDRESS, address);
|
||||
pinIntent.setAction(BluetoothIntent.PAIRING_REQUEST_ACTION);
|
||||
pinIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
if (localManager.getForegroundActivity() != null) {
|
||||
// Since the BT-related activity is in the foreground, just open the dialog
|
||||
context.startActivity(pinIntent);
|
||||
|
||||
} else {
|
||||
|
||||
// Put up a notification that leads to the dialog
|
||||
Resources res = context.getResources();
|
||||
Notification notification = new Notification(
|
||||
android.R.drawable.stat_sys_data_bluetooth,
|
||||
res.getString(R.string.bluetooth_notif_ticker),
|
||||
System.currentTimeMillis());
|
||||
|
||||
PendingIntent pending = PendingIntent.getActivity(context, 0,
|
||||
pinIntent, PendingIntent.FLAG_ONE_SHOT);
|
||||
|
||||
String name = intent.getStringExtra(BluetoothIntent.NAME);
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
name = localManager.getLocalDeviceManager().getName(address);
|
||||
}
|
||||
|
||||
notification.setLatestEventInfo(context,
|
||||
res.getString(R.string.bluetooth_notif_title),
|
||||
res.getString(R.string.bluetooth_notif_message) + name,
|
||||
pending);
|
||||
notification.flags |= Notification.FLAG_AUTO_CANCEL;
|
||||
|
||||
NotificationManager manager = (NotificationManager)
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
manager.notify(NOTIFICATION_ID, notification);
|
||||
}
|
||||
|
||||
} else if (action.equals(BluetoothIntent.PAIRING_CANCEL_ACTION)) {
|
||||
|
||||
// Remove the notification
|
||||
NotificationManager manager = (NotificationManager) context
|
||||
.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
manager.cancel(NOTIFICATION_ID);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,258 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.ProgressCategory;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.LocalBluetoothManager.ExtendedBluetoothState;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
||||
|
||||
/**
|
||||
* BluetoothSettings is the Settings screen for Bluetooth configuration and
|
||||
* connection management.
|
||||
*/
|
||||
public class BluetoothSettings extends PreferenceActivity
|
||||
implements LocalBluetoothManager.Callback {
|
||||
|
||||
private static final String TAG = "BluetoothSettings";
|
||||
|
||||
private static final int MENU_SCAN = Menu.FIRST;
|
||||
|
||||
private static final String KEY_BT_CHECKBOX = "bt_checkbox";
|
||||
private static final String KEY_BT_DISCOVERABLE = "bt_discoverable";
|
||||
private static final String KEY_BT_DEVICE_LIST = "bt_device_list";
|
||||
private static final String KEY_BT_NAME = "bt_name";
|
||||
private static final String KEY_BT_SCAN = "bt_scan";
|
||||
|
||||
private LocalBluetoothManager mLocalManager;
|
||||
|
||||
private BluetoothEnabler mEnabler;
|
||||
private BluetoothDiscoverableEnabler mDiscoverableEnabler;
|
||||
|
||||
private BluetoothNamePreference mNamePreference;
|
||||
|
||||
private ProgressCategory mDeviceList;
|
||||
|
||||
private WeakHashMap<LocalBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap =
|
||||
new WeakHashMap<LocalBluetoothDevice, BluetoothDevicePreference>();
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
// TODO: put this in callback instead of receiving
|
||||
onBluetoothStateChanged(mLocalManager.getBluetoothState());
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mLocalManager = LocalBluetoothManager.getInstance(this);
|
||||
if (mLocalManager == null) finish();
|
||||
|
||||
addPreferencesFromResource(R.xml.bluetooth_settings);
|
||||
|
||||
mEnabler = new BluetoothEnabler(
|
||||
this,
|
||||
(CheckBoxPreference) findPreference(KEY_BT_CHECKBOX));
|
||||
|
||||
mDiscoverableEnabler = new BluetoothDiscoverableEnabler(
|
||||
this,
|
||||
(CheckBoxPreference) findPreference(KEY_BT_DISCOVERABLE));
|
||||
|
||||
mNamePreference = (BluetoothNamePreference) findPreference(KEY_BT_NAME);
|
||||
|
||||
mDeviceList = (ProgressCategory) findPreference(KEY_BT_DEVICE_LIST);
|
||||
|
||||
registerForContextMenu(getListView());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
// Repopulate (which isn't too bad since it's cached in the settings
|
||||
// bluetooth manager
|
||||
mDevicePreferenceMap.clear();
|
||||
mDeviceList.removeAll();
|
||||
addDevices();
|
||||
|
||||
mEnabler.resume();
|
||||
mDiscoverableEnabler.resume();
|
||||
mNamePreference.resume();
|
||||
mLocalManager.registerCallback(this);
|
||||
|
||||
mLocalManager.startScanning(false);
|
||||
|
||||
registerReceiver(mReceiver,
|
||||
new IntentFilter(LocalBluetoothManager.EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION));
|
||||
|
||||
mLocalManager.setForegroundActivity(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
mLocalManager.setForegroundActivity(null);
|
||||
|
||||
unregisterReceiver(mReceiver);
|
||||
|
||||
mLocalManager.unregisterCallback(this);
|
||||
mNamePreference.pause();
|
||||
mDiscoverableEnabler.pause();
|
||||
mEnabler.pause();
|
||||
}
|
||||
|
||||
private void addDevices() {
|
||||
List<LocalBluetoothDevice> devices = mLocalManager.getLocalDeviceManager().getDevicesCopy();
|
||||
for (LocalBluetoothDevice device : devices) {
|
||||
onDeviceAdded(device);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
menu.add(0, MENU_SCAN, 0, R.string.bluetooth_scan_for_devices)
|
||||
.setIcon(com.android.internal.R.drawable.ic_menu_refresh)
|
||||
.setAlphabeticShortcut('r');
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(MENU_SCAN).setEnabled(mLocalManager.getBluetoothManager().isEnabled());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
|
||||
case MENU_SCAN:
|
||||
mLocalManager.startScanning(true);
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
|
||||
Preference preference) {
|
||||
|
||||
if (KEY_BT_SCAN.equals(preference.getKey())) {
|
||||
mLocalManager.startScanning(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (preference instanceof BluetoothDevicePreference) {
|
||||
BluetoothDevicePreference btPreference = (BluetoothDevicePreference) preference;
|
||||
btPreference.getDevice().onClicked();
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onPreferenceTreeClick(preferenceScreen, preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v,
|
||||
ContextMenuInfo menuInfo) {
|
||||
LocalBluetoothDevice device = getDeviceFromMenuInfo(menuInfo);
|
||||
if (device == null) return;
|
||||
|
||||
device.onCreateContextMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected(MenuItem item) {
|
||||
LocalBluetoothDevice device = getDeviceFromMenuInfo(item.getMenuInfo());
|
||||
if (device == null) return false;
|
||||
|
||||
device.onContextItemSelected(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
private LocalBluetoothDevice getDeviceFromMenuInfo(ContextMenuInfo menuInfo) {
|
||||
if ((menuInfo == null) || !(menuInfo instanceof AdapterContextMenuInfo)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo;
|
||||
Preference pref = (Preference) getPreferenceScreen().getRootAdapter().getItem(
|
||||
adapterMenuInfo.position);
|
||||
if (pref == null || !(pref instanceof BluetoothDevicePreference)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ((BluetoothDevicePreference) pref).getDevice();
|
||||
}
|
||||
|
||||
public void onDeviceAdded(LocalBluetoothDevice device) {
|
||||
|
||||
if (mDevicePreferenceMap.get(device) != null) {
|
||||
throw new IllegalStateException("Got onDeviceAdded, but device already exists");
|
||||
}
|
||||
|
||||
createDevicePreference(device);
|
||||
}
|
||||
|
||||
private void createDevicePreference(LocalBluetoothDevice device) {
|
||||
BluetoothDevicePreference preference = new BluetoothDevicePreference(this, device);
|
||||
mDeviceList.addPreference(preference);
|
||||
mDevicePreferenceMap.put(device, preference);
|
||||
}
|
||||
|
||||
public void onDeviceDeleted(LocalBluetoothDevice device) {
|
||||
BluetoothDevicePreference preference = mDevicePreferenceMap.remove(device);
|
||||
if (preference != null) {
|
||||
mDeviceList.removePreference(preference);
|
||||
}
|
||||
}
|
||||
|
||||
public void onScanningStateChanged(boolean started) {
|
||||
mDeviceList.setProgress(started);
|
||||
}
|
||||
|
||||
private void onBluetoothStateChanged(ExtendedBluetoothState bluetoothState) {
|
||||
// When bluetooth is enabled (and we are in the activity, which we are),
|
||||
// we should start a scan
|
||||
if (bluetoothState == ExtendedBluetoothState.ENABLED) {
|
||||
mLocalManager.startScanning(false);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,292 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceGroup;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* ConnectSpecificProfilesActivity presents the user with all of the profiles
|
||||
* for a particular device, and allows him to choose which should be connected
|
||||
* (or disconnected).
|
||||
*/
|
||||
public class ConnectSpecificProfilesActivity extends PreferenceActivity
|
||||
implements LocalBluetoothDevice.Callback, Preference.OnPreferenceChangeListener {
|
||||
private static final String TAG = "ConnectSpecificProfilesActivity";
|
||||
|
||||
private static final String KEY_ONLINE_MODE = "online_mode";
|
||||
private static final String KEY_TITLE = "title";
|
||||
private static final String KEY_PROFILE_CONTAINER = "profile_container";
|
||||
|
||||
public static final String EXTRA_ADDRESS = "address";
|
||||
|
||||
private LocalBluetoothManager mManager;
|
||||
private LocalBluetoothDevice mDevice;
|
||||
|
||||
private PreferenceGroup mProfileContainer;
|
||||
private CheckBoxPreference mOnlineModePreference;
|
||||
|
||||
/**
|
||||
* The current mode of this activity and its checkboxes (either online mode
|
||||
* or offline mode). In online mode, user interactions with the profile
|
||||
* checkboxes will also toggle the profile's connectivity. In offline mode,
|
||||
* they will not, and only the preferred state will be saved for the
|
||||
* profile.
|
||||
*/
|
||||
private boolean mOnlineMode;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
String address;
|
||||
if (savedInstanceState != null) {
|
||||
address = savedInstanceState.getString(EXTRA_ADDRESS);
|
||||
} else {
|
||||
Intent intent = getIntent();
|
||||
address = intent.getStringExtra(EXTRA_ADDRESS);
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(address)) {
|
||||
Log.w(TAG, "Activity started without address");
|
||||
finish();
|
||||
}
|
||||
|
||||
mManager = LocalBluetoothManager.getInstance(this);
|
||||
mDevice = mManager.getLocalDeviceManager().findDevice(address);
|
||||
if (mDevice == null) {
|
||||
Log.w(TAG, "Device not found, cannot connect to it");
|
||||
finish();
|
||||
}
|
||||
|
||||
addPreferencesFromResource(R.xml.bluetooth_device_advanced);
|
||||
mProfileContainer = (PreferenceGroup) findPreference(KEY_PROFILE_CONTAINER);
|
||||
|
||||
// Set the title of the screen
|
||||
findPreference(KEY_TITLE).setTitle(
|
||||
getString(R.string.bluetooth_device_advanced_title, mDevice.getName()));
|
||||
|
||||
// Listen for check/uncheck of the online mode checkbox
|
||||
mOnlineModePreference = (CheckBoxPreference) findPreference(KEY_ONLINE_MODE);
|
||||
mOnlineModePreference.setOnPreferenceChangeListener(this);
|
||||
|
||||
// Add a preference for each profile
|
||||
addPreferencesForProfiles();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
outState.putString(EXTRA_ADDRESS, mDevice.getAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
mManager.setForegroundActivity(this);
|
||||
mDevice.registerCallback(this);
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
mDevice.unregisterCallback(this);
|
||||
mManager.setForegroundActivity(null);
|
||||
}
|
||||
|
||||
private void addPreferencesForProfiles() {
|
||||
for (Profile profile : mDevice.getProfiles()) {
|
||||
Preference pref = createProfilePreference(profile);
|
||||
mProfileContainer.addPreference(pref);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a checkbox preference for the particular profile. The key will be
|
||||
* the profile's name.
|
||||
*
|
||||
* @param profile The profile for which the preference controls.
|
||||
* @return A preference that allows the user to choose whether this profile
|
||||
* will be connected to.
|
||||
*/
|
||||
private CheckBoxPreference createProfilePreference(Profile profile) {
|
||||
CheckBoxPreference pref = new CheckBoxPreference(this);
|
||||
pref.setKey(profile.toString());
|
||||
pref.setTitle(profile.localizedString);
|
||||
pref.setPersistent(false);
|
||||
pref.setOnPreferenceChangeListener(this);
|
||||
|
||||
refreshProfilePreference(pref, profile);
|
||||
|
||||
return pref;
|
||||
}
|
||||
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
String key = preference.getKey();
|
||||
if (TextUtils.isEmpty(key) || newValue == null) return true;
|
||||
|
||||
if (key.equals(KEY_ONLINE_MODE)) {
|
||||
onOnlineModeCheckedStateChanged((Boolean) newValue);
|
||||
|
||||
} else {
|
||||
Profile profile = getProfileOf(preference);
|
||||
if (profile == null) return false;
|
||||
onProfileCheckedStateChanged(profile, (Boolean) newValue);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void onOnlineModeCheckedStateChanged(boolean checked) {
|
||||
setOnlineMode(checked, true);
|
||||
}
|
||||
|
||||
private void onProfileCheckedStateChanged(Profile profile, boolean checked) {
|
||||
if (mOnlineMode) {
|
||||
if (checked) {
|
||||
mDevice.connect(profile);
|
||||
} else {
|
||||
mDevice.disconnect(profile);
|
||||
}
|
||||
}
|
||||
|
||||
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
|
||||
.getProfileManager(mManager, profile);
|
||||
profileManager.setPreferred(mDevice.getAddress(), checked);
|
||||
}
|
||||
|
||||
public void onDeviceAttributesChanged(LocalBluetoothDevice device) {
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
// We are in 'online mode' if we are connected, connecting, or disconnecting
|
||||
setOnlineMode(mDevice.isConnected() || mDevice.isBusy(), false);
|
||||
refreshProfiles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches between online/offline mode.
|
||||
*
|
||||
* @param onlineMode Whether to be in online mode, or offline mode.
|
||||
* @param takeAction Whether to take action (i.e., connect or disconnect)
|
||||
* based on the new online mode.
|
||||
*/
|
||||
private void setOnlineMode(boolean onlineMode, boolean takeAction) {
|
||||
mOnlineMode = onlineMode;
|
||||
|
||||
if (takeAction) {
|
||||
if (onlineMode) {
|
||||
mDevice.connect();
|
||||
} else {
|
||||
mDevice.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
refreshOnlineModePreference();
|
||||
}
|
||||
|
||||
private void refreshOnlineModePreference() {
|
||||
mOnlineModePreference.setChecked(mOnlineMode);
|
||||
|
||||
/**
|
||||
* If the device is online, show status. Otherwise, show a summary that
|
||||
* describes what the checkbox does.
|
||||
*/
|
||||
mOnlineModePreference.setSummary(mOnlineMode ? mDevice.getSummary()
|
||||
: R.string.bluetooth_device_advanced_online_mode_summary);
|
||||
}
|
||||
|
||||
private void refreshProfiles() {
|
||||
for (Profile profile : mDevice.getProfiles()) {
|
||||
CheckBoxPreference profilePref =
|
||||
(CheckBoxPreference) findPreference(profile.toString());
|
||||
if (profilePref == null) {
|
||||
profilePref = createProfilePreference(profile);
|
||||
mProfileContainer.addPreference(profilePref);
|
||||
} else {
|
||||
refreshProfilePreference(profilePref, profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshProfilePreference(CheckBoxPreference profilePref, Profile profile) {
|
||||
String address = mDevice.getAddress();
|
||||
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
|
||||
.getProfileManager(mManager, profile);
|
||||
|
||||
int connectionStatus = profileManager.getConnectionStatus(address);
|
||||
|
||||
profilePref.setSummary(getProfileSummary(profileManager, profile, address,
|
||||
connectionStatus, mOnlineMode));
|
||||
|
||||
profilePref.setChecked(profileManager.isPreferred(address));
|
||||
}
|
||||
|
||||
private Profile getProfileOf(Preference pref) {
|
||||
if (!(pref instanceof CheckBoxPreference)) return null;
|
||||
String key = pref.getKey();
|
||||
if (TextUtils.isEmpty(key)) return null;
|
||||
|
||||
try {
|
||||
return Profile.valueOf(pref.getKey());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static int getProfileSummary(LocalBluetoothProfileManager profileManager,
|
||||
Profile profile, String address, int connectionStatus, boolean onlineMode) {
|
||||
if (!onlineMode || connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED) {
|
||||
return getProfileSummaryForSettingPreference(profile);
|
||||
} else {
|
||||
return profileManager.getSummary(address);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the summary that describes when checked, it will become a preferred profile.
|
||||
*
|
||||
* @param profile The profile to get the summary for.
|
||||
* @return The summary.
|
||||
*/
|
||||
private static final int getProfileSummaryForSettingPreference(Profile profile) {
|
||||
switch (profile) {
|
||||
case A2DP:
|
||||
return R.string.bluetooth_a2dp_profile_summary_use_for;
|
||||
case HEADSET:
|
||||
return R.string.bluetooth_headset_profile_summary_use_for;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,576 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothClass;
|
||||
import android.bluetooth.IBluetoothDeviceCallback;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* LocalBluetoothDevice represents a remote Bluetooth device. It contains
|
||||
* attributes of the device (such as the address, name, RSSI, etc.) and
|
||||
* functionality that can be performed on the device (connect, pair, disconnect,
|
||||
* etc.).
|
||||
*/
|
||||
public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
|
||||
private static final String TAG = "LocalBluetoothDevice";
|
||||
|
||||
private static final int CONTEXT_ITEM_CONNECT = Menu.FIRST + 1;
|
||||
private static final int CONTEXT_ITEM_DISCONNECT = Menu.FIRST + 2;
|
||||
private static final int CONTEXT_ITEM_UNPAIR = Menu.FIRST + 3;
|
||||
private static final int CONTEXT_ITEM_CONNECT_ADVANCED = Menu.FIRST + 4;
|
||||
|
||||
private final String mAddress;
|
||||
private String mName;
|
||||
private short mRssi;
|
||||
private int mBtClass = BluetoothClass.ERROR;
|
||||
|
||||
private List<Profile> mProfiles = new ArrayList<Profile>();
|
||||
|
||||
private boolean mVisible;
|
||||
|
||||
private final LocalBluetoothManager mLocalManager;
|
||||
|
||||
private List<Callback> mCallbacks = new ArrayList<Callback>();
|
||||
|
||||
/**
|
||||
* When we connect to multiple profiles, we only want to display a single
|
||||
* error even if they all fail. This tracks that state.
|
||||
*/
|
||||
private boolean mIsConnectingErrorPossible;
|
||||
|
||||
LocalBluetoothDevice(Context context, String address) {
|
||||
mLocalManager = LocalBluetoothManager.getInstance(context);
|
||||
if (mLocalManager == null) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot use LocalBluetoothDevice without Bluetooth hardware");
|
||||
}
|
||||
|
||||
mAddress = address;
|
||||
|
||||
fillData();
|
||||
}
|
||||
|
||||
public void onClicked() {
|
||||
int bondState = getBondState();
|
||||
|
||||
if (isConnected()) {
|
||||
askDisconnect();
|
||||
} else if (bondState == BluetoothDevice.BOND_BONDED) {
|
||||
connect();
|
||||
} else if (bondState == BluetoothDevice.BOND_NOT_BONDED) {
|
||||
pair();
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
for (Profile profile : mProfiles) {
|
||||
disconnect(profile);
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect(Profile profile) {
|
||||
LocalBluetoothProfileManager profileManager =
|
||||
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
|
||||
int status = profileManager.getConnectionStatus(mAddress);
|
||||
if (SettingsBtStatus.isConnectionStatusConnected(status)) {
|
||||
profileManager.disconnect(mAddress);
|
||||
}
|
||||
}
|
||||
|
||||
public void askDisconnect() {
|
||||
Context context = mLocalManager.getForegroundActivity();
|
||||
if (context == null) {
|
||||
// Cannot ask, since we need an activity context
|
||||
disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
Resources res = context.getResources();
|
||||
|
||||
String name = getName();
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
name = res.getString(R.string.bluetooth_device);
|
||||
}
|
||||
String message = res.getString(R.string.bluetooth_disconnect_blank, name);
|
||||
|
||||
DialogInterface.OnClickListener disconnectListener = new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
disconnect();
|
||||
}
|
||||
};
|
||||
|
||||
AlertDialog ad = new AlertDialog.Builder(context)
|
||||
.setTitle(getName())
|
||||
.setMessage(message)
|
||||
.setPositiveButton(android.R.string.ok, disconnectListener)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
if (!ensurePaired()) return;
|
||||
|
||||
// Reset the only-show-one-error-dialog tracking variable
|
||||
mIsConnectingErrorPossible = true;
|
||||
|
||||
Context context = mLocalManager.getContext();
|
||||
boolean hasAtLeastOnePreferredProfile = false;
|
||||
for (Profile profile : mProfiles) {
|
||||
LocalBluetoothProfileManager profileManager =
|
||||
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
|
||||
if (profileManager.isPreferred(mAddress)) {
|
||||
hasAtLeastOnePreferredProfile = true;
|
||||
connectInt(profile);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasAtLeastOnePreferredProfile) {
|
||||
connectAndPreferAllProfiles();
|
||||
}
|
||||
}
|
||||
|
||||
private void connectAndPreferAllProfiles() {
|
||||
if (!ensurePaired()) return;
|
||||
|
||||
// Reset the only-show-one-error-dialog tracking variable
|
||||
mIsConnectingErrorPossible = true;
|
||||
|
||||
Context context = mLocalManager.getContext();
|
||||
for (Profile profile : mProfiles) {
|
||||
LocalBluetoothProfileManager profileManager =
|
||||
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
|
||||
profileManager.setPreferred(mAddress, true);
|
||||
connectInt(profile);
|
||||
}
|
||||
}
|
||||
|
||||
public void connect(Profile profile) {
|
||||
// Reset the only-show-one-error-dialog tracking variable
|
||||
mIsConnectingErrorPossible = true;
|
||||
connectInt(profile);
|
||||
}
|
||||
|
||||
public void connectInt(Profile profile) {
|
||||
if (!ensurePaired()) return;
|
||||
|
||||
LocalBluetoothProfileManager profileManager =
|
||||
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
|
||||
int status = profileManager.getConnectionStatus(mAddress);
|
||||
if (!SettingsBtStatus.isConnectionStatusConnected(status)) {
|
||||
if (profileManager.connect(mAddress) != BluetoothDevice.RESULT_SUCCESS) {
|
||||
Log.i(TAG, "Failed to connect " + profile.toString() + " to " + mName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void showConnectingError() {
|
||||
if (!mIsConnectingErrorPossible) return;
|
||||
mIsConnectingErrorPossible = false;
|
||||
|
||||
mLocalManager.showError(mAddress, R.string.bluetooth_error_title,
|
||||
R.string.bluetooth_connecting_error_message);
|
||||
}
|
||||
|
||||
private boolean ensurePaired() {
|
||||
if (getBondState() == BluetoothDevice.BOND_NOT_BONDED) {
|
||||
pair();
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void pair() {
|
||||
BluetoothDevice manager = mLocalManager.getBluetoothManager();
|
||||
|
||||
// Pairing is unreliable while scanning, so cancel discovery
|
||||
if (manager.isDiscovering()) {
|
||||
manager.cancelDiscovery();
|
||||
}
|
||||
|
||||
if (!mLocalManager.getBluetoothManager().createBond(mAddress)) {
|
||||
mLocalManager.showError(mAddress, R.string.bluetooth_error_title,
|
||||
R.string.bluetooth_pairing_error_message);
|
||||
}
|
||||
}
|
||||
|
||||
public void unpair() {
|
||||
BluetoothDevice manager = mLocalManager.getBluetoothManager();
|
||||
|
||||
switch (getBondState()) {
|
||||
case BluetoothDevice.BOND_BONDED:
|
||||
manager.removeBond(mAddress);
|
||||
break;
|
||||
|
||||
case BluetoothDevice.BOND_BONDING:
|
||||
manager.cancelBondProcess(mAddress);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void fillData() {
|
||||
BluetoothDevice manager = mLocalManager.getBluetoothManager();
|
||||
|
||||
fetchName();
|
||||
fetchBtClass();
|
||||
|
||||
mVisible = false;
|
||||
|
||||
dispatchAttributesChanged();
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return mAddress;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public void refreshName() {
|
||||
fetchName();
|
||||
dispatchAttributesChanged();
|
||||
}
|
||||
|
||||
private void fetchName() {
|
||||
mName = mLocalManager.getBluetoothManager().getRemoteName(mAddress);
|
||||
|
||||
if (TextUtils.isEmpty(mName)) {
|
||||
mName = mAddress;
|
||||
}
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
dispatchAttributesChanged();
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return mVisible;
|
||||
}
|
||||
|
||||
void setVisible(boolean visible) {
|
||||
if (mVisible != visible) {
|
||||
mVisible = visible;
|
||||
dispatchAttributesChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public int getBondState() {
|
||||
return mLocalManager.getBluetoothManager().getBondState(mAddress);
|
||||
}
|
||||
|
||||
void setRssi(short rssi) {
|
||||
if (mRssi != rssi) {
|
||||
mRssi = rssi;
|
||||
dispatchAttributesChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether we are connected to this device (any profile counts).
|
||||
*
|
||||
* @return Whether it is connected.
|
||||
*/
|
||||
public boolean isConnected() {
|
||||
for (Profile profile : mProfiles) {
|
||||
int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
|
||||
.getConnectionStatus(mAddress);
|
||||
if (SettingsBtStatus.isConnectionStatusConnected(status)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isBusy() {
|
||||
for (Profile profile : mProfiles) {
|
||||
int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
|
||||
.getConnectionStatus(mAddress);
|
||||
if (SettingsBtStatus.isConnectionStatusBusy(status)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (getBondState() == BluetoothDevice.BOND_BONDING) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getBtClassDrawable() {
|
||||
|
||||
// First try looking at profiles
|
||||
if (mProfiles.contains(Profile.A2DP)) {
|
||||
return R.drawable.ic_bt_headphones_a2dp;
|
||||
} else if (mProfiles.contains(Profile.HEADSET)) {
|
||||
return R.drawable.ic_bt_headset_hfp;
|
||||
}
|
||||
|
||||
// Fallback on class
|
||||
switch (BluetoothClass.Device.Major.getDeviceMajor(mBtClass)) {
|
||||
case BluetoothClass.Device.Major.COMPUTER:
|
||||
return R.drawable.ic_bt_laptop;
|
||||
|
||||
case BluetoothClass.Device.Major.PHONE:
|
||||
return R.drawable.ic_bt_cellphone;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a new value for the cached BT class.
|
||||
*/
|
||||
private void fetchBtClass() {
|
||||
mBtClass = mLocalManager.getBluetoothManager().getRemoteClass(mAddress);
|
||||
mProfiles.clear();
|
||||
LocalBluetoothProfileManager.fill(mBtClass, mProfiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the UI for the BT class, including fetching the latest value
|
||||
* for the class.
|
||||
*/
|
||||
public void refreshBtClass() {
|
||||
fetchBtClass();
|
||||
dispatchAttributesChanged();
|
||||
}
|
||||
|
||||
public int getSummary() {
|
||||
// TODO: clean up
|
||||
int oneOffSummary = getOneOffSummary();
|
||||
if (oneOffSummary != 0) {
|
||||
return oneOffSummary;
|
||||
}
|
||||
|
||||
for (Profile profile : mProfiles) {
|
||||
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
|
||||
.getProfileManager(mLocalManager, profile);
|
||||
int connectionStatus = profileManager.getConnectionStatus(mAddress);
|
||||
|
||||
if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus) ||
|
||||
connectionStatus == SettingsBtStatus.CONNECTION_STATUS_CONNECTING ||
|
||||
connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING) {
|
||||
return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
|
||||
}
|
||||
}
|
||||
|
||||
return SettingsBtStatus.getPairingStatusSummary(getBondState());
|
||||
}
|
||||
|
||||
/**
|
||||
* We have special summaries when particular profiles are connected. This
|
||||
* checks for those states and returns an applicable summary.
|
||||
*
|
||||
* @return A one-off summary that is applicable for the current state, or 0.
|
||||
*/
|
||||
private int getOneOffSummary() {
|
||||
boolean isA2dpConnected = false, isHeadsetConnected = false, isConnecting = false;
|
||||
|
||||
if (mProfiles.contains(Profile.A2DP)) {
|
||||
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
|
||||
.getProfileManager(mLocalManager, Profile.A2DP);
|
||||
isConnecting = profileManager.getConnectionStatus(mAddress) ==
|
||||
SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
|
||||
isA2dpConnected = profileManager.isConnected(mAddress);
|
||||
}
|
||||
|
||||
if (mProfiles.contains(Profile.HEADSET)) {
|
||||
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
|
||||
.getProfileManager(mLocalManager, Profile.HEADSET);
|
||||
isConnecting |= profileManager.getConnectionStatus(mAddress) ==
|
||||
SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
|
||||
isHeadsetConnected = profileManager.isConnected(mAddress);
|
||||
}
|
||||
|
||||
if (isConnecting) {
|
||||
// If any of these important profiles is connecting, prefer that
|
||||
return SettingsBtStatus.getConnectionStatusSummary(
|
||||
SettingsBtStatus.CONNECTION_STATUS_CONNECTING);
|
||||
} else if (isA2dpConnected && isHeadsetConnected) {
|
||||
return R.string.bluetooth_summary_connected_to_a2dp_headset;
|
||||
} else if (isA2dpConnected) {
|
||||
return R.string.bluetooth_summary_connected_to_a2dp;
|
||||
} else if (isHeadsetConnected) {
|
||||
return R.string.bluetooth_summary_connected_to_headset;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Profile> getProfiles() {
|
||||
return new ArrayList<Profile>(mProfiles);
|
||||
}
|
||||
|
||||
public void onCreateContextMenu(ContextMenu menu) {
|
||||
// No context menu if it is busy (none of these items are applicable if busy)
|
||||
if (isBusy()) return;
|
||||
|
||||
int bondState = getBondState();
|
||||
boolean isConnected = isConnected();
|
||||
boolean hasProfiles = mProfiles.size() > 0;
|
||||
|
||||
menu.setHeaderTitle(getName());
|
||||
|
||||
if (isConnected) {
|
||||
menu.add(0, CONTEXT_ITEM_DISCONNECT, 0, R.string.bluetooth_device_context_disconnect);
|
||||
} else if (hasProfiles) {
|
||||
// For connection action, show either "Connect" or "Pair & connect"
|
||||
int connectString = (bondState == BluetoothDevice.BOND_NOT_BONDED)
|
||||
? R.string.bluetooth_device_context_pair_connect
|
||||
: R.string.bluetooth_device_context_connect;
|
||||
menu.add(0, CONTEXT_ITEM_CONNECT, 0, connectString);
|
||||
}
|
||||
|
||||
if (bondState == BluetoothDevice.BOND_BONDED) {
|
||||
// For unpair action, show either "Unpair" or "Disconnect & unpair"
|
||||
int unpairString = isConnected
|
||||
? R.string.bluetooth_device_context_disconnect_unpair
|
||||
: R.string.bluetooth_device_context_unpair;
|
||||
menu.add(0, CONTEXT_ITEM_UNPAIR, 0, unpairString);
|
||||
|
||||
// Show the connection options item
|
||||
menu.add(0, CONTEXT_ITEM_CONNECT_ADVANCED, 0,
|
||||
R.string.bluetooth_device_context_connect_advanced);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a context menu item is clicked.
|
||||
*
|
||||
* @param item The item that was clicked.
|
||||
*/
|
||||
public void onContextItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case CONTEXT_ITEM_DISCONNECT:
|
||||
disconnect();
|
||||
break;
|
||||
|
||||
case CONTEXT_ITEM_CONNECT:
|
||||
connect();
|
||||
break;
|
||||
|
||||
case CONTEXT_ITEM_UNPAIR:
|
||||
mLocalManager.getBluetoothManager().disconnectRemoteDeviceAcl(mAddress);
|
||||
unpair();
|
||||
break;
|
||||
|
||||
case CONTEXT_ITEM_CONNECT_ADVANCED:
|
||||
Intent intent = new Intent();
|
||||
// Need an activity context to open this in our task
|
||||
Context context = mLocalManager.getForegroundActivity();
|
||||
if (context == null) {
|
||||
// Fallback on application context, and open in a new task
|
||||
context = mLocalManager.getContext();
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
intent.setClass(context, ConnectSpecificProfilesActivity.class);
|
||||
intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_ADDRESS, mAddress);
|
||||
context.startActivity(intent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void registerCallback(Callback callback) {
|
||||
synchronized (mCallbacks) {
|
||||
mCallbacks.add(callback);
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterCallback(Callback callback) {
|
||||
synchronized (mCallbacks) {
|
||||
mCallbacks.remove(callback);
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchAttributesChanged() {
|
||||
synchronized (mCallbacks) {
|
||||
for (Callback callback : mCallbacks) {
|
||||
callback.onDeviceAttributesChanged(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ((o == null) || !(o instanceof LocalBluetoothDevice)) {
|
||||
throw new ClassCastException();
|
||||
}
|
||||
|
||||
return mAddress.equals(((LocalBluetoothDevice) o).mAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mAddress.hashCode();
|
||||
}
|
||||
|
||||
public int compareTo(LocalBluetoothDevice another) {
|
||||
int comparison;
|
||||
|
||||
// Connected above not connected
|
||||
comparison = (another.isConnected() ? 1 : 0) - (isConnected() ? 1 : 0);
|
||||
if (comparison != 0) return comparison;
|
||||
|
||||
// Paired above not paired
|
||||
comparison = (another.getBondState() == BluetoothDevice.BOND_BONDED ? 1 : 0) -
|
||||
(getBondState() == BluetoothDevice.BOND_BONDED ? 1 : 0);
|
||||
if (comparison != 0) return comparison;
|
||||
|
||||
// Visible above not visible
|
||||
comparison = (another.mVisible ? 1 : 0) - (mVisible ? 1 : 0);
|
||||
if (comparison != 0) return comparison;
|
||||
|
||||
// Stronger signal above weaker signal
|
||||
comparison = another.mRssi - mRssi;
|
||||
if (comparison != 0) return comparison;
|
||||
|
||||
// Fallback on name
|
||||
return getName().compareTo(another.getName());
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
void onDeviceAttributesChanged(LocalBluetoothDevice device);
|
||||
}
|
||||
}
|
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.LocalBluetoothManager.Callback;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* LocalBluetoothDeviceManager manages the set of remote Bluetooth devices.
|
||||
*/
|
||||
public class LocalBluetoothDeviceManager {
|
||||
private static final String TAG = "LocalBluetoothDeviceManager";
|
||||
|
||||
final LocalBluetoothManager mLocalManager;
|
||||
final List<Callback> mCallbacks;
|
||||
|
||||
final List<LocalBluetoothDevice> mDevices = new ArrayList<LocalBluetoothDevice>();
|
||||
|
||||
public LocalBluetoothDeviceManager(LocalBluetoothManager localManager) {
|
||||
mLocalManager = localManager;
|
||||
mCallbacks = localManager.getCallbacks();
|
||||
readPairedDevices();
|
||||
}
|
||||
|
||||
private synchronized boolean readPairedDevices() {
|
||||
BluetoothDevice manager = mLocalManager.getBluetoothManager();
|
||||
String[] bondedAddresses = manager.listBonds();
|
||||
if (bondedAddresses == null) return false;
|
||||
|
||||
boolean deviceAdded = false;
|
||||
for (String address : bondedAddresses) {
|
||||
LocalBluetoothDevice device = findDevice(address);
|
||||
if (device == null) {
|
||||
device = new LocalBluetoothDevice(mLocalManager.getContext(), address);
|
||||
mDevices.add(device);
|
||||
dispatchDeviceAdded(device);
|
||||
deviceAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
return deviceAdded;
|
||||
}
|
||||
|
||||
public synchronized List<LocalBluetoothDevice> getDevicesCopy() {
|
||||
return new ArrayList<LocalBluetoothDevice>(mDevices);
|
||||
}
|
||||
|
||||
void onBluetoothStateChanged(boolean enabled) {
|
||||
if (enabled) {
|
||||
readPairedDevices();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void onDeviceAppeared(String address, short rssi) {
|
||||
boolean deviceAdded = false;
|
||||
|
||||
LocalBluetoothDevice device = findDevice(address);
|
||||
if (device == null) {
|
||||
device = new LocalBluetoothDevice(mLocalManager.getContext(), address);
|
||||
mDevices.add(device);
|
||||
deviceAdded = true;
|
||||
}
|
||||
|
||||
device.setRssi(rssi);
|
||||
device.setVisible(true);
|
||||
|
||||
if (deviceAdded) {
|
||||
dispatchDeviceAdded(device);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void onDeviceDisappeared(String address) {
|
||||
LocalBluetoothDevice device = findDevice(address);
|
||||
if (device == null) return;
|
||||
|
||||
device.setVisible(false);
|
||||
checkForDeviceRemoval(device);
|
||||
}
|
||||
|
||||
private void checkForDeviceRemoval(LocalBluetoothDevice device) {
|
||||
if (device.getBondState() == BluetoothDevice.BOND_NOT_BONDED &&
|
||||
!device.isVisible()) {
|
||||
// If device isn't paired, remove it altogether
|
||||
mDevices.remove(device);
|
||||
dispatchDeviceDeleted(device);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void onDeviceNameUpdated(String address) {
|
||||
LocalBluetoothDevice device = findDevice(address);
|
||||
if (device != null) {
|
||||
device.refreshName();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized LocalBluetoothDevice findDevice(String address) {
|
||||
|
||||
for (int i = mDevices.size() - 1; i >= 0; i--) {
|
||||
LocalBluetoothDevice device = mDevices.get(i);
|
||||
|
||||
if (device.getAddress().equals(address)) {
|
||||
return device;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to get the name of a remote device, otherwise returns the address.
|
||||
*
|
||||
* @param address The address.
|
||||
* @return The name, or if unavailable, the address.
|
||||
*/
|
||||
public String getName(String address) {
|
||||
LocalBluetoothDevice device = findDevice(address);
|
||||
return device != null ? device.getName() : address;
|
||||
}
|
||||
|
||||
private void dispatchDeviceAdded(LocalBluetoothDevice device) {
|
||||
synchronized (mCallbacks) {
|
||||
for (Callback callback : mCallbacks) {
|
||||
callback.onDeviceAdded(device);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: divider between prev paired/connected and scanned
|
||||
}
|
||||
|
||||
private void dispatchDeviceDeleted(LocalBluetoothDevice device) {
|
||||
synchronized (mCallbacks) {
|
||||
for (Callback callback : mCallbacks) {
|
||||
callback.onDeviceDeleted(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void onBondingStateChanged(String address, int bondState) {
|
||||
LocalBluetoothDevice device = findDevice(address);
|
||||
if (device == null) {
|
||||
if (!readPairedDevices()) {
|
||||
Log.e(TAG, "Got bonding state changed for " + address +
|
||||
", but we have no record of that device.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
device.refresh();
|
||||
|
||||
if (bondState == BluetoothDevice.BOND_BONDED) {
|
||||
// Auto-connect after pairing
|
||||
device.connect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when there is a bonding error.
|
||||
*
|
||||
* @param address The address of the remote device.
|
||||
* @param reason The reason, one of the error reasons from
|
||||
* BluetoothDevice.UNBOND_REASON_*
|
||||
*/
|
||||
public synchronized void onBondingError(String address, int reason) {
|
||||
mLocalManager.showError(address, R.string.bluetooth_error_title,
|
||||
(reason == BluetoothDevice.UNBOND_REASON_AUTH_FAILED) ?
|
||||
R.string.bluetooth_pairing_pin_error_message :
|
||||
R.string.bluetooth_pairing_error_message);
|
||||
}
|
||||
|
||||
public synchronized void onProfileStateChanged(String address) {
|
||||
LocalBluetoothDevice device = findDevice(address);
|
||||
if (device == null) return;
|
||||
|
||||
device.refresh();
|
||||
}
|
||||
|
||||
public synchronized void onConnectingError(String address) {
|
||||
LocalBluetoothDevice device = findDevice(address);
|
||||
if (device == null) return;
|
||||
|
||||
/*
|
||||
* Go through the device's delegate so we don't spam the user with
|
||||
* errors connecting to different profiles, and instead make sure the
|
||||
* user sees a single error for his single 'connect' action.
|
||||
*/
|
||||
device.showConnectingError();
|
||||
}
|
||||
|
||||
public synchronized void onScanningStateChanged(boolean started) {
|
||||
if (!started) return;
|
||||
|
||||
// If starting a new scan, clear old visibility
|
||||
for (int i = mDevices.size() - 1; i >= 0; i--) {
|
||||
LocalBluetoothDevice device = mDevices.get(i);
|
||||
device.setVisible(false);
|
||||
checkForDeviceRemoval(device);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void onBtClassChanged(String address) {
|
||||
LocalBluetoothDevice device = findDevice(address);
|
||||
if (device != null) {
|
||||
device.refreshBtClass();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,256 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
// 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.
|
||||
*/
|
||||
public class LocalBluetoothManager {
|
||||
private static final String TAG = "LocalBluetoothManager";
|
||||
static final boolean V = true;
|
||||
|
||||
public static final String EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION =
|
||||
"com.android.settings.bluetooth.intent.action.EXTENDED_BLUETOOTH_STATE_CHANGED";
|
||||
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 BluetoothDevice mManager;
|
||||
|
||||
private LocalBluetoothDeviceManager mLocalDeviceManager;
|
||||
private BluetoothEventRedirector mEventRedirector;
|
||||
|
||||
public static enum ExtendedBluetoothState { ENABLED, ENABLING, DISABLED, DISABLING, UNKNOWN }
|
||||
private ExtendedBluetoothState mState = ExtendedBluetoothState.UNKNOWN;
|
||||
|
||||
private List<Callback> mCallbacks = new ArrayList<Callback>();
|
||||
|
||||
private static final int SCAN_EXPIRATION_MS = 5 * 60 * 1000; // 5 mins
|
||||
private long mLastScan;
|
||||
|
||||
public static LocalBluetoothManager getInstance(Context context) {
|
||||
synchronized (INSTANCE_LOCK) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new LocalBluetoothManager();
|
||||
}
|
||||
|
||||
if (!INSTANCE.init(context)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mLocalDeviceManager = new LocalBluetoothDeviceManager(this);
|
||||
|
||||
mEventRedirector = new BluetoothEventRedirector(this);
|
||||
mEventRedirector.start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public BluetoothDevice getBluetoothManager() {
|
||||
return mManager;
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
public Activity getForegroundActivity() {
|
||||
return mForegroundActivity;
|
||||
}
|
||||
|
||||
public void setForegroundActivity(Activity activity) {
|
||||
mForegroundActivity = activity;
|
||||
}
|
||||
|
||||
public SharedPreferences getSharedPreferences() {
|
||||
return mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public LocalBluetoothDeviceManager getLocalDeviceManager() {
|
||||
return mLocalDeviceManager;
|
||||
}
|
||||
|
||||
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()) {
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
// Don't scan more than frequently than SCAN_EXPIRATION_MS, unless forced
|
||||
if (!force && mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) return;
|
||||
|
||||
if (mManager.startDiscovery(true)) {
|
||||
mLastScan = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ExtendedBluetoothState getBluetoothState() {
|
||||
|
||||
if (mState == ExtendedBluetoothState.UNKNOWN) {
|
||||
syncBluetoothState();
|
||||
}
|
||||
|
||||
return mState;
|
||||
}
|
||||
|
||||
void setBluetoothStateInt(ExtendedBluetoothState state) {
|
||||
mState = state;
|
||||
|
||||
/*
|
||||
* TODO: change to callback method. originally it was broadcast to
|
||||
* parallel the framework's method, but it just complicates things here.
|
||||
*/
|
||||
// If this were a real API, I'd add as an extra
|
||||
mContext.sendBroadcast(new Intent(EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION));
|
||||
|
||||
if (state == ExtendedBluetoothState.ENABLED || state == ExtendedBluetoothState.DISABLED) {
|
||||
mLocalDeviceManager.onBluetoothStateChanged(state == ExtendedBluetoothState.ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
private void syncBluetoothState() {
|
||||
setBluetoothStateInt(mManager.isEnabled()
|
||||
? ExtendedBluetoothState.ENABLED
|
||||
: ExtendedBluetoothState.DISABLED);
|
||||
}
|
||||
|
||||
public void setBluetoothEnabled(boolean enabled) {
|
||||
boolean wasSetStateSuccessful = enabled
|
||||
? mManager.enable()
|
||||
: mManager.disable();
|
||||
|
||||
if (wasSetStateSuccessful) {
|
||||
setBluetoothStateInt(enabled
|
||||
? ExtendedBluetoothState.ENABLING
|
||||
: ExtendedBluetoothState.DISABLING);
|
||||
} 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);
|
||||
dispatchScanningStateChanged(started);
|
||||
}
|
||||
|
||||
private void dispatchScanningStateChanged(boolean started) {
|
||||
synchronized (mCallbacks) {
|
||||
for (Callback callback : mCallbacks) {
|
||||
callback.onScanningStateChanged(started);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void showError(String address, int titleResId, int messageResId) {
|
||||
LocalBluetoothDevice device = mLocalDeviceManager.findDevice(address);
|
||||
if (device == null) return;
|
||||
|
||||
String name = device.getName();
|
||||
String message = mContext.getString(messageResId, name);
|
||||
|
||||
if (mForegroundActivity != null) {
|
||||
// Need an activity context to show a dialog
|
||||
AlertDialog ad = new AlertDialog.Builder(mForegroundActivity)
|
||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||
.setTitle(titleResId)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.show();
|
||||
} else {
|
||||
// Fallback on a toast
|
||||
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
void onScanningStateChanged(boolean started);
|
||||
void onDeviceAdded(LocalBluetoothDevice device);
|
||||
void onDeviceDeleted(LocalBluetoothDevice device);
|
||||
}
|
||||
|
||||
}
|
@@ -1,280 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import android.bluetooth.BluetoothA2dp;
|
||||
import android.bluetooth.BluetoothError;
|
||||
import android.bluetooth.BluetoothHeadset;
|
||||
import android.bluetooth.BluetoothClass;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* LocalBluetoothProfileManager is an abstract class defining the basic
|
||||
* functionality related to a profile.
|
||||
*/
|
||||
public abstract class LocalBluetoothProfileManager {
|
||||
|
||||
// TODO: close profiles when we're shutting down
|
||||
private static Map<Profile, LocalBluetoothProfileManager> sProfileMap =
|
||||
new HashMap<Profile, LocalBluetoothProfileManager>();
|
||||
|
||||
protected LocalBluetoothManager mLocalManager;
|
||||
|
||||
public static LocalBluetoothProfileManager getProfileManager(LocalBluetoothManager localManager,
|
||||
Profile profile) {
|
||||
|
||||
LocalBluetoothProfileManager profileManager;
|
||||
|
||||
synchronized (sProfileMap) {
|
||||
profileManager = sProfileMap.get(profile);
|
||||
|
||||
if (profileManager == null) {
|
||||
switch (profile) {
|
||||
case A2DP:
|
||||
profileManager = new A2dpProfileManager(localManager);
|
||||
break;
|
||||
|
||||
case HEADSET:
|
||||
profileManager = new HeadsetProfileManager(localManager);
|
||||
break;
|
||||
}
|
||||
|
||||
sProfileMap.put(profile, profileManager);
|
||||
}
|
||||
}
|
||||
|
||||
return profileManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary method to fill profiles based on a device's class.
|
||||
*
|
||||
* @param btClass The class
|
||||
* @param profiles The list of profiles to fill
|
||||
*/
|
||||
public static void fill(int btClass, List<Profile> profiles) {
|
||||
profiles.clear();
|
||||
|
||||
if (BluetoothA2dp.doesClassMatchSink(btClass)) {
|
||||
profiles.add(Profile.A2DP);
|
||||
}
|
||||
|
||||
if (BluetoothHeadset.doesClassMatch(btClass)) {
|
||||
profiles.add(Profile.HEADSET);
|
||||
}
|
||||
}
|
||||
|
||||
protected LocalBluetoothProfileManager(LocalBluetoothManager localManager) {
|
||||
mLocalManager = localManager;
|
||||
}
|
||||
|
||||
public abstract int connect(String address);
|
||||
|
||||
public abstract int disconnect(String address);
|
||||
|
||||
public abstract int getConnectionStatus(String address);
|
||||
|
||||
public abstract int getSummary(String address);
|
||||
|
||||
public abstract boolean isPreferred(String address);
|
||||
|
||||
public abstract void setPreferred(String address, boolean preferred);
|
||||
|
||||
public boolean isConnected(String address) {
|
||||
return SettingsBtStatus.isConnectionStatusConnected(getConnectionStatus(address));
|
||||
}
|
||||
|
||||
// TODO: int instead of enum
|
||||
public enum Profile {
|
||||
HEADSET(R.string.bluetooth_profile_headset),
|
||||
A2DP(R.string.bluetooth_profile_a2dp);
|
||||
|
||||
public final int localizedString;
|
||||
|
||||
private Profile(int localizedString) {
|
||||
this.localizedString = localizedString;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A2dpProfileManager is an abstraction for the {@link BluetoothA2dp} service.
|
||||
*/
|
||||
private static class A2dpProfileManager extends LocalBluetoothProfileManager {
|
||||
private BluetoothA2dp mService;
|
||||
|
||||
public A2dpProfileManager(LocalBluetoothManager localManager) {
|
||||
super(localManager);
|
||||
mService = new BluetoothA2dp(localManager.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int connect(String address) {
|
||||
return mService.connectSink(address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int disconnect(String address) {
|
||||
return mService.disconnectSink(address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getConnectionStatus(String address) {
|
||||
return convertState(mService.getSinkState(address));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSummary(String address) {
|
||||
int connectionStatus = getConnectionStatus(address);
|
||||
|
||||
if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) {
|
||||
return R.string.bluetooth_a2dp_profile_summary_connected;
|
||||
} else {
|
||||
return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreferred(String address) {
|
||||
return mService.getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreferred(String address, boolean preferred) {
|
||||
mService.setSinkPriority(address,
|
||||
preferred ? BluetoothA2dp.PRIORITY_AUTO : BluetoothA2dp.PRIORITY_OFF);
|
||||
}
|
||||
|
||||
private static int convertState(int a2dpState) {
|
||||
switch (a2dpState) {
|
||||
case BluetoothA2dp.STATE_CONNECTED:
|
||||
return SettingsBtStatus.CONNECTION_STATUS_CONNECTED;
|
||||
case BluetoothA2dp.STATE_CONNECTING:
|
||||
return SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
|
||||
case BluetoothA2dp.STATE_DISCONNECTED:
|
||||
return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
|
||||
case BluetoothA2dp.STATE_DISCONNECTING:
|
||||
return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING;
|
||||
case BluetoothA2dp.STATE_PLAYING:
|
||||
return SettingsBtStatus.CONNECTION_STATUS_ACTIVE;
|
||||
default:
|
||||
return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HeadsetProfileManager is an abstraction for the {@link BluetoothHeadset} service.
|
||||
*/
|
||||
private static class HeadsetProfileManager extends LocalBluetoothProfileManager
|
||||
implements BluetoothHeadset.ServiceListener {
|
||||
private BluetoothHeadset mService;
|
||||
private Handler mUiHandler = new Handler();
|
||||
|
||||
public HeadsetProfileManager(LocalBluetoothManager localManager) {
|
||||
super(localManager);
|
||||
mService = new BluetoothHeadset(localManager.getContext(), this);
|
||||
}
|
||||
|
||||
public void onServiceConnected() {
|
||||
// This could be called on a non-UI thread, funnel to UI thread.
|
||||
mUiHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
/*
|
||||
* We just bound to the service, so refresh the UI of the
|
||||
* headset device.
|
||||
*/
|
||||
String address = mService.getHeadsetAddress();
|
||||
if (TextUtils.isEmpty(address)) return;
|
||||
mLocalManager.getLocalDeviceManager().onProfileStateChanged(address);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onServiceDisconnected() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int connect(String address) {
|
||||
// Since connectHeadset fails if already connected to a headset, we
|
||||
// disconnect from any headset first
|
||||
mService.disconnectHeadset();
|
||||
return mService.connectHeadset(address)
|
||||
? BluetoothError.SUCCESS : BluetoothError.ERROR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int disconnect(String address) {
|
||||
if (mService.getHeadsetAddress().equals(address)) {
|
||||
return mService.disconnectHeadset() ? BluetoothError.SUCCESS : BluetoothError.ERROR;
|
||||
} else {
|
||||
return BluetoothError.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getConnectionStatus(String address) {
|
||||
String headsetAddress = mService.getHeadsetAddress();
|
||||
return headsetAddress != null && headsetAddress.equals(address)
|
||||
? convertState(mService.getState())
|
||||
: SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSummary(String address) {
|
||||
int connectionStatus = getConnectionStatus(address);
|
||||
|
||||
if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) {
|
||||
return R.string.bluetooth_headset_profile_summary_connected;
|
||||
} else {
|
||||
return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreferred(String address) {
|
||||
return mService.getPriority(address) > BluetoothHeadset.PRIORITY_OFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreferred(String address, boolean preferred) {
|
||||
mService.setPriority(address,
|
||||
preferred ? BluetoothHeadset.PRIORITY_AUTO : BluetoothHeadset.PRIORITY_OFF);
|
||||
}
|
||||
|
||||
private static int convertState(int headsetState) {
|
||||
switch (headsetState) {
|
||||
case BluetoothHeadset.STATE_CONNECTED:
|
||||
return SettingsBtStatus.CONNECTION_STATUS_CONNECTED;
|
||||
case BluetoothHeadset.STATE_CONNECTING:
|
||||
return SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
|
||||
case BluetoothHeadset.STATE_DISCONNECTED:
|
||||
return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
|
||||
default:
|
||||
return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
/**
|
||||
* SettingsBtStatus is a helper class that contains constants for various status
|
||||
* codes.
|
||||
*/
|
||||
public class SettingsBtStatus {
|
||||
private static final String TAG = "SettingsBtStatus";
|
||||
|
||||
// Connection status
|
||||
|
||||
public static final int CONNECTION_STATUS_UNKNOWN = 0;
|
||||
public static final int CONNECTION_STATUS_ACTIVE = 1;
|
||||
/** Use {@link #isConnected} to check for the connected state */
|
||||
public static final int CONNECTION_STATUS_CONNECTED = 2;
|
||||
public static final int CONNECTION_STATUS_CONNECTING = 3;
|
||||
public static final int CONNECTION_STATUS_DISCONNECTED = 4;
|
||||
public static final int CONNECTION_STATUS_DISCONNECTING = 5;
|
||||
|
||||
public static final int getConnectionStatusSummary(int connectionStatus) {
|
||||
switch (connectionStatus) {
|
||||
case CONNECTION_STATUS_ACTIVE:
|
||||
return R.string.bluetooth_connected;
|
||||
case CONNECTION_STATUS_CONNECTED:
|
||||
return R.string.bluetooth_connected;
|
||||
case CONNECTION_STATUS_CONNECTING:
|
||||
return R.string.bluetooth_connecting;
|
||||
case CONNECTION_STATUS_DISCONNECTED:
|
||||
return R.string.bluetooth_disconnected;
|
||||
case CONNECTION_STATUS_DISCONNECTING:
|
||||
return R.string.bluetooth_disconnecting;
|
||||
case CONNECTION_STATUS_UNKNOWN:
|
||||
return R.string.bluetooth_unknown;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static final boolean isConnectionStatusConnected(int connectionStatus) {
|
||||
return connectionStatus == CONNECTION_STATUS_ACTIVE
|
||||
|| connectionStatus == CONNECTION_STATUS_CONNECTED;
|
||||
}
|
||||
|
||||
public static final boolean isConnectionStatusBusy(int connectionStatus) {
|
||||
return connectionStatus == CONNECTION_STATUS_CONNECTING
|
||||
|| connectionStatus == CONNECTION_STATUS_DISCONNECTING;
|
||||
}
|
||||
|
||||
public static final int getPairingStatusSummary(int bondState) {
|
||||
switch (bondState) {
|
||||
case BluetoothDevice.BOND_BONDED:
|
||||
return R.string.bluetooth_paired;
|
||||
case BluetoothDevice.BOND_BONDING:
|
||||
return R.string.bluetooth_pairing;
|
||||
case BluetoothDevice.BOND_NOT_BONDED:
|
||||
return R.string.bluetooth_not_connected;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user