summaryrefslogtreecommitdiffstats
path: root/core/java/android/server
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-02 22:54:33 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-02 22:54:33 -0800
commit3dec7d563a2f3e1eb967ce2054a00b6620e3558c (patch)
treeaa3b0365c47cb3c1607c0dc76c8d32b4046fc287 /core/java/android/server
parent15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b (diff)
downloadframeworks_base-3dec7d563a2f3e1eb967ce2054a00b6620e3558c.zip
frameworks_base-3dec7d563a2f3e1eb967ce2054a00b6620e3558c.tar.gz
frameworks_base-3dec7d563a2f3e1eb967ce2054a00b6620e3558c.tar.bz2
auto import from //depot/cupcake/@137055
Diffstat (limited to 'core/java/android/server')
-rw-r--r--core/java/android/server/BluetoothA2dpService.java82
-rw-r--r--core/java/android/server/BluetoothDeviceService.java24
-rw-r--r--core/java/android/server/search/SearchableInfo.java18
3 files changed, 105 insertions, 19 deletions
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index 58f9491..f8bc765 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -15,8 +15,7 @@
*/
/**
- * TODO: Move this to
- * java/services/com/android/server/BluetoothA2dpService.java
+ * TODO: Move this to services.jar
* and make the contructor package private again.
* @hide
*/
@@ -35,15 +34,16 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.os.Binder;
+import android.os.Handler;
+import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.List;
import java.util.HashMap;
-import java.util.Iterator;
+import java.util.List;
public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
private static final String TAG = "BluetoothA2dpService";
@@ -57,6 +57,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
private static final String A2DP_SINK_ADDRESS = "a2dp_sink_address";
private static final String BLUETOOTH_ENABLED = "bluetooth_enabled";
+ private static final int MESSAGE_CONNECT_TO = 1;
+
private final Context mContext;
private final IntentFilter mIntentFilter;
private HashMap<String, SinkState> mAudioDevices;
@@ -86,6 +88,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
mIntentFilter = new IntentFilter(BluetoothIntent.ENABLED_ACTION);
mIntentFilter.addAction(BluetoothIntent.DISABLED_ACTION);
mIntentFilter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
+ mIntentFilter.addAction(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION);
mContext.registerReceiver(mReceiver, mIntentFilter);
if (device.isEnabled()) {
@@ -123,6 +126,37 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
setSinkPriority(address, BluetoothA2dp.PRIORITY_OFF);
break;
}
+ } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION)) {
+ if (getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF) {
+ // This device is a preferred sink. Make an A2DP connection
+ // after a delay. We delay to avoid connection collisions,
+ // and to give other profiles such as HFP a chance to
+ // connect first.
+ Message msg = Message.obtain(mHandler, MESSAGE_CONNECT_TO, address);
+ mHandler.sendMessageDelayed(msg, 6000);
+ }
+ }
+ }
+ };
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MESSAGE_CONNECT_TO:
+ String address = (String)msg.obj;
+ // check device is still preferred, and nothing is currently
+ // connected
+ if (getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF &&
+ lookupSinksMatchingStates(new int[] {
+ BluetoothA2dp.STATE_CONNECTING,
+ BluetoothA2dp.STATE_CONNECTED,
+ BluetoothA2dp.STATE_PLAYING,
+ BluetoothA2dp.STATE_DISCONNECTING}).size() == 0) {
+ log("Auto-connecting A2DP to sink " + address);
+ connectSink(address);
+ }
+ break;
}
}
};
@@ -142,7 +176,10 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
private synchronized void onBluetoothDisable() {
if (mAudioDevices != null) {
- for (String path : mAudioDevices.keySet()) {
+ // copy to allow modification during iteration
+ String[] paths = new String[mAudioDevices.size()];
+ paths = mAudioDevices.keySet().toArray(paths);
+ for (String path : paths) {
switch (mAudioDevices.get(path).state) {
case BluetoothA2dp.STATE_CONNECTING:
case BluetoothA2dp.STATE_CONNECTED:
@@ -234,17 +271,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
public synchronized List<String> listConnectedSinks() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- List<String> connectedSinks = new ArrayList<String>();
- if (mAudioDevices == null) {
- return connectedSinks;
- }
- for (SinkState sink : mAudioDevices.values()) {
- if (sink.state == BluetoothA2dp.STATE_CONNECTED ||
- sink.state == BluetoothA2dp.STATE_PLAYING) {
- connectedSinks.add(sink.address);
- }
- }
- return connectedSinks;
+ return lookupSinksMatchingStates(new int[] {BluetoothA2dp.STATE_CONNECTED,
+ BluetoothA2dp.STATE_PLAYING});
}
public synchronized int getSinkState(String address) {
@@ -298,7 +326,11 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
// bluez 3.36 quietly disconnects the previous sink when a new sink
// is connected, so we need to mark all previously connected sinks as
// disconnected
- for (String oldPath : mAudioDevices.keySet()) {
+
+ // copy to allow modification during iteration
+ String[] paths = new String[mAudioDevices.size()];
+ paths = mAudioDevices.keySet().toArray(paths);
+ for (String oldPath : paths) {
if (path.equals(oldPath)) {
continue;
}
@@ -350,6 +382,22 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
return null;
}
+ private synchronized List<String> lookupSinksMatchingStates(int[] states) {
+ List<String> sinks = new ArrayList<String>();
+ if (mAudioDevices == null) {
+ return sinks;
+ }
+ for (SinkState sink : mAudioDevices.values()) {
+ for (int state : states) {
+ if (sink.state == state) {
+ sinks.add(sink.address);
+ break;
+ }
+ }
+ }
+ return sinks;
+ }
+
private synchronized void updateState(String path, int state) {
if (mAudioDevices == null) return;
diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java
index fa53a60..950ff3a 100644
--- a/core/java/android/server/BluetoothDeviceService.java
+++ b/core/java/android/server/BluetoothDeviceService.java
@@ -141,6 +141,20 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
mBondState.setBondState(address, BluetoothDevice.BOND_NOT_BONDED,
BluetoothDevice.UNBOND_REASON_AUTH_CANCELED);
}
+
+ // Remove remoteServiceChannelCallbacks
+ HashMap<String, IBluetoothDeviceCallback> callbacksMap =
+ mEventLoop.getRemoteServiceChannelCallbacks();
+ IBluetoothDeviceCallback callback;
+
+ for (String address : callbacksMap.keySet()) {
+ callback = callbacksMap.get(address);
+ try {
+ callback.onGetRemoteServiceChannelResult(address, BluetoothError.ERROR_DISABLED);
+ } catch (RemoteException e) {}
+ callbacksMap.remove(address);
+ }
+
// update mode
Intent intent = new Intent(BluetoothIntent.SCAN_MODE_CHANGED_ACTION);
intent.putExtra(BluetoothIntent.SCAN_MODE, BluetoothDevice.SCAN_MODE_NONE);
@@ -569,10 +583,18 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
}
address = address.toUpperCase();
+ String[] bonding = mBondState.listInState(BluetoothDevice.BOND_BONDING);
+ if (bonding.length > 0 && !bonding[0].equals(address)) {
+ log("Ignoring createBond(): another device is bonding");
+ // a different device is currently bonding, fail
+ return false;
+ }
+
// Check for bond state only if we are not performing auto
// pairing exponential back-off attempts.
if (!mBondState.isAutoPairingAttemptsInProgress(address) &&
- mBondState.getBondState(address) != BluetoothDevice.BOND_NOT_BONDED) {
+ mBondState.getBondState(address) != BluetoothDevice.BOND_NOT_BONDED) {
+ log("Ignoring createBond(): this device is already bonding or bonded");
return false;
}
diff --git a/core/java/android/server/search/SearchableInfo.java b/core/java/android/server/search/SearchableInfo.java
index c18675e..0c04839 100644
--- a/core/java/android/server/search/SearchableInfo.java
+++ b/core/java/android/server/search/SearchableInfo.java
@@ -35,6 +35,7 @@ import android.text.InputType;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
+import android.view.inputmethod.EditorInfo;
import java.io.IOException;
import java.util.ArrayList;
@@ -77,6 +78,7 @@ public final class SearchableInfo implements Parcelable {
private int mIconId = 0;
private int mSearchButtonText = 0;
private int mSearchInputType = 0;
+ private int mSearchImeOptions = 0;
private String mSuggestAuthority = null;
private String mSuggestPath = null;
private String mSuggestSelection = null;
@@ -429,8 +431,9 @@ public final class SearchableInfo implements Parcelable {
com.android.internal.R.styleable.Searchable_searchButtonText, 0);
mSearchInputType = a.getInt(com.android.internal.R.styleable.Searchable_inputType,
InputType.TYPE_CLASS_TEXT |
- InputType.TYPE_TEXT_FLAG_SEARCH |
InputType.TYPE_TEXT_VARIATION_NORMAL);
+ mSearchImeOptions = a.getInt(com.android.internal.R.styleable.Searchable_imeOptions,
+ EditorInfo.IME_ACTION_SEARCH);
setSearchModeFlags();
if (DBG_INHIBIT_SUGGESTIONS == 0) {
@@ -743,6 +746,17 @@ public final class SearchableInfo implements Parcelable {
}
/**
+ * Return the input method options specified in the searchable attributes.
+ * This will default to EditorInfo.ACTION_SEARCH if not specified (which is
+ * appropriate for a search box).
+ *
+ * @return the input type
+ */
+ public int getImeOptions() {
+ return mSearchImeOptions;
+ }
+
+ /**
* Return the list of searchable activities, for use in the drop-down.
*/
public static ArrayList<SearchableInfo> getSearchablesList() {
@@ -782,6 +796,7 @@ public final class SearchableInfo implements Parcelable {
mIconId = in.readInt();
mSearchButtonText = in.readInt();
mSearchInputType = in.readInt();
+ mSearchImeOptions = in.readInt();
setSearchModeFlags();
mSuggestAuthority = in.readString();
@@ -818,6 +833,7 @@ public final class SearchableInfo implements Parcelable {
dest.writeInt(mIconId);
dest.writeInt(mSearchButtonText);
dest.writeInt(mSearchInputType);
+ dest.writeInt(mSearchImeOptions);
dest.writeString(mSuggestAuthority);
dest.writeString(mSuggestPath);