Merge change Ie05f07df into eclair
* changes:
fix [2170319] gmail bulk operation checkbox latency on passion
diff --git a/Android.mk b/Android.mk
index 1428454..2e2fec1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -90,6 +90,7 @@
core/java/android/backup/IRestoreSession.aidl \
core/java/android/bluetooth/IBluetooth.aidl \
core/java/android/bluetooth/IBluetoothA2dp.aidl \
+ core/java/android/bluetooth/IBluetoothCallback.aidl \
core/java/android/bluetooth/IBluetoothHeadset.aidl \
core/java/android/bluetooth/IBluetoothPbap.aidl \
core/java/android/content/IContentService.aidl \
diff --git a/api/current.xml b/api/current.xml
index e0a0278..f4d81c7 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -25550,6 +25550,17 @@
visibility="public"
>
</method>
+<method name="getDefaultAdapter"
+ return="android.bluetooth.BluetoothAdapter"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getName"
return="java.lang.String"
abstract="false"
@@ -25618,7 +25629,7 @@
visibility="public"
>
</method>
-<method name="listenUsingRfcomm"
+<method name="listenUsingRfcommWithServiceRecord"
return="android.bluetooth.BluetoothServerSocket"
abstract="false"
native="false"
@@ -25630,7 +25641,7 @@
>
<parameter name="name" type="java.lang.String">
</parameter>
-<parameter name="uuid" type="android.os.ParcelUuid">
+<parameter name="uuid" type="java.util.UUID">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -26804,7 +26815,7 @@
>
<implements name="android.os.Parcelable">
</implements>
-<method name="createRfcommSocket"
+<method name="createRfcommSocketToServiceRecord"
return="android.bluetooth.BluetoothSocket"
abstract="false"
native="false"
@@ -26814,7 +26825,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="channel" type="int">
+<parameter name="uuid" type="java.util.UUID">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -31505,17 +31516,6 @@
visibility="public"
>
</field>
-<field name="BLUETOOTH_SERVICE"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value=""bluetooth""
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="CLIPBOARD_SERVICE"
type="java.lang.String"
transient="false"
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index 8ba7c01..f48f150 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -22,8 +22,6 @@
import org.xmlpull.v1.XmlPullParserException;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.IBluetooth;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -182,8 +180,6 @@
private StatusBarManager mStatusBarManager = null;
private TelephonyManager mTelephonyManager = null;
private ClipboardManager mClipboardManager = null;
- private boolean mIsBluetoothAdapterCached = false;
- private BluetoothAdapter mBluetoothAdapter;
private boolean mRestricted;
private AccountManager mAccountManager; // protected by mSync
@@ -883,8 +879,6 @@
return getSearchManager();
} else if (SENSOR_SERVICE.equals(name)) {
return getSensorManager();
- } else if (BLUETOOTH_SERVICE.equals(name)) {
- return getBluetoothAdapter();
} else if (VIBRATOR_SERVICE.equals(name)) {
return getVibrator();
} else if (STATUS_BAR_SERVICE.equals(name)) {
@@ -1034,18 +1028,6 @@
return mSearchManager;
}
- private synchronized BluetoothAdapter getBluetoothAdapter() {
- if (!mIsBluetoothAdapterCached) {
- mIsBluetoothAdapterCached = true;
- IBinder b = ServiceManager.getService(BLUETOOTH_SERVICE);
- if (b != null) {
- IBluetooth service = IBluetooth.Stub.asInterface(b);
- mBluetoothAdapter = new BluetoothAdapter(service);
- }
- }
- return mBluetoothAdapter;
- }
-
private SensorManager getSensorManager() {
synchronized (mSync) {
if (mSensorManager == null) {
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index c6a0619..cc35b7d 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -20,9 +20,11 @@
import android.annotation.SdkConstant.SdkConstantType;
import android.os.Binder;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Message;
import android.os.ParcelUuid;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.util.Log;
import java.io.IOException;
@@ -31,14 +33,13 @@
import java.util.LinkedList;
import java.util.Random;
import java.util.Set;
+import java.util.UUID;
/**
* Represents the local Bluetooth adapter.
*
- * <p>Use {@link android.content.Context#getSystemService} with {@link
- * android.content.Context#BLUETOOTH_SERVICE} to get the default local
- * Bluetooth adapter. On most Android devices there is only one local
- * Bluetotoh adapter.
+ * <p>Use {@link #getDefaultAdapter} to get the default local Bluetooth
+ * adapter.
*
* <p>Use the {@link BluetoothDevice} class for operations on remote Bluetooth
* devices.
@@ -256,12 +257,40 @@
*/
public static final String EXTRA_LOCAL_NAME = "android.bluetooth.adapter.extra.LOCAL_NAME";
+ /** @hide */
+ public static final String BLUETOOTH_SERVICE = "bluetooth";
+
private static final int ADDRESS_LENGTH = 17;
+ /**
+ * Lazyily initialized singleton. Guaranteed final after first object
+ * constructed.
+ */
+ private static BluetoothAdapter sAdapter;
+
private final IBluetooth mService;
/**
- * Do not use this constructor. Use Context.getSystemService() instead.
+ * Get a handle to the default local Bluetooth adapter.
+ * <p>Currently Android only supports one Bluetooth adapter, but the API
+ * could be extended to support more. This will always return the default
+ * adapter.
+ * @return the default local adapter, or null if Bluetooth is not supported
+ * on this hardware platform
+ */
+ public static synchronized BluetoothAdapter getDefaultAdapter() {
+ if (sAdapter == null) {
+ IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
+ if (b != null) {
+ IBluetooth service = IBluetooth.Stub.asInterface(b);
+ sAdapter = new BluetoothAdapter(service);
+ }
+ }
+ return sAdapter;
+ }
+
+ /**
+ * Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance.
* @hide
*/
public BluetoothAdapter(IBluetooth service) {
@@ -564,8 +593,16 @@
}
/**
- * Randomly picks RFCOMM channels until none are left.
+ * Picks RFCOMM channels until none are left.
* Avoids reserved channels.
+ * Ideally we would pick random channels, but in the current implementation
+ * we start with the channel that is the hash of the UUID, and try every
+ * available channel from there. This means that in most cases a given
+ * uuid will use the same channel. This is a workaround for a Bluez SDP
+ * bug where we are not updating the cache when the channel changes for a
+ * uuid.
+ * TODO: Fix the Bluez SDP caching bug, and go back to random channel
+ * selection
*/
private static class RfcommChannelPicker {
private static final int[] RESERVED_RFCOMM_CHANNELS = new int[] {
@@ -579,7 +616,9 @@
private final LinkedList<Integer> mChannels; // local list of channels left to try
- public RfcommChannelPicker() {
+ private final UUID mUuid;
+
+ public RfcommChannelPicker(UUID uuid) {
synchronized (RfcommChannelPicker.class) {
if (sChannels == null) {
// lazy initialization of non-reserved rfcomm channels
@@ -594,13 +633,21 @@
}
mChannels = (LinkedList<Integer>)sChannels.clone();
}
+ mUuid = uuid;
}
- /* Returns next random channel, or -1 if we're out */
+ /* Returns next channel, or -1 if we're out */
public int nextChannel() {
- if (mChannels.size() == 0) {
- return -1;
+ int channel = mUuid.hashCode(); // always pick the same channel to try first
+ Integer channelInt;
+ while (mChannels.size() > 0) {
+ channelInt = new Integer(channel);
+ if (mChannels.remove(channelInt)) {
+ return channel;
+ }
+ channel = (channel % BluetoothSocket.MAX_RFCOMM_CHANNEL) + 1;
}
- return mChannels.remove(sRandom.nextInt(mChannels.size()));
+
+ return -1;
}
}
@@ -644,6 +691,8 @@
* can use the same UUID to query our SDP server and discover which channel
* to connect to. This SDP record will be removed when this socket is
* closed, or if this application closes unexpectedly.
+ * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to
+ * connect to this socket from another device using the same {@link UUID}.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH}
* @param name service name for SDP record
* @param uuid uuid for SDP record
@@ -651,9 +700,9 @@
* @throws IOException on error, for example Bluetooth not available, or
* insufficient permissions, or channel in use.
*/
- public BluetoothServerSocket listenUsingRfcomm(String name, ParcelUuid uuid)
+ public BluetoothServerSocket listenUsingRfcommWithServiceRecord(String name, UUID uuid)
throws IOException {
- RfcommChannelPicker picker = new RfcommChannelPicker();
+ RfcommChannelPicker picker = new RfcommChannelPicker(uuid);
BluetoothServerSocket socket;
int channel;
@@ -687,7 +736,8 @@
int handle = -1;
try {
- handle = mService.addRfcommServiceRecord(name, uuid, channel, new Binder());
+ handle = mService.addRfcommServiceRecord(name, new ParcelUuid(uuid), channel,
+ new Binder());
} catch (RemoteException e) {Log.e(TAG, "", e);}
if (handle == -1) {
try {
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index d5393ed..9c23746 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -18,7 +18,6 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
-import android.content.Context;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -316,11 +315,28 @@
*/
public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
-
- private static IBluetooth sService; /* Guarenteed constant after first object constructed */
+ /**
+ * Lazy initialization. Guaranteed final after first object constructed, or
+ * getService() called.
+ * TODO: Unify implementation of sService amongst BluetoothFoo API's
+ */
+ private static IBluetooth sService;
private final String mAddress;
+ /*package*/ static IBluetooth getService() {
+ synchronized (BluetoothDevice.class) {
+ if (sService == null) {
+ IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
+ if (b == null) {
+ throw new RuntimeException("Bluetooth service not available");
+ }
+ sService = IBluetooth.Stub.asInterface(b);
+ }
+ }
+ return sService;
+ }
+
/**
* Create a new BluetoothDevice
* Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB",
@@ -331,16 +347,7 @@
* @hide
*/
/*package*/ BluetoothDevice(String address) {
- synchronized (BluetoothDevice.class) {
- if (sService == null) {
- IBinder b = ServiceManager.getService(Context.BLUETOOTH_SERVICE);
- if (b == null) {
- throw new RuntimeException("Bluetooth service not available");
- }
- sService = IBluetooth.Stub.asInterface(b);
- }
- }
-
+ getService(); // ensures sService is initialized
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
}
@@ -551,7 +558,7 @@
*/
public boolean fetchUuidsWithSdp() {
try {
- return sService.fetchRemoteUuidsWithSdp(mAddress);
+ return sService.fetchRemoteUuids(mAddress, null, null);
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
@@ -598,7 +605,7 @@
/**
* Create an RFCOMM {@link BluetoothSocket} ready to start a secure
- * outgoing connection to this remote device.
+ * outgoing connection to this remote device on given channel.
* <p>The remote device will be authenticated and communication on this
* socket will be encrypted.
* <p>Use {@link BluetoothSocket#connect} to intiate the outgoing
@@ -610,9 +617,34 @@
* @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
* @throws IOException on error, for example Bluetooth not available, or
* insufficient permissions
+ * @hide
*/
public BluetoothSocket createRfcommSocket(int channel) throws IOException {
- return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel);
+ return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel,
+ null);
+ }
+
+ /**
+ * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
+ * outgoing connection to this remote device using SDP lookup of uuid.
+ * <p>This is designed to be used with {@link
+ * BluetoothAdapter#listenUsingRfcommWithServiceRecord} for peer-peer
+ * Bluetooth applications.
+ * <p>Use {@link BluetoothSocket#connect} to intiate the outgoing
+ * connection. This will also perform an SDP lookup of the given uuid to
+ * determine which channel to connect to.
+ * <p>The remote device will be authenticated and communication on this
+ * socket will be encrypted.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+ *
+ * @param uuid service record uuid to lookup RFCOMM channel
+ * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
+ * @throws IOException on error, for example Bluetooth not available, or
+ * insufficient permissions
+ */
+ public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
+ return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, -1,
+ new ParcelUuid(uuid));
}
/**
@@ -628,7 +660,8 @@
* @hide
*/
public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
- return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port);
+ return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port,
+ null);
}
/**
@@ -640,7 +673,7 @@
* @hide
*/
public BluetoothSocket createScoSocket() throws IOException {
- return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1);
+ return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1, null);
}
/**
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index d126ea4..605bdc1 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -36,13 +36,13 @@
* connection orientated, streaming transport over Bluetooth. It is also known
* as the Serial Port Profile (SPP).
*
- * <p>Use {@link BluetoothDevice#createRfcommSocket} to create a new {@link
- * BluetoothSocket} ready for an outgoing connection to a remote
+ * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to create
+ * a new {@link BluetoothSocket} ready for an outgoing connection to a remote
* {@link BluetoothDevice}.
*
- * <p>Use {@link BluetoothAdapter#listenUsingRfcomm} to create a listening
- * {@link BluetoothServerSocket} ready for incoming connections to the local
- * {@link BluetoothAdapter}.
+ * <p>Use {@link BluetoothAdapter#listenUsingRfcommWithServiceRecord} to
+ * create a listening {@link BluetoothServerSocket} ready for incoming
+ * connections to the local {@link BluetoothAdapter}.
*
* <p>{@link BluetoothSocket} and {@link BluetoothServerSocket} are thread
* safe. In particular, {@link #close} will always immediately abort ongoing
@@ -68,7 +68,7 @@
*/
/*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port)
throws IOException {
- mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port);
+ mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port, null);
}
/**
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index b9e33f3..7e72590 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -16,11 +16,15 @@
package android.bluetooth;
+import android.bluetooth.IBluetoothCallback;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Log;
+
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
@@ -38,13 +42,13 @@
* connection orientated, streaming transport over Bluetooth. It is also known
* as the Serial Port Profile (SPP).
*
- * <p>Use {@link BluetoothDevice#createRfcommSocket} to create a new {@link
- * BluetoothSocket} ready for an outgoing connection to a remote
+ * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to create
+ * a new {@link BluetoothSocket} ready for an outgoing connection to a remote
* {@link BluetoothDevice}.
*
- * <p>Use {@link BluetoothAdapter#listenUsingRfcomm} to create a listening
- * {@link BluetoothServerSocket} ready for incoming connections to the local
- * {@link BluetoothAdapter}.
+ * <p>Use {@link BluetoothAdapter#listenUsingRfcommWithServiceRecord} to
+ * create a listening {@link BluetoothServerSocket} ready for incoming
+ * connections to the local {@link BluetoothAdapter}.
*
* <p>{@link BluetoothSocket} and {@link BluetoothServerSocket} are thread
* safe. In particular, {@link #close} will always immediately abort ongoing
@@ -54,6 +58,8 @@
* {@link android.Manifest.permission#BLUETOOTH}
*/
public final class BluetoothSocket implements Closeable {
+ private static final String TAG = "BluetoothSocket";
+
/** @hide */
public static final int MAX_RFCOMM_CHANNEL = 30;
@@ -66,13 +72,15 @@
/*package*/ static final int EADDRINUSE = 98;
private final int mType; /* one of TYPE_RFCOMM etc */
- private final int mPort; /* RFCOMM channel or L2CAP psm */
private final BluetoothDevice mDevice; /* remote device */
private final String mAddress; /* remote address */
private final boolean mAuth;
private final boolean mEncrypt;
private final BluetoothInputStream mInputStream;
private final BluetoothOutputStream mOutputStream;
+ private final SdpHelper mSdp;
+
+ private int mPort; /* RFCOMM channel or L2CAP psm */
/** prevents all native calls after destroyNative() */
private boolean mClosed;
@@ -91,16 +99,24 @@
* @param encrypt require the connection to be encrypted
* @param device remote device that this socket can connect to
* @param port remote port
+ * @param uuid SDP uuid
* @throws IOException On error, for example Bluetooth not available, or
* insufficient priveleges
*/
/*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt,
- BluetoothDevice device, int port) throws IOException {
- if (type == BluetoothSocket.TYPE_RFCOMM) {
+ BluetoothDevice device, int port, ParcelUuid uuid) throws IOException {
+ if (type == BluetoothSocket.TYPE_RFCOMM && uuid == null && fd == -1) {
if (port < 1 || port > MAX_RFCOMM_CHANNEL) {
throw new IOException("Invalid RFCOMM channel: " + port);
}
}
+ if (uuid == null) {
+ mPort = port;
+ mSdp = null;
+ } else {
+ mSdp = new SdpHelper(device, uuid);
+ mPort = -1;
+ }
mType = type;
mAuth = auth;
mEncrypt = encrypt;
@@ -110,7 +126,6 @@
} else {
mAddress = device.getAddress();
}
- mPort = port;
if (fd == -1) {
initSocketNative();
} else {
@@ -123,7 +138,7 @@
}
/**
- * Construct a BluetoothSocket from address.
+ * Construct a BluetoothSocket from address. Used by native code.
* @param type type of socket
* @param fd fd to use for connected socket, or -1 for a new socket
* @param auth require the remote device to be authenticated
@@ -135,7 +150,7 @@
*/
private BluetoothSocket(int type, int fd, boolean auth, boolean encrypt, String address,
int port) throws IOException {
- this(type, fd, auth, encrypt, new BluetoothDevice(address), port);
+ this(type, fd, auth, encrypt, new BluetoothDevice(address), port, null);
}
/** @hide */
@@ -160,7 +175,12 @@
mLock.readLock().lock();
try {
if (mClosed) throw new IOException("socket closed");
- connectNative();
+
+ if (mSdp != null) {
+ mPort = mSdp.doSdp(); // blocks
+ }
+
+ connectNative(); // blocks
} finally {
mLock.readLock().unlock();
}
@@ -176,12 +196,15 @@
mLock.readLock().lock();
try {
if (mClosed) return;
+ if (mSdp != null) {
+ mSdp.cancel();
+ }
abortNative();
} finally {
mLock.readLock().unlock();
}
- // all native calls are guarenteed to immediately return after
+ // all native calls are guaranteed to immediately return after
// abortNative(), so this lock should immediatley acquire
mLock.writeLock().lock();
try {
@@ -291,4 +314,62 @@
* use strerr to convert to string error.
*/
/*package*/ native void throwErrnoNative(int errno) throws IOException;
+
+ /**
+ * Helper to perform blocking SDP lookup.
+ */
+ private static class SdpHelper extends IBluetoothCallback.Stub {
+ private final IBluetooth service;
+ private final ParcelUuid uuid;
+ private final BluetoothDevice device;
+ private int channel;
+ private boolean canceled;
+ public SdpHelper(BluetoothDevice device, ParcelUuid uuid) {
+ service = BluetoothDevice.getService();
+ this.device = device;
+ this.uuid = uuid;
+ canceled = false;
+ }
+ /**
+ * Returns the RFCOMM channel for the UUID, or throws IOException
+ * on failure.
+ */
+ public synchronized int doSdp() throws IOException {
+ if (canceled) throw new IOException("Service discovery canceled");
+ channel = -1;
+
+ boolean inProgress = false;
+ try {
+ inProgress = service.fetchRemoteUuids(device.getAddress(), uuid, this);
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+
+ if (!inProgress) throw new IOException("Unable to start Service Discovery");
+
+ try {
+ /* 12 second timeout as a precaution - onRfcommChannelFound
+ * should always occur before the timeout */
+ wait(12000); // block
+
+ } catch (InterruptedException e) {}
+
+ if (canceled) throw new IOException("Service discovery canceled");
+ if (channel < 1) throw new IOException("Service discovery failed");
+
+ return channel;
+ }
+ /** Object cannot be re-used after calling cancel() */
+ public synchronized void cancel() {
+ if (!canceled) {
+ canceled = true;
+ channel = -1;
+ notifyAll(); // unblock
+ }
+ }
+ public synchronized void onRfcommChannelFound(int channel) {
+ if (!canceled) {
+ this.channel = channel;
+ notifyAll(); // unblock
+ }
+ }
+ }
}
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index e54abec..7e752af 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.bluetooth.IBluetoothCallback;
import android.os.ParcelUuid;
/**
@@ -53,8 +54,8 @@
String getRemoteName(in String address);
int getRemoteClass(in String address);
ParcelUuid[] getRemoteUuids(in String address);
- boolean fetchRemoteUuidsWithSdp(in String address);
- int getRemoteServiceChannel(in String address,in ParcelUuid uuid);
+ boolean fetchRemoteUuids(in String address, in ParcelUuid uuid, in IBluetoothCallback callback);
+ int getRemoteServiceChannel(in String address, in ParcelUuid uuid);
boolean setPin(in String address, in byte[] pin);
boolean setPasskey(in String address, int passkey);
diff --git a/core/java/android/bluetooth/IBluetoothCallback.aidl b/core/java/android/bluetooth/IBluetoothCallback.aidl
new file mode 100644
index 0000000..8edb3f4
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothCallback.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009, 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 android.bluetooth;
+
+/**
+ * System private API for Bluetooth service callbacks.
+ *
+ * {@hide}
+ */
+interface IBluetoothCallback
+{
+ void onRfcommChannelFound(int channel);
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index fe4665e..8f1c671 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1218,14 +1218,6 @@
*/
public static final String SENSOR_SERVICE = "sensor";
/**
- * Use with {@link #getSystemService} to retrieve a {@link
- * android.bluetooth.BluetoothAdapter} for using Bluetooth.
- *
- * @see #getSystemService
- * @see android.bluetooth.BluetoothAdapter
- */
- public static final String BLUETOOTH_SERVICE = "bluetooth";
- /**
* Use with {@link #getSystemService} to retrieve a
* com.android.server.WallpaperService for accessing wallpapers.
*
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index d61b42f..b73e53f 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -137,7 +137,7 @@
throw new RuntimeException("Could not init BluetoothA2dpService");
}
- mAdapter = (BluetoothAdapter) context.getSystemService(Context.BLUETOOTH_SERVICE);
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
mIntentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 0152223..da1918a 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -55,6 +55,10 @@
private static final int EVENT_RESTART_BLUETOOTH = 2;
private static final int EVENT_PAIRING_CONSENT_DELAYED_ACCEPT = 3;
+ private static final int CREATE_DEVICE_ALREADY_EXISTS = 1;
+ private static final int CREATE_DEVICE_SUCCESS = 0;
+ private static final int CREATE_DEVICE_FAILED = -1;
+
// The time (in millisecs) to delay the pairing attempt after the first
// auto pairing attempt fails. We use an exponential delay with
// INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY as the initial value and
@@ -550,14 +554,27 @@
mBluetoothService.updateRemoteDevicePropertiesCache(address);
}
mBluetoothService.sendUuidIntent(address);
+ mBluetoothService.makeServiceChannelCallbacks(address);
}
- private void onCreateDeviceResult(String address, boolean result) {
- if (DBG) {
- log("Result of onCreateDeviceResult:" + result);
- }
- if (!result) {
+ private void onCreateDeviceResult(String address, int result) {
+ if (DBG) log("Result of onCreateDeviceResult:" + result);
+
+ switch (result) {
+ case CREATE_DEVICE_ALREADY_EXISTS:
+ String path = mBluetoothService.getObjectPathFromAddress(address);
+ if (path != null) {
+ mBluetoothService.discoverServicesNative(path, "");
+ break;
+ }
+ Log.w(TAG, "Device exists, but we dont have the bluez path, failing");
+ // fall-through
+ case CREATE_DEVICE_FAILED:
mBluetoothService.sendUuidIntent(address);
+ mBluetoothService.makeServiceChannelCallbacks(address);
+ break;
+ case CREATE_DEVICE_SUCCESS:
+ // nothing to do, UUID intent's will be sent via property changed
}
}
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 93133d7..6d4d152 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -31,6 +31,7 @@
import android.bluetooth.BluetoothSocket;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetooth;
+import android.bluetooth.IBluetoothCallback;
import android.os.ParcelUuid;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -55,6 +56,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
public class BluetoothService extends IBluetooth.Stub {
@@ -86,14 +88,39 @@
// This timeout should be greater than the page timeout
private static final int UUID_INTENT_DELAY = 6000;
- private final Map<String, String> mAdapterProperties;
- private final HashMap <String, Map<String, String>> mDeviceProperties;
+ /** Always retrieve RFCOMM channel for these SDP UUIDs */
+ private static final ParcelUuid[] RFCOMM_UUIDS = {
+ BluetoothUuid.Handsfree,
+ BluetoothUuid.HSP,
+ BluetoothUuid.ObexObjectPush };
- private final HashMap <String, Map<ParcelUuid, Integer>> mDeviceServiceChannelCache;
- private final ArrayList <String> mUuidIntentTracker;
+
+ private final Map<String, String> mAdapterProperties;
+ private final HashMap<String, Map<String, String>> mDeviceProperties;
+
+ private final HashMap<String, Map<ParcelUuid, Integer>> mDeviceServiceChannelCache;
+ private final ArrayList<String> mUuidIntentTracker;
+ private final HashMap<RemoteService, IBluetoothCallback> mUuidCallbackTracker;
private final HashMap<Integer, Integer> mServiceRecordToPid;
+ private static class RemoteService {
+ public String address;
+ public ParcelUuid uuid;
+ public RemoteService(String address, ParcelUuid uuid) {
+ this.address = address;
+ this.uuid = uuid;
+ }
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof RemoteService) {
+ RemoteService service = (RemoteService)o;
+ return address.equals(service.address) && uuid.equals(service.uuid);
+ }
+ return false;
+ }
+ }
+
static {
classInitNative();
}
@@ -121,12 +148,13 @@
mDeviceServiceChannelCache = new HashMap<String, Map<ParcelUuid, Integer>>();
mUuidIntentTracker = new ArrayList<String>();
+ mUuidCallbackTracker = new HashMap<RemoteService, IBluetoothCallback>();
mServiceRecordToPid = new HashMap<Integer, Integer>();
registerForAirplaneMode();
}
public synchronized void initAfterRegistration() {
- mAdapter = (BluetoothAdapter) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
mEventLoop = new BluetoothEventLoop(mContext, mAdapter, this);
}
@@ -312,8 +340,10 @@
break;
case MESSAGE_UUID_INTENT:
String address = (String)msg.obj;
- if (address != null)
+ if (address != null) {
sendUuidIntent(address);
+ makeServiceChannelCallbacks(address);
+ }
break;
case MESSAGE_DISCOVERABLE_TIMEOUT:
int mode = msg.arg1;
@@ -1064,14 +1094,35 @@
return uuids;
}
- public synchronized boolean fetchRemoteUuidsWithSdp(String address) {
+ /**
+ * Connect and fetch new UUID's using SDP.
+ * The UUID's found are broadcast as intents.
+ * Optionally takes a uuid and callback to fetch the RFCOMM channel for the
+ * a given uuid.
+ * TODO: Don't wait UUID_INTENT_DELAY to broadcast UUID intents on success
+ * TODO: Don't wait UUID_INTENT_DELAY to handle the failure case for
+ * callback and broadcast intents.
+ */
+ public synchronized boolean fetchRemoteUuids(String address, ParcelUuid uuid,
+ IBluetoothCallback callback) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
return false;
}
+ RemoteService service = new RemoteService(address, uuid);
+ if (uuid != null && mUuidCallbackTracker.get(service) != null) {
+ // An SDP query for this address & uuid is already in progress
+ // Do not add this callback for the uuid
+ return false;
+ }
+
if (mUuidIntentTracker.contains(address)) {
// An SDP query for this address is already in progress
+ // Add this uuid onto the in-progress SDP query
+ if (uuid != null) {
+ mUuidCallbackTracker.put(new RemoteService(address, uuid), callback);
+ }
return true;
}
@@ -1087,6 +1138,9 @@
}
mUuidIntentTracker.add(address);
+ if (uuid != null) {
+ mUuidCallbackTracker.put(new RemoteService(address, uuid), callback);
+ }
Message message = mHandler.obtainMessage(MESSAGE_UUID_INTENT);
message.obj = address;
@@ -1096,6 +1150,7 @@
/**
* Gets the rfcomm channel associated with the UUID.
+ * Pulls records from the cache only.
*
* @param address Address of the remote device
* @param uuid ParcelUuid of the service attribute
@@ -1201,20 +1256,67 @@
// We are storing the rfcomm channel numbers only for the uuids
// we are interested in.
int channel;
- ParcelUuid[] interestedUuids = {BluetoothUuid.Handsfree,
- BluetoothUuid.HSP,
- BluetoothUuid.ObexObjectPush};
+ if (DBG) log("updateDeviceServiceChannelCache(" + address + ")");
+
+ ArrayList<ParcelUuid> applicationUuids = new ArrayList();
+
+ synchronized (this) {
+ for (RemoteService service : mUuidCallbackTracker.keySet()) {
+ if (service.address.equals(address)) {
+ applicationUuids.add(service.uuid);
+ }
+ }
+ }
Map <ParcelUuid, Integer> value = new HashMap<ParcelUuid, Integer>();
- for (ParcelUuid uuid: interestedUuids) {
+
+ // Retrieve RFCOMM channel for default uuids
+ for (ParcelUuid uuid : RFCOMM_UUIDS) {
if (BluetoothUuid.isUuidPresent(deviceUuids, uuid)) {
- channel =
- getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid.toString(),
- 0x0004);
+ channel = getDeviceServiceChannelNative(getObjectPathFromAddress(address),
+ uuid.toString(), 0x0004);
+ if (DBG) log("\tuuid(system): " + uuid + " " + channel);
value.put(uuid, channel);
}
}
- mDeviceServiceChannelCache.put(address, value);
+ // Retrieve RFCOMM channel for application requested uuids
+ for (ParcelUuid uuid : applicationUuids) {
+ if (BluetoothUuid.isUuidPresent(deviceUuids, uuid)) {
+ channel = getDeviceServiceChannelNative(getObjectPathFromAddress(address),
+ uuid.toString(), 0x0004);
+ if (DBG) log("\tuuid(application): " + uuid + " " + channel);
+ value.put(uuid, channel);
+ }
+ }
+
+ synchronized (this) {
+ // Make application callbacks
+ for (Iterator<RemoteService> iter = mUuidCallbackTracker.keySet().iterator();
+ iter.hasNext();) {
+ RemoteService service = iter.next();
+ if (service.address.equals(address)) {
+ channel = -1;
+ if (value.get(service.uuid) != null) {
+ channel = value.get(service.uuid);
+ }
+ if (channel != -1) {
+ if (DBG) log("Making callback for " + service.uuid + " with result " +
+ channel);
+ IBluetoothCallback callback = mUuidCallbackTracker.get(service);
+ if (callback != null) {
+ try {
+ callback.onRfcommChannelFound(channel);
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ }
+
+ iter.remove();
+ }
+ }
+ }
+
+ // Update cache
+ mDeviceServiceChannelCache.put(address, value);
+ }
}
/**
@@ -1330,6 +1432,26 @@
if (mUuidIntentTracker.contains(address))
mUuidIntentTracker.remove(address);
+
+ }
+
+ /*package*/ synchronized void makeServiceChannelCallbacks(String address) {
+ for (Iterator<RemoteService> iter = mUuidCallbackTracker.keySet().iterator();
+ iter.hasNext();) {
+ RemoteService service = iter.next();
+ if (service.address.equals(address)) {
+ if (DBG) log("Cleaning up failed UUID channel lookup: " + service.address +
+ " " + service.uuid);
+ IBluetoothCallback callback = mUuidCallbackTracker.get(service);
+ if (callback != null) {
+ try {
+ callback.onRfcommChannelFound(-1);
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ }
+
+ iter.remove();
+ }
+ }
}
@Override
@@ -1377,6 +1499,11 @@
}
}
}
+ for (RemoteService service : mUuidCallbackTracker.keySet()) {
+ if (service.address.equals(address)) {
+ pw.println("\tPENDING CALLBACK: " + service.uuid);
+ }
+ }
}
String value = getProperty("Devices");
@@ -1508,7 +1635,7 @@
private native boolean setDevicePropertyBooleanNative(String objectPath, String key,
int value);
private native boolean createDeviceNative(String address);
- private native boolean discoverServicesNative(String objectPath, String pattern);
+ /*package*/ native boolean discoverServicesNative(String objectPath, String pattern);
private native int addRfcommServiceRecordNative(String name, long uuidMsb, long uuidLsb,
short channel);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7d821b5..4c91b6b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6188,11 +6188,12 @@
}
final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;
- final boolean opaque = drawingCacheBackgroundColor != 0 ||
- (mBGDrawable != null && mBGDrawable.getOpacity() == PixelFormat.OPAQUE);
+ final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque();
+ final boolean translucentWindow = attachInfo.mTranslucentWindow;
if (width <= 0 || height <= 0 ||
- (width * height * (opaque ? 2 : 4) > // Projected bitmap size in bytes
+ // Projected bitmap size in bytes
+ (width * height * (opaque && !translucentWindow ? 2 : 4) >
ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize())) {
destroyDrawingCache();
return;
@@ -6203,7 +6204,6 @@
(mUnscaledDrawingCache == null ? null : mUnscaledDrawingCache.get());
if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
-
Bitmap.Config quality;
if (!opaque) {
switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
@@ -6221,7 +6221,9 @@
break;
}
} else {
- quality = Bitmap.Config.RGB_565;
+ // Optimization for translucent windows
+ // If the window is translucent, use a 32 bits bitmap to benefit from memcpy()
+ quality = translucentWindow ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
}
// Try to cleanup memory
@@ -6235,6 +6237,7 @@
} else {
mUnscaledDrawingCache = new SoftReference<Bitmap>(bitmap);
}
+ if (opaque && translucentWindow) bitmap.setHasAlpha(false);
} catch (OutOfMemoryError e) {
// If there is not enough memory to create the bitmap cache, just
// ignore the issue as bitmap caches are not required to draw the
@@ -8821,6 +8824,11 @@
int mWindowTop;
/**
+ * Indicates whether the window is translucent/transparent
+ */
+ boolean mTranslucentWindow;
+
+ /**
* For windows that are full-screen but using insets to layout inside
* of the screen decorations, these are the current insets for the
* content of the window.
@@ -9033,8 +9041,8 @@
public ScrollabilityCache(ViewConfiguration configuration, View host) {
fadingEdgeLength = configuration.getScaledFadingEdgeLength();
scrollBarSize = configuration.getScaledScrollBarSize();
- scrollBarDefaultDelayBeforeFade = configuration.getScrollDefaultDelay();
- scrollBarFadeDuration = configuration.getScrollBarFadeDuration();
+ scrollBarDefaultDelayBeforeFade = ViewConfiguration.getScrollDefaultDelay();
+ scrollBarFadeDuration = ViewConfiguration.getScrollBarFadeDuration();
paint = new Paint();
matrix = new Matrix();
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index dba2e04..a6d644b 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -408,7 +408,7 @@
}
boolean restore = false;
- if (attrs != null && mTranslator != null) {
+ if (mTranslator != null) {
restore = true;
attrs.backup();
mTranslator.translateWindowLayout(attrs);
@@ -422,7 +422,7 @@
mSoftInputMode = attrs.softInputMode;
mWindowAttributesChanged = true;
mAttachInfo.mRootView = view;
- mAttachInfo.mScalingRequired = mTranslator == null ? false : true;
+ mAttachInfo.mScalingRequired = mTranslator != null;
mAttachInfo.mApplicationScale =
mTranslator == null ? 1.0f : mTranslator.applicationScale;
if (panelParentView != null) {
@@ -680,6 +680,7 @@
// object is not initialized to its backing store, but soon it
// will be (assuming the window is visible).
attachInfo.mSurface = mSurface;
+ attachInfo.mTranslucentWindow = lp.format != PixelFormat.OPAQUE;
attachInfo.mHasWindowFocus = false;
attachInfo.mWindowVisibility = viewVisibility;
attachInfo.mRecomputeGlobalAttributes = false;
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index 9e1f325..01f6dac 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -181,7 +181,7 @@
ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
final IBluetooth bluetooth =
IBluetooth.Stub.asInterface(ServiceManager.checkService(
- Context.BLUETOOTH_SERVICE));
+ BluetoothAdapter.BLUETOOTH_SERVICE));
try {
bluetoothOff = bluetooth == null ||
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index e37e832..62a50e5 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -36,6 +36,10 @@
namespace android {
+#define CREATE_DEVICE_ALREADY_EXISTS 1
+#define CREATE_DEVICE_SUCCESS 0
+#define CREATE_DEVICE_FAILED -1
+
#ifdef HAVE_BLUETOOTH
static jfieldID field_mNativeData;
@@ -95,7 +99,7 @@
method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult",
"(Ljava/lang/String;I)V");
method_onCreateDeviceResult = env->GetMethodID(clazz, "onCreateDeviceResult",
- "(Ljava/lang/String;Z)V");
+ "(Ljava/lang/String;I)V");
method_onDiscoverServicesResult = env->GetMethodID(clazz, "onDiscoverServicesResult",
"(Ljava/lang/String;Z)V");
@@ -1115,10 +1119,13 @@
LOGV("... Address = %s", address);
- bool result = JNI_TRUE;
+ jint result = CREATE_DEVICE_SUCCESS;
if (dbus_set_error_from_message(&err, msg)) {
+ if (dbus_error_has_name(&err, "org.bluez.Error.AlreadyExists")) {
+ result = CREATE_DEVICE_ALREADY_EXISTS;
+ }
LOG_AND_FREE_DBUS_ERROR(&err);
- result = JNI_FALSE;
+ result = CREATE_DEVICE_FAILED;
}
env->CallVoidMethod(nat->me,
method_onCreateDeviceResult,
diff --git a/core/res/res/values-en-rUS/donottranslate-names.xml b/core/res/res/values-en-rUS/donottranslate-names.xml
index 82ba310..ae38ddf 100644
--- a/core/res/res/values-en-rUS/donottranslate-names.xml
+++ b/core/res/res/values-en-rUS/donottranslate-names.xml
@@ -4,31 +4,39 @@
<!-- various string resources for Contacts -->
<string-array name="common_nicknames">
+ <item>Abigail, Abbie, Gail, Gayle</item>
+ <item>Abe, Abraham</item>
+ <item>Aggie, Agatha, Agnes</item>
<item>Albert, Al, Bert, Bertie</item>
- <item>Alexander, Al, Alex, Lex, Sasha</item>
- <item>Alexandra, Al, Alex, Allie, Ally, Lex, Lexie, Sandra, Sandy, Sasha</item>
+ <item>Alexander, Al, Alec, Alex, Lex, Sasha</item>
+ <item>Alexandra, Al, Allie, Ally, Lex, Lexie, Sandra, Sandy, Sasha</item>
+ <item>Alf, Alfred, Alfredo, Alfie</item>
<item>Alice, Allie, Ally</item>
<item>Alison, Allie, Ally</item>
<item>Allison, Allie, Ally</item>
<item>Amanda, Mandi, Mandy</item>
<item>Andrea, Andie</item>
<item>Andrew, Andy, Drew</item>
+ <item>Anne, Annie, Annette</item>
<item>Anthony, Tony, Toni, Tone</item>
<item>Arthur, Art, Arty</item>
<item>Barbara, Babs, Barb, Barbie</item>
<item>Benjamin, Ben, Benji, Benny</item>
- <item>Bernard, Bern, Bernie</item>
+ <item>Bernard, Bern, Bernie, Barnie</item>
<item>Bertram, Bert, Bertie</item>
<item>Bradly, Brad</item>
+ <item>Calvin, Cal</item>
<item>Catherine, Cat, Cate, Cath, Catie, Cathy, Kat, Kate, Katie, Kathy</item>
+ <item>Carrie, Caroline, Carolyn</item>
<item>Charles, Chuck, Chaz, Charlie, Buck</item>
- <item>Christine, Chris, Chrissy, Chrissie</item>
+ <item>Christine, Chrissy, Chrissie</item>
<item>Christopher, Chris</item>
+ <item>Clinton, Clint</item>
<item>Cynthia, Cindy, Cynth</item>
<item>Daniel, Dan, Danny</item>
<item>David, Dave</item>
<item>Deborah, Deb, Debbie</item>
- <item>Dennis, Den, Denny, Dean</item>
+ <item>Dennis, Den, Denny</item>
<item>Dolores, Dolly</item>
<item>Donald, Don, Donny</item>
<item>Donnatella, Donna</item>
@@ -41,22 +49,21 @@
<item>Elizabeth, Beth, Bess, Bessie, Betsy, Betty, Bette, Eliza, Lisa, Liza, Liz</item>
<item>Emily, Em, Ems, Emmy</item>
<item>Emma, Em, Ems, Emmy</item>
- <item>Erica, Rikki, Rikkie, Ricky</item>
<item>Eugene, Gene</item>
+ <item>Fannie, Fanny</item>
<item>Florence, Flo</item>
<item>Frances, Fran, Francie</item>
- <item>Francis, Fran, Frank</item>
+ <item>Francis, Fran, Frank, Frankie</item>
<item>Frederick, Fred, Freddy</item>
<item>Gabriel, Gabe</item>
- <item>Geoffrey, Jeff</item>
<item>Gerald, Gerry</item>
<item>Gerard, Gerry</item>
- <item>Gregory, Greg</item>
- <item>Harold, Hal, Hank, Harry</item>
+ <item>Gregory, Greg, Gregg</item>
+ <item>Harold, Hal, Harry</item>
<item>Henry, Hal, Hank, Harry</item>
<item>Herbert, Bert, Bertie</item>
<item>Irving, Irv</item>
- <item>Isabella, Isa, Izzy</item>
+ <item>Isabella, Isa, Izzy, Bella</item>
<item>Jacob, Jake</item>
<item>Jacqueline, Jackie</item>
<item>James, Jim, Jimmy, Jamie, Jock</item>
@@ -68,8 +75,9 @@
<item>Jennifer, Jen, Jenny</item>
<item>Jerome, Jerry</item>
<item>Jessica, Jessie</item>
- <item>John, Jack, Jacky, Johnny, Jon</item>
- <item>Jonathan, Jon, John</item>
+ <item>John, Johnny, Jon</item>
+ <item>Jack, Jacky</item>
+ <item>Jonathan, Jon</item>
<item>Joseph, Joe, Joey</item>
<item>Joshua, Josh</item>
<item>Kaitlyn, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
@@ -78,17 +86,20 @@
<item>Katrina, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
<item>Kenneth, Ken</item>
<item>Kevin, Kev</item>
+ <item>Kim, Kimberly</item>
<item>Laura, Lauri, Laurie</item>
<item>Lauren, Lauri, Laurie</item>
- <item>Laurence, Larry, Lauri, Laurie</item>
- <item>Lawrence, Larry, Lauri, Laurie</item>
+ <item>Lawrence, Larry</item>
<item>Leonard, Leo, Len, Lenny</item>
<item>Leopold, Leo, Len, Lenny</item>
<item>Madeline, Maddie, Maddy</item>
- <item>Margaret, Marge, Marg, Maggie, Mags, Meg, Peggy</item>
+ <item>Margaret, Marge, Marg, Maggie, Mags, Meg, Peggy, Greta, Gretchen</item>
+ <item>Martin, Martie, Marty</item>
<item>Matthew, Matt, Mattie</item>
<item>Maureen, Mo</item>
<item>Maurice, Mo</item>
+ <item>Maxwell, Max</item>
+ <item>Maximilian, Maxim, Max</item>
<item>Megan, Meg</item>
<item>Michael, Mickey, Mick, Mike, Mikey</item>
<item>Morris, Mo</item>
@@ -96,16 +107,17 @@
<item>Nathan, Nat, Nate</item>
<item>Nathaniel, Nat, Nate</item>
<item>Nicholas, Nick</item>
+ <item>Nicole, Nicky, Nickie, Nikky</item>
<item>Pamela, Pam</item>
<item>Patricia, Pat, Patsy, Patty, Trish, Tricia</item>
- <item>Patrick, Paddy, Pat, Patty, Patter, Rick, Ricky</item>
+ <item>Patrick, Pat, Patter</item>
+ <item>Penelope, Penny</item>
<item>Peter, Pete</item>
<item>Raymond, Ray</item>
<item>Philip, Phil</item>
- <item>Rebecca, Becca</item>
+ <item>Rebecca, Becca, Becky</item>
<item>Richard, Rick, Rich, Dick</item>
<item>Robert, Bob, Rob, Robbie, Bobby, Rab</item>
- <item>Roberta, Bobbie</item>
<item>Rodney. Rod</item>
<item>Ronald, Ron, Ronnie</item>
<item>Rosemary, Rosie, Rose</item>
@@ -120,7 +132,8 @@
<item>Stuart, Stu</item>
<item>Susan, Sue, Susie, Suzie</item>
<item>Suzanne, Sue, Susie, Suzie</item>
- <item>Teresa, Terrie, Terry</item>
+ <item>Tamara, Tammy</item>
+ <item>Theresa, Teresa</item>
<item>Theodora, Teddie, Thea, Theo</item>
<item>Theodore, Ted, Teddy, Theo</item>
<item>Thomas, Tom, Thom, Tommy</item>
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e5c6010..b8cf844 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -23,6 +23,7 @@
import dalvik.system.VMRuntime;
import android.app.ActivityManagerNative;
+import android.bluetooth.BluetoothAdapter;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentService;
@@ -172,14 +173,14 @@
// support Bluetooth - see bug 988521
if (SystemProperties.get("ro.kernel.qemu").equals("1")) {
Log.i(TAG, "Registering null Bluetooth Service (emulator)");
- ServiceManager.addService(Context.BLUETOOTH_SERVICE, null);
+ ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, null);
} else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
Log.i(TAG, "Registering null Bluetooth Service (factory test)");
- ServiceManager.addService(Context.BLUETOOTH_SERVICE, null);
+ ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, null);
} else {
Log.i(TAG, "Bluetooth Service");
bluetooth = new BluetoothService(context);
- ServiceManager.addService(Context.BLUETOOTH_SERVICE, bluetooth);
+ ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, bluetooth);
bluetooth.initAfterRegistration();
bluetoothA2dp = new BluetoothA2dpService(context, bluetooth);
ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index cf63d02..801a938 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -448,8 +448,7 @@
mBluetoothData = IconData.makeIcon("bluetooth",
null, com.android.internal.R.drawable.stat_sys_data_bluetooth, 0, 0);
mBluetoothIcon = service.addIcon(mBluetoothData, null);
- BluetoothAdapter adapter =
- (BluetoothAdapter) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
mBluetoothEnabled = adapter.isEnabled();
} else {