Merge change 24283 into eclair

* changes:
  CameraService change for OVERLAY_FORMAT_DEFAULT
diff --git a/api/current.xml b/api/current.xml
index 2d13363..fa9ab93 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -25457,6 +25457,50 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<method name="disable"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="enable"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getAddress"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getName"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getRemoteDevice"
  return="android.bluetooth.BluetoothDevice"
  abstract="false"
@@ -25470,6 +25514,39 @@
 <parameter name="address" type="java.lang.String">
 </parameter>
 </method>
+<method name="getScanMode"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getState"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="listenUsingRfcommOn"
  return="android.bluetooth.BluetoothServerSocket"
  abstract="false"
@@ -25485,6 +25562,186 @@
 <exception name="IOException" type="java.io.IOException">
 </exception>
 </method>
+<method name="setName"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+</method>
+<method name="setScanMode"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mode" type="int">
+</parameter>
+</method>
+<field name="ACTION_SCAN_MODE_CHANGED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.intent.action.SCAN_MODE_CHANGED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_STATE_CHANGED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.intent.action.STATE_CHANGED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_PREVIOUS_SCAN_MODE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.intent.extra.PREVIOUS_SCAN_MODE&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_PREVIOUS_STATE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.intent.extra.PREVIOUS_STATE&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_SCAN_MODE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.intent.extra.SCAN_MODE&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_STATE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.intent.extra.STATE&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCAN_MODE_CONNECTABLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="51"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCAN_MODE_CONNECTABLE_DISCOVERABLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="53"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCAN_MODE_NONE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="50"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATE_OFF"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="40"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATE_ON"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="42"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATE_TURNING_OFF"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="43"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATE_TURNING_ON"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="41"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="BluetoothDevice"
  extends="java.lang.Object"
@@ -25533,6 +25790,17 @@
  visibility="public"
 >
 </method>
+<method name="getName"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="writeToParcel"
  return="void"
  abstract="false"
@@ -25548,6 +25816,17 @@
 <parameter name="flags" type="int">
 </parameter>
 </method>
+<field name="ERROR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="BluetoothServerSocket"
  extends="java.lang.Object"
@@ -78336,6 +78615,19 @@
 <method name="startTone"
  return="boolean"
  abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="toneType" type="int">
+</parameter>
+</method>
+<method name="startTone"
+ return="boolean"
+ abstract="false"
  native="true"
  synchronized="false"
  static="false"
@@ -78345,6 +78637,8 @@
 >
 <parameter name="toneType" type="int">
 </parameter>
+<parameter name="durationMs" type="int">
+</parameter>
 </method>
 <method name="stopTone"
  return="void"
diff --git a/cmds/keystore/certtool.h b/cmds/keystore/certtool.h
index aefad66..9b72bf7 100644
--- a/cmds/keystore/certtool.h
+++ b/cmds/keystore/certtool.h
@@ -38,9 +38,9 @@
     int count, fd, ret = -1;
     LPC_MARSHAL cmd;
     char delimiter[] = "_";
-    char *namespace, *keyname;
+    char *p = NULL;
     char *context = NULL;
-    char cname[CERT_NAME_LEN];
+    char *cname = (char*)cmd.data;
 
     if ((certname == NULL) || (value == NULL)) {
         LOGE("get_cert: certname or value is null\n");
@@ -61,12 +61,10 @@
     }
 
     cmd.opcode = GET;
-    if (((namespace = strtok_r(cname, delimiter, &context)) == NULL) ||
-        ((keyname = strtok_r(NULL, delimiter, &context)) == NULL)) {
-        goto err;
-    }
-    if ((cmd.len = snprintf((char*)cmd.data, BUFFER_MAX, "%s %s", namespace, keyname))
-        > (2 * MAX_KEY_NAME_LENGTH + 1)) goto err;
+    p = strstr(cname, delimiter);
+    cmd.len = strlen(certname) + 1;
+    if (p == NULL) goto err;
+    *p = 0; // replace the delimiter with \0 .
 
     if (write_marshal(fd, &cmd)) {
         LOGE("Incorrect command or command line is too long.\n");
diff --git a/cmds/keystore/keymgmt.c b/cmds/keystore/keymgmt.c
index 9a1f845..69e0380 100644
--- a/cmds/keystore/keymgmt.c
+++ b/cmds/keystore/keymgmt.c
@@ -192,21 +192,15 @@
     return ret;
 }
 
-static int change_passwd(char *data)
+int change_passwd(char *old_pass, char *new_pass)
 {
     unsigned char master_key[USER_KEY_LEN];
-    char *old_pass, *new_pass = NULL, *p, *delimiter=" ";
-    int ret, count = 0;
-    char *context = NULL;
+    int ret;
 
-    old_pass = p = strtok_r(data, delimiter, &context);
-    while (p != NULL) {
-        count++;
-        new_pass = p;
-        p = strtok_r(NULL, delimiter, &context);
-    }
-    if (count != 2) return -1;
-    if (strlen(new_pass) < MIN_PASSWD_LENGTH) return -1;
+    if (state == UNINITIALIZED) return -1;
+    if ((strlen(old_pass) < MIN_PASSWD_LENGTH) ||
+        (strlen(new_pass) < MIN_PASSWD_LENGTH)) return -1;
+
     if ((ret = get_master_key(old_pass, master_key)) == 0) {
         ret = store_master_key(new_pass, master_key);
         retry_count = 0;
@@ -336,14 +330,12 @@
     return 0;
 }
 
-int passwd(char *data)
+int new_passwd(char *password)
 {
-    if (state == UNINITIALIZED) {
-        if (strchr(data, ' ')) return -1;
-        if (strlen(data) < MIN_PASSWD_LENGTH) return -1;
-        return create_master_key(data);
-    }
-    return change_passwd(data);
+    int passwdlen = strlen(password);
+
+    if ((state != UNINITIALIZED) || (passwdlen < MIN_PASSWD_LENGTH)) return -1;
+    return create_master_key(password);
 }
 
 int lock()
diff --git a/cmds/keystore/keymgmt.h b/cmds/keystore/keymgmt.h
index 0e928db..116d7a3 100644
--- a/cmds/keystore/keymgmt.h
+++ b/cmds/keystore/keymgmt.h
@@ -72,7 +72,8 @@
             unsigned char *data, int *size);
 int remove_key(const char *namespace, const char *keyname);
 int list_keys(const char *namespace, char reply[BUFFER_MAX]);
-int passwd(char *data);
+int new_passwd(char *password);
+int change_passwd(char *old_pass, char *new_pass);
 int lock();
 int unlock(char *passwd);
 KEYSTORE_STATE get_state();
diff --git a/cmds/keystore/netkeystore.c b/cmds/keystore/netkeystore.c
index bdd5960..82a92c3 100644
--- a/cmds/keystore/netkeystore.c
+++ b/cmds/keystore/netkeystore.c
@@ -85,28 +85,44 @@
     return -1;
 }
 
-static int parse_keyname(char *name, uint32_t len,
-                         char *namespace, char *keyname)
+/**
+ * The function parse_strings() only handle two or three tokens just for
+ * keystore's need.
+ */
+static int parse_strings(char *data, int data_len, int ntokens, ...)
 {
     int count = 0;
-    char *c = namespace, *p = namespace, *t = name;
+    va_list args;
+    char *p = data, **q;
 
-    if (!name || !namespace || !keyname) return -1;
-    while (t < name + len && (*t != 0)) {
-        if (*t == ' ') {
-            if (c == keyname) return -1;
-            *p = count = 0;
-            c = p = keyname;
-            t++;
-        } else {
-            if (!isalnum(*t)) return -1;
-            *p++ = *t++;
-            // also check if the keyname/namespace is too long.
-            if (count++ == MAX_KEY_NAME_LENGTH) return -1;
+    va_start(args, ntokens);
+    q = va_arg(args, char**);
+    *q = p;
+    while (p < (data + data_len)) {
+        if (*(p++) == 0) {
+            if (++count == ntokens) break;
+            if ((q = va_arg(args, char**)) == NULL) break;
+            *q = p;
         }
     }
-    *p = 0;
-    return 0;
+    va_end(args);
+    // the first two strings should be null-terminated and the third could
+    // ignore the delimiter.
+    if (count >= 2) {
+        if ((ntokens == 3) || ((ntokens == 2) && (p == (data + data_len)))) {
+            return 0;
+        }
+    }
+    return -1;
+}
+
+static int is_alnum_string(char *s)
+{
+    while (*s != 0) {
+        if (!isalnum(*s++)) return 0;
+    }
+    LOGE("The string %s is not an alphanumeric string\n", s);
+    return 1;
 }
 
 // args of passwd():
@@ -114,7 +130,17 @@
 // oldPassword newPassword - for changing the password
 static void do_passwd(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
 {
-    reply->retcode = passwd((char*)cmd->data);
+    char *p1 = NULL, *p2 = NULL;
+
+    if (strlen((char*)cmd->data) == (cmd->len - 1)) {
+        reply->retcode = new_passwd((char*)cmd->data);
+    } else {
+        if (parse_strings((char *)cmd->data, cmd->len, 2, &p1, &p2) != 0) {
+            reply->retcode = -1;
+        } else {
+            reply->retcode = change_passwd(p1, p2);
+        }
+    }
 }
 
 // args of lock():
@@ -150,8 +176,7 @@
 // namespace keyname
 static void do_get_key(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
 {
-    char namespace[MAX_KEY_NAME_LENGTH];
-    char keyname[MAX_KEY_NAME_LENGTH];
+    char *namespace = NULL, *keyname = NULL;
 
     if (check_get_perm(cr.uid)) {
         LOGE("uid %d doesn't have the permission to get key value\n", cr.uid);
@@ -159,7 +184,8 @@
         return;
     }
 
-    if (parse_keyname((char*)cmd->data, cmd->len, namespace, keyname)) {
+    if (parse_strings((char*)cmd->data, cmd->len, 2, &namespace, &keyname) ||
+        !is_alnum_string(namespace) || !is_alnum_string(keyname)) {
         reply->retcode = -1;
     } else {
         reply->retcode = get_key(namespace, keyname, reply->data,
@@ -182,31 +208,26 @@
 // namespace keyname keyvalue
 static void do_put_key(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
 {
-    char namespace[MAX_KEY_NAME_LENGTH];
-    char keyname[MAX_KEY_NAME_LENGTH];
+    char *namespace = NULL, *keyname = NULL;
+    char *value = NULL;
 
-    int p = get_value_index(cmd);
-    if (p == -1) {
+    if (parse_strings((char*)cmd->data, cmd->len, 3, &namespace, &keyname, &value) ||
+        !is_alnum_string(namespace) || !is_alnum_string(keyname)) {
         reply->retcode = -1;
-    } else {
-        unsigned char *value;
-        if (parse_keyname((char*)cmd->data, p - 1, namespace, keyname)) {
-            reply->retcode = -1;
-            return;
-        }
-        value = &cmd->data[p];
-        int len = cmd->len - p;
-        reply->retcode = put_key(namespace, keyname, value, len);
+        return;
     }
+    int len = cmd->len - (value - namespace);
+    reply->retcode = put_key(namespace, keyname, (unsigned char *)value, len);
 }
 
 // args of remove_key():
 // namespace keyname
 static void do_remove_key(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
 {
-    char namespace[MAX_KEY_NAME_LENGTH];
-    char keyname[MAX_KEY_NAME_LENGTH];
-    if (parse_keyname((char*)cmd->data, cmd->len, namespace, keyname)) {
+    char *namespace = NULL, *keyname = NULL;
+
+    if (parse_strings((char*)cmd->data, cmd->len, 2, &namespace, &keyname) ||
+        !is_alnum_string(namespace) || !is_alnum_string(keyname)) {
         reply->retcode = -1;
         return;
     }
@@ -260,8 +281,6 @@
         fprintf(stderr, "Can not open file %s\n", filename);
         return -1;
     }
-    cmd->data[cmd->len] = ' ';
-    cmd->len++;
     len = read(fd, cmd->data + cmd->len, BUFFER_MAX - cmd->len);
     if (len < 0 || (len == (int)(BUFFER_MAX - cmd->len))) {
         ret = -1;
@@ -278,14 +297,15 @@
     char *buf = (char*)cmd->data;
     buf[0] = 0;
     for (i = 0 ; i < argc ; ++i) {
+        // we also include the \0 character in the input.
         if (i == 0) {
-            len = strlcpy(buf, argv[i], BUFFER_MAX);
+            len = (strlcpy(buf, argv[i], BUFFER_MAX) + 1);
         } else {
-            len += snprintf(buf + len, BUFFER_MAX - len, " %s", argv[i]);
+            len += (snprintf(buf + len, BUFFER_MAX - len, "%s", argv[i]) + 1);
         }
         if (len >= BUFFER_MAX) return -1;
     }
-    if (len) cmd->len = len;
+    if (len) cmd->len = len ;
     return 0;
 }
 
diff --git a/cmds/keystore/tests/netkeystore_test.c b/cmds/keystore/tests/netkeystore_test.c
index e7e686b..00390e0 100644
--- a/cmds/keystore/tests/netkeystore_test.c
+++ b/cmds/keystore/tests/netkeystore_test.c
@@ -43,7 +43,7 @@
 #define FUNC_BODY(x) int test_##x()
 
 #define TEST_PASSWD        "12345678"
-#define TEST_NPASSWD    "11111111"
+#define TEST_NPASSWD    "hello world"
 #define TEST_DIR        "/data/local/tmp/keystore"
 #define READONLY_DIR    "/proc/keystore"
 #define TEST_NAMESPACE    "test"
@@ -83,7 +83,7 @@
 FUNC_BODY(get_state)
 {
     if (get_state() != UNINITIALIZED) return -1;
-    passwd(TEST_PASSWD);
+    new_passwd(TEST_PASSWD);
     if (get_state() != UNLOCKED) return -1;
     lock();
     if (get_state() != LOCKED) return -1;
@@ -96,19 +96,17 @@
 {
     char buf[512];
 
-    if (passwd(" 23432dsfsdf") == 0) return -1;
-    if (passwd("dsfsdf") == 0) return -1;
-    passwd(TEST_PASSWD);
+    if (new_passwd("2d fsdf") == 0) return -1;
+    if (new_passwd("dsfsdf") == 0) return -1;
+    new_passwd(TEST_PASSWD);
     lock();
     if (unlock("55555555") == 0) return -1;
     if (unlock(TEST_PASSWD) != 0) return -1;
 
     // change the password
-    sprintf(buf, "%s %s", "klfdjdsklfjg", "abcdefghi");
-    if (passwd(buf) == 0) return -1;
+    if (change_passwd("klfdjdsklfjg", "abcdefghi") == 0) return -1;
 
-    sprintf(buf, "%s %s", TEST_PASSWD, TEST_NPASSWD);
-    if (passwd(buf) != 0) return -1;
+    if (change_passwd(TEST_PASSWD, TEST_NPASSWD) != 0) return -1;
     lock();
 
     if (unlock(TEST_PASSWD) == 0) return -1;
@@ -120,7 +118,7 @@
 FUNC_BODY(lock)
 {
     if (lock() == 0) return -1;
-    passwd(TEST_PASSWD);
+    new_passwd(TEST_PASSWD);
     if (lock() != 0) return -1;
     if (lock() != 0) return -1;
     return EXIT_SUCCESS;
@@ -129,7 +127,7 @@
 FUNC_BODY(unlock)
 {
     int i = MAX_RETRY_COUNT;
-    passwd(TEST_PASSWD);
+    new_passwd(TEST_PASSWD);
     lock();
     while (i > 1) {
         if (unlock(TEST_NPASSWD) != --i) return -1;
@@ -145,7 +143,7 @@
 
     if (put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
                 strlen(TEST_KEYVALUE)) == 0) return -1;
-    passwd(TEST_PASSWD);
+    new_passwd(TEST_PASSWD);
     if (put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
                 strlen(TEST_KEYVALUE)) != 0) return -1;
 
@@ -165,7 +163,7 @@
 
     if (get_key(TEST_NAMESPACE, TEST_KEYNAME, data, &size) == 0) return -1;
 
-    passwd(TEST_PASSWD);
+    new_passwd(TEST_PASSWD);
     put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
             strlen(TEST_KEYVALUE));
     if (get_key(TEST_NAMESPACE, TEST_KEYNAME, data, &size) != 0) return -1;
@@ -178,7 +176,7 @@
 {
     if (remove_key(TEST_NAMESPACE, TEST_KEYNAME) == 0) return -1;
 
-    passwd(TEST_PASSWD);
+    new_passwd(TEST_PASSWD);
     if (remove_key(TEST_NAMESPACE, TEST_KEYNAME) == 0) return -1;
 
     put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
@@ -199,7 +197,7 @@
 
     if (list_keys(TEST_NAMESPACE, reply) == 0) return -1;
 
-    passwd(TEST_PASSWD);
+    new_passwd(TEST_PASSWD);
     if (list_keys(buf, reply) == 0) return -1;
 
     if (list_keys(TEST_NAMESPACE, reply) != 0) return -1;
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index 81a1c0a..4751580 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -228,7 +228,7 @@
 #endif
 
     sp<MetaData> encMeta = new MetaData;
-    encMeta->setCString(kKeyMIMEType, 1 ? "audio/3gpp" : "audio/mp4a-latm");
+    encMeta->setCString(kKeyMIMEType, 1 ? "audio/amr-wb" : "audio/mp4a-latm");
     encMeta->setInt32(kKeySampleRate, kSampleRate);
     encMeta->setInt32(kKeyChannelCount, kNumChannels);
     encMeta->setInt32(kKeyMaxInputSize, 8192);
@@ -248,7 +248,7 @@
         buffer->release();
         buffer = NULL;
 
-        if (++n == 10000) {
+        if (++n == 100) {
             break;
         }
     }
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index b531a50..060f20e 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -42,9 +42,6 @@
  *
  * Currently the BluetoothA2dp service runs in the system server and this
  * proxy object will be immediately bound to the service on construction.
- * However this may change in future releases, and error codes such as
- * BluetoothError.ERROR_IPC_NOT_READY will be returned from this API when the
- * proxy object is not yet attached.
  * 
  * Currently this class provides methods to connect to A2DP audio sinks.
  *
@@ -105,16 +102,16 @@
      *  Listen for SINK_STATE_CHANGED_ACTION to find out when the
      *  connection is completed.
      *  @param device Remote BT device.
-     *  @return Result code, negative indicates an immediate error.
+     *  @return false on immediate error, true otherwise
      *  @hide
      */
-    public int connectSink(BluetoothDevice device) {
+    public boolean connectSink(BluetoothDevice device) {
         if (DBG) log("connectSink(" + device + ")");
         try {
             return mService.connectSink(device);
         } catch (RemoteException e) {
-            Log.w(TAG, "", e);
-            return BluetoothError.ERROR_IPC;
+            Log.e(TAG, "", e);
+            return false;
         }
     }
 
@@ -122,16 +119,16 @@
      *  Listen for SINK_STATE_CHANGED_ACTION to find out when
      *  disconnect is completed.
      *  @param device Remote BT device.
-     *  @return Result code, negative indicates an immediate error.
+     *  @return false on immediate error, true otherwise
      *  @hide
      */
-    public int disconnectSink(BluetoothDevice device) {
+    public boolean disconnectSink(BluetoothDevice device) {
         if (DBG) log("disconnectSink(" + device + ")");
         try {
             return mService.disconnectSink(device);
         } catch (RemoteException e) {
-            Log.w(TAG, "", e);
-            return BluetoothError.ERROR_IPC;
+            Log.e(TAG, "", e);
+            return false;
         }
     }
 
@@ -156,14 +153,14 @@
             return Collections.unmodifiableSet(
                     new HashSet<BluetoothDevice>(Arrays.asList(mService.getConnectedSinks())));
         } catch (RemoteException e) {
-            Log.w(TAG, "", e);
+            Log.e(TAG, "", e);
             return null;
         }
     }
 
     /** Get the state of an A2DP sink
      *  @param device Remote BT device.
-     *  @return State code, or negative on error
+     *  @return State code, one of STATE_
      *  @hide
      */
     public int getSinkState(BluetoothDevice device) {
@@ -171,8 +168,8 @@
         try {
             return mService.getSinkState(device);
         } catch (RemoteException e) {
-            Log.w(TAG, "", e);
-            return BluetoothError.ERROR_IPC;
+            Log.e(TAG, "", e);
+            return BluetoothA2dp.STATE_DISCONNECTED;
         }
     }
 
@@ -186,15 +183,15 @@
      * @param device Paired sink
      * @param priority Integer priority, for example PRIORITY_AUTO or
      *                 PRIORITY_NONE
-     * @return Result code, negative indicates an error
+     * @return true if priority is set, false on error
      */
-    public int setSinkPriority(BluetoothDevice device, int priority) {
+    public boolean setSinkPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setSinkPriority(" + device + ", " + priority + ")");
         try {
             return mService.setSinkPriority(device, priority);
         } catch (RemoteException e) {
-            Log.w(TAG, "", e);
-            return BluetoothError.ERROR_IPC;
+            Log.e(TAG, "", e);
+            return false;
         }
     }
 
@@ -208,8 +205,8 @@
         try {
             return mService.getSinkPriority(device);
         } catch (RemoteException e) {
-            Log.w(TAG, "", e);
-            return BluetoothError.ERROR_IPC;
+            Log.e(TAG, "", e);
+            return PRIORITY_OFF;
         }
     }
 
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 5a182f0..18f6995 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -16,6 +16,8 @@
 
 package android.bluetooth;
 
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -40,32 +42,118 @@
 public final class BluetoothAdapter {
     private static final String TAG = "BluetoothAdapter";
 
-    /** @hide */
-    public static final int BLUETOOTH_STATE_OFF = 0;
-    /** @hide */
-    public static final int BLUETOOTH_STATE_TURNING_ON = 1;
-    /** @hide */
-    public static final int BLUETOOTH_STATE_ON = 2;
-    /** @hide */
-    public static final int BLUETOOTH_STATE_TURNING_OFF = 3;
+    /**
+     * Sentinel error value for this class. Guaranteed to not equal any other
+     * integer constant in this class. Provided as a convenience for functions
+     * that require a sentinel error value, for example:
+     * <p><code>Intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+     * BluetoothAdapter.ERROR)</code>
+     */
+    public static final int ERROR = -1;
 
-    /** Inquiry scan and page scan are both off.
-     *  Device is neither discoverable nor connectable
-     *  @hide */
-    public static final int SCAN_MODE_NONE = 0;
-    /** Page scan is on, inquiry scan is off.
-     *  Device is connectable, but not discoverable
-     *  @hide*/
-    public static final int SCAN_MODE_CONNECTABLE = 1;
-    /** Page scan and inquiry scan are on.
-     *  Device is connectable and discoverable
-     *  @hide*/
-    public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 3;
+    /**
+     * Broadcast Action: The state of the local Bluetooth adapter has been
+     * changed.
+     * <p>For example, Bluetooth has been turned on or off.
+     * <p>Contains the extra fields {@link #EXTRA_STATE} and {@link
+     * #EXTRA_PREVIOUS_STATE} containing the new and old states
+     * respectively.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_STATE_CHANGED =
+            "android.bluetooth.intent.action.STATE_CHANGED";
 
-    /** @hide */
-    public static final int RESULT_FAILURE = -1;
-    /** @hide */
-    public static final int RESULT_SUCCESS = 0;
+    /**
+     * Used as an int extra field in {@link #ACTION_STATE_CHANGED}
+     * intents to request the current power state. Possible values are:
+     * {@link #STATE_OFF},
+     * {@link #STATE_TURNING_ON},
+     * {@link #STATE_ON},
+     * {@link #STATE_TURNING_OFF},
+     */
+    public static final String EXTRA_STATE =
+            "android.bluetooth.intent.extra.STATE";
+    /**
+     * Used as an int extra field in {@link #ACTION_STATE_CHANGED}
+     * intents to request the previous power state. Possible values are:
+     * {@link #STATE_OFF},
+     * {@link #STATE_TURNING_ON},
+     * {@link #STATE_ON},
+     * {@link #STATE_TURNING_OFF},
+     */
+    public static final String EXTRA_PREVIOUS_STATE =
+            "android.bluetooth.intent.extra.PREVIOUS_STATE";
+
+    /**
+     * Indicates the local Bluetooth adapter is off.
+     */
+    public static final int STATE_OFF = 40;
+    /**
+     * Indicates the local Bluetooth adapter is turning on. However local
+     * clients should wait for {@link #STATE_ON} before attempting to
+     * use the adapter.
+     */
+    public static final int STATE_TURNING_ON = 41;
+    /**
+     * Indicates the local Bluetooth adapter is on, and ready for use.
+     */
+    public static final int STATE_ON = 42;
+    /**
+     * Indicates the local Bluetooth adapter is turning off. Local clients
+     * should immediately attempt graceful disconnection of any remote links.
+     */
+    public static final int STATE_TURNING_OFF = 43;
+
+    /**
+     * Broadcast Action: Indicates the Bluetooth scan mode of the local Adapter
+     * has changed.
+     * <p>Contains the extra fields {@link #EXTRA_SCAN_MODE} and {@link
+     * #EXTRA_PREVIOUS_SCAN_MODE} containing the new and old scan modes
+     * respectively.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_SCAN_MODE_CHANGED =
+            "android.bluetooth.intent.action.SCAN_MODE_CHANGED";
+
+    /**
+     * Used as an int extra field in {@link #ACTION_SCAN_MODE_CHANGED}
+     * intents to request the current scan mode. Possible values are:
+     * {@link #SCAN_MODE_NONE},
+     * {@link #SCAN_MODE_CONNECTABLE},
+     * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE},
+     */
+    public static final String EXTRA_SCAN_MODE = "android.bluetooth.intent.extra.SCAN_MODE";
+    /**
+     * Used as an int extra field in {@link #ACTION_SCAN_MODE_CHANGED}
+     * intents to request the previous scan mode. Possible values are:
+     * {@link #SCAN_MODE_NONE},
+     * {@link #SCAN_MODE_CONNECTABLE},
+     * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE},
+     */
+    public static final String EXTRA_PREVIOUS_SCAN_MODE =
+            "android.bluetooth.intent.extra.PREVIOUS_SCAN_MODE";
+
+    /**
+     * Indicates that both inquiry scan and page scan are disabled on the local
+     * Bluetooth adapter. Therefore this device is neither discoverable
+     * nor connectable from remote Bluetooth devices.
+     */
+    public static final int SCAN_MODE_NONE = 50;
+    /**
+     * Indicates that inquiry scan is disabled, but page scan is enabled on the
+     * local Bluetooth adapter. Therefore this device is not discoverable from
+     * remote Bluetooth devices, but is connectable from remote devices that
+     * have previously discovered this device.
+     */
+    public static final int SCAN_MODE_CONNECTABLE = 51;
+    /**
+     * Indicates that both inquiry scan and page scan are enabled on the local
+     * Bluetooth adapter. Therefore this device is both discoverable and
+     * connectable from remote Bluetooth devices.
+     */
+    public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 53;
 
     /** The user will be prompted to enter a pin
      * @hide */
@@ -97,6 +185,7 @@
      * such as "00:11:22:33:AA:BB".
      * <p>A {@link BluetoothDevice} will always be returned for a valid
      * hardware address, even if this adapter has never seen that device.
+     *
      * @param address valid Bluetooth MAC address
      * @throws IllegalArgumentException if address is invalid
      */
@@ -105,10 +194,12 @@
     }
 
     /**
-     * Is Bluetooth currently turned on.
+     * Return true if Bluetooth is currently enabled and ready for use.
+     * <p>Equivalent to:
+     * <code>getBluetoothState() == STATE_ON</code>
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
-     * @return true if Bluetooth enabled, false otherwise.
-     * @hide
+     * @return true if the local adapter is turned on
      */
     public boolean isEnabled() {
         try {
@@ -118,28 +209,40 @@
     }
 
     /**
-     * Get the current state of Bluetooth.
+     * Get the current state of the local Bluetooth adapter.
+     * <p>Possible return values are
+     * {@link #STATE_OFF},
+     * {@link #STATE_TURNING_ON},
+     * {@link #STATE_ON},
+     * {@link #STATE_TURNING_OFF}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
-     * @return One of BLUETOOTH_STATE_ or BluetoothError.ERROR.
-     * @hide
+     * @return current state of Bluetooth adapter
      */
-    public int getBluetoothState() {
+    public int getState() {
         try {
             return mService.getBluetoothState();
         } catch (RemoteException e) {Log.e(TAG, "", e);}
-        return BluetoothError.ERROR;
+        return STATE_OFF;
     }
 
     /**
-     * Enable the Bluetooth device.
-     * Turn on the underlying hardware.
-     * This is an asynchronous call,
-     * BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION can be used to check if
-     * and when the device is sucessfully enabled.
-     * @return false if we cannot enable the Bluetooth device. True does not
-     * imply the device was enabled, it only implies that so far there were no
-     * problems.
-     * @hide
+     * Turn on the local Bluetooth adapter.
+     * <p>This powers on the underlying Bluetooth hardware, and starts all
+     * Bluetooth system services.
+     * <p>This is an asynchronous call: it will return immediatley, and
+     * clients should listen for {@link #ACTION_STATE_CHANGED}
+     * to be notified of subsequent adapter state changes. If this call returns
+     * true, then the adapter state will immediately transition from {@link
+     * #STATE_OFF} to {@link #STATE_TURNING_ON}, and some time
+     * later transition to either {@link #STATE_OFF} or {@link
+     * #STATE_ON}. If this call returns false then there was an
+     * immediate problem that will prevent the adapter from being turned on -
+     * such as Airplane mode, or the adapter is already turned on.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     *
+     * @return true to indicate adapter startup has begun, or false on
+     *         immediate error
      */
     public boolean enable() {
         try {
@@ -149,11 +252,22 @@
     }
 
     /**
-     * Disable the Bluetooth device.
-     * This turns off the underlying hardware.
+     * Turn off the local Bluetooth adapter.
+     * <p>This gracefully shuts down all Bluetooth connections, stops Bluetooth
+     * system services, and powers down the underlying Bluetooth hardware.
+     * <p>This is an asynchronous call: it will return immediatley, and
+     * clients should listen for {@link #ACTION_STATE_CHANGED}
+     * to be notified of subsequent adapter state changes. If this call returns
+     * true, then the adapter state will immediately transition from {@link
+     * #STATE_ON} to {@link #STATE_TURNING_OFF}, and some time
+     * later transition to either {@link #STATE_OFF} or {@link
+     * #STATE_ON}. If this call returns false then there was an
+     * immediate problem that will prevent the adapter from being turned off -
+     * such as the adapter already being turned off.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
      *
-     * @return true if successful, false otherwise.
-     * @hide
+     * @return true to indicate adapter shutdown has begun, or false on
+     *         immediate error
      */
     public boolean disable() {
         try {
@@ -162,7 +276,13 @@
         return false;
     }
 
-    /** @hide */
+    /**
+     * Returns the hardware address of the local Bluetooth adapter.
+     * <p>For example, "00:11:22:AA:BB:CC".
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+     *
+     * @return Bluetooth hardware address as string
+     */
     public String getAddress() {
         try {
             return mService.getAddress();
@@ -171,13 +291,11 @@
     }
 
     /**
-     * Get the friendly Bluetooth name of this device.
+     * Get the friendly Bluetooth name of the local Bluetooth adapter.
+     * <p>This name is visible to remote Bluetooth devices.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
-     * This name is visible to remote Bluetooth devices. Currently it is only
-     * possible to retrieve the Bluetooth name when Bluetooth is enabled.
-     *
-     * @return the Bluetooth name, or null if there was a problem.
-     * @hide
+     * @return the Bluetooth name, or null on error
      */
     public String getName() {
         try {
@@ -187,14 +305,15 @@
     }
 
     /**
-     * Set the friendly Bluetooth name of this device.
+     * Set the friendly Bluetooth name of the local Bluetoth adapter.
+     * <p>This name is visible to remote Bluetooth devices.
+     * <p>Valid Bluetooth names are a maximum of 248 UTF-8 characters, however
+     * many remote devices can only display the first 40 characters, and some
+     * may be limited to just 20.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
      *
-     * This name is visible to remote Bluetooth devices. The Bluetooth Service
-     * is responsible for persisting this name.
-     *
-     * @param name the name to set
-     * @return     true, if the name was successfully set. False otherwise.
-     * @hide
+     * @param name a valid Bluetooth name
+     * @return     true if the name was set, false otherwise
      */
     public boolean setName(String name) {
         try {
@@ -204,28 +323,46 @@
     }
 
     /**
-     * Get the current scan mode.
-     * Used to determine if the local device is connectable and/or discoverable
-     * @return Scan mode, one of SCAN_MODE_* or an error code
-     * @hide
+     * Get the current Bluetooth scan mode of the local Bluetooth adaper.
+     * <p>The Bluetooth scan mode determines if the local adapter is
+     * connectable and/or discoverable from remote Bluetooth devices.
+     * <p>Possible values are:
+     * {@link #SCAN_MODE_NONE},
+     * {@link #SCAN_MODE_CONNECTABLE},
+     * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+     *
+     * @return scan mode
      */
     public int getScanMode() {
         try {
             return mService.getScanMode();
         } catch (RemoteException e) {Log.e(TAG, "", e);}
-        return BluetoothError.ERROR_IPC;
+        return SCAN_MODE_NONE;
     }
 
     /**
-     * Set the current scan mode.
-     * Used to make the local device connectable and/or discoverable
-     * @param scanMode One of SCAN_MODE_*
-     * @hide
+     * Set the Bluetooth scan mode of the local Bluetooth adapter.
+     * <p>The Bluetooth scan mode determines if the local adapter is
+     * connectable and/or discoverable from remote Bluetooth devices.
+     * <p>For privacy reasons, it is recommended to limit the duration of time
+     * that the local adapter remains in a discoverable scan mode. For example,
+     * 2 minutes is a generous time to allow a remote Bluetooth device to
+     * initiate and complete its discovery process.
+     * <p>Valid scan mode values are:
+     * {@link #SCAN_MODE_NONE},
+     * {@link #SCAN_MODE_CONNECTABLE},
+     * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     *
+     * @param mode valid scan mode
+     * @return     true if the scan mode was set, false otherwise
      */
-    public void setScanMode(int scanMode) {
+    public boolean setScanMode(int mode) {
         try {
-            mService.setScanMode(scanMode);
+            return mService.setScanMode(mode);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
+        return false;
     }
 
     /** @hide */
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 1b7011c..1ab4389 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -44,6 +44,15 @@
 public final class BluetoothDevice implements Parcelable {
     private static final String TAG = "BluetoothDevice";
 
+    /**
+     * Sentinel error value for this class. Guaranteed to not equal any other
+     * integer constant in this class. Provided as a convenience for functions
+     * that require a sentinel error value, for example:
+     * <p><code>Intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+     * BluetoothAdapter.ERROR)</code>
+     */
+    public static final int ERROR = -1;
+
     /** We do not have a link key for the remote device, and are therefore not
      * bonded
      * @hide*/
@@ -65,7 +74,9 @@
      *  @hide */
     public static final int DEVICE_PICKER_FILTER_TYPE_TRANSFER = 2;
 
-    //TODO: Unify these result codes in BluetoothResult or BluetoothError
+    /** A bond attempt succeeded
+     * @hide */
+    public static final int BOND_SUCCESS = 0;
     /** A bond attempt failed because pins did not match, or remote device did
      * not respond to pin request in time 
      * @hide */
@@ -193,9 +204,9 @@
      * <p>The local adapter will automatically retrieve remote names when
      * performing a device scan, and will cache them. This method just returns
      * the name for this device from the cache.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
      * @return the Bluetooth name, or null if there was a problem.
-     * @hide
      */
     public String getName() {
         try {
@@ -252,8 +263,8 @@
      * Get the bonding state of a remote device.
      *
      * Result is one of:
-     * BluetoothError.*
      * BOND_*
+     * ERROR
      *
      * @param address Bluetooth hardware address of the remote device to check.
      * @return Result code
@@ -263,7 +274,7 @@
         try {
             return sService.getBondState(mAddress);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
-        return BluetoothError.ERROR_IPC;
+        return BluetoothDevice.ERROR;
     }
 
     /**
@@ -298,7 +309,7 @@
         try {
             return sService.getRemoteClass(mAddress);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
-        return BluetoothError.ERROR_IPC;
+        return BluetoothDevice.ERROR;
     }
 
     /** @hide */
@@ -314,7 +325,7 @@
          try {
              return sService.getRemoteServiceChannel(mAddress, uuid);
          } catch (RemoteException e) {Log.e(TAG, "", e);}
-         return BluetoothError.ERROR_IPC;
+         return BluetoothDevice.ERROR;
     }
 
     /** @hide */
@@ -358,6 +369,7 @@
      * connection.
      * <p>Valid RFCOMM channels are in range 1 to 30.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+     *
      * @param channel RFCOMM channel to connect to
      * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
      * @throws IOException on error, for example Bluetooth not available, or
diff --git a/core/java/android/bluetooth/BluetoothError.java b/core/java/android/bluetooth/BluetoothError.java
deleted file mode 100644
index 2554bea..0000000
--- a/core/java/android/bluetooth/BluetoothError.java
+++ /dev/null
@@ -1,42 +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 android.bluetooth;
-
-/**
- * Bluetooth API error codes.
- *
- * Errors are always negative.
- *
- * @hide
- */
-public class BluetoothError {
-    /** No error */
-    public static final int SUCCESS = 0;
-
-    /** Generic error */
-    public static final int ERROR = -1000;
-
-    /** Bluetooth currently disabled */
-    public static final int ERROR_DISABLED = -1001;
-
-    /** IPC is not ready, for example service is not yet bound */
-    public static final int ERROR_IPC_NOT_READY = -1011;
-
-    /** Some other IPC error, for example a RemoteException */
-    public static final int ERROR_IPC = -1012;
-
-}
diff --git a/core/java/android/bluetooth/BluetoothIntent.java b/core/java/android/bluetooth/BluetoothIntent.java
index c39bc3d..8de19f5 100644
--- a/core/java/android/bluetooth/BluetoothIntent.java
+++ b/core/java/android/bluetooth/BluetoothIntent.java
@@ -20,17 +20,12 @@
 import android.annotation.SdkConstant.SdkConstantType;
 
 /**
- * The Android Bluetooth API is not finalized, and *will* change. Use at your
- * own risk.
+ * Bluetooth API constants.
  *
- * Manages the local Bluetooth device. Scan for devices, create bondings,
- * power up and down the adapter.
- *
+ * TODO: Deprecate this class
  * @hide
  */
 public interface BluetoothIntent {
-    public static final String SCAN_MODE =
-        "android.bluetooth.intent.SCAN_MODE";
     public static final String DEVICE =
         "android.bluetooth.intent.DEVICE";
     public static final String NAME =
@@ -41,10 +36,6 @@
         "android.bluetooth.intent.RSSI";
     public static final String CLASS =
         "android.bluetooth.intent.CLASS";
-    public static final String BLUETOOTH_STATE =
-        "android.bluetooth.intent.BLUETOOTH_STATE";
-    public static final String BLUETOOTH_PREVIOUS_STATE =
-        "android.bluetooth.intent.BLUETOOTH_PREVIOUS_STATE";
     public static final String HEADSET_STATE =
         "android.bluetooth.intent.HEADSET_STATE";
     public static final String HEADSET_PREVIOUS_STATE =
@@ -91,25 +82,10 @@
     public static final String DEVICE_PICKER_DEVICE_PICKER =
         "android.bluetooth.intent.action.DEVICE_PICKER";
 
-    /** Broadcast when the local Bluetooth device state changes, for example
-     *  when Bluetooth is enabled. Will contain int extra's BLUETOOTH_STATE and
-     *  BLUETOOTH_PREVIOUS_STATE. */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String BLUETOOTH_STATE_CHANGED_ACTION =
-        "android.bluetooth.intent.action.BLUETOOTH_STATE_CHANGED";
-
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String NAME_CHANGED_ACTION  =
         "android.bluetooth.intent.action.NAME_CHANGED";
 
-    /**
-     * Broadcast when the scan mode changes. Always contains an int extra
-     * named SCAN_MODE that contains the new scan mode.
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String SCAN_MODE_CHANGED_ACTION         =
-        "android.bluetooth.intent.action.SCAN_MODE_CHANGED";
-
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String DISCOVERY_STARTED_ACTION          =
         "android.bluetooth.intent.action.DISCOVERY_STARTED";
diff --git a/core/java/android/bluetooth/IBluetoothA2dp.aidl b/core/java/android/bluetooth/IBluetoothA2dp.aidl
index e6c6be2..2df7f23 100644
--- a/core/java/android/bluetooth/IBluetoothA2dp.aidl
+++ b/core/java/android/bluetooth/IBluetoothA2dp.aidl
@@ -24,10 +24,10 @@
  * {@hide}
  */
 interface IBluetoothA2dp {
-    int connectSink(in BluetoothDevice device);
-    int disconnectSink(in BluetoothDevice device);
+    boolean connectSink(in BluetoothDevice device);
+    boolean disconnectSink(in BluetoothDevice device);
     BluetoothDevice[] getConnectedSinks();  // change to Set<> once AIDL supports
     int getSinkState(in BluetoothDevice device);
-    int setSinkPriority(in BluetoothDevice device, int priority);
+    boolean setSinkPriority(in BluetoothDevice device, int priority);
     int getSinkPriority(in BluetoothDevice device);
 }
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 4f31ef0..0cd4036 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -194,7 +194,7 @@
     private static final int LOCK_ACQUIRED_WARNING_THREAD_TIME_IN_MS = 100;
     private static final int LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT = 2000;
 
-    private static final int SLEEP_AFTER_YIELD_QUANTUM = 500;
+    private static final int SLEEP_AFTER_YIELD_QUANTUM = 1000;
 
     private long mLastLockMessageTime = 0L;
 
diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java
index 6554827..3c01a9e 100644
--- a/core/java/android/pim/vcard/VCardComposer.java
+++ b/core/java/android/pim/vcard/VCardComposer.java
@@ -871,11 +871,10 @@
     }
 
     private boolean appendPostalsForDoCoMoInternal(final StringBuilder builder,
-            final List<ContentValues> contentValuesList, int preferedType) {
+            final List<ContentValues> contentValuesList, Integer preferedType) {
         for (ContentValues contentValues : contentValuesList) {
-            final int type = contentValues.getAsInteger(StructuredPostal.TYPE);
-            final String label = contentValues
-                    .getAsString(StructuredPostal.LABEL);
+            final Integer type = contentValues.getAsInteger(StructuredPostal.TYPE);
+            final String label = contentValues.getAsString(StructuredPostal.LABEL);
             if (type == preferedType) {
                 appendVCardPostalLine(builder, type, label, contentValues);
                 return true;
@@ -887,9 +886,8 @@
     private void appendPostalsForGeneric(final StringBuilder builder,
             final List<ContentValues> contentValuesList) {
         for (ContentValues contentValues : contentValuesList) {
-            final int type = contentValues.getAsInteger(StructuredPostal.TYPE);
-            final String label = contentValues
-                    .getAsString(StructuredPostal.LABEL);
+            final Integer type = contentValues.getAsInteger(StructuredPostal.TYPE);
+            final String label = contentValues.getAsString(StructuredPostal.LABEL);
             appendVCardPostalLine(builder, type, label, contentValues);
         }
     }
@@ -900,15 +898,10 @@
                 .get(Im.CONTENT_ITEM_TYPE);
         if (contentValuesList != null) {
             for (ContentValues contentValues : contentValuesList) {
-                int type = contentValues.getAsInteger(Im.PROTOCOL);
+                Integer protocol = contentValues.getAsInteger(Im.PROTOCOL);
                 String data = contentValues.getAsString(Im.DATA);
-                
-                Log.d("@@@", "Im information. protocol=\"" + type +
-                        "\", data=\"" + data + "\", protocol=\"" +
-                        contentValues.getAsString(Im.PROTOCOL) + "\", custom_protocol=\"" +
-                        contentValues.getAsString(Im.CUSTOM_PROTOCOL) + "\"");
 
-                if (type == Im.PROTOCOL_GOOGLE_TALK) {
+                if (protocol != null && protocol == Im.PROTOCOL_GOOGLE_TALK) {
                     if (VCardConfig.usesAndroidSpecificProperty(mVCardType)) {
                         appendVCardLine(builder, Constants.PROPERTY_X_GOOGLE_TALK, data);
                     }
@@ -1129,8 +1122,8 @@
         builder.append(VCARD_COL_SEPARATOR);
     }
 
-    private void appendVCardPostalLine(StringBuilder builder, int type,
-            String label, final ContentValues contentValues) {
+    private void appendVCardPostalLine(StringBuilder builder, Integer type, String label,
+            final ContentValues contentValues) {
         builder.append(VCARD_PROPERTY_ADR);
         builder.append(VCARD_ATTR_SEPARATOR);
 
@@ -1150,6 +1143,10 @@
             }
         }
 
+        if (type == null) {
+            type = StructuredPostal.TYPE_OTHER;
+        }
+
         boolean typeIsAppended = false;
         switch (type) {
         case StructuredPostal.TYPE_HOME:
@@ -1161,7 +1158,8 @@
             typeIsAppended = true;
             break;
         case StructuredPostal.TYPE_CUSTOM:
-            if (mUsesAndroidProperty && VCardUtils.containsOnlyAlphaDigitHyphen(label)){
+            if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
+                        && VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
                 // We're not sure whether the label is valid in the spec ("IANA-token" in the vCard 3.1
                 // is unclear...)
                 // Just for safety, we add "X-" at the beggining of each label.
@@ -1216,17 +1214,21 @@
         builder.append(VCARD_COL_SEPARATOR);
     }
 
-    private void appendVCardEmailLine(StringBuilder builder, int type,
-            String label, String data) {
+    private void appendVCardEmailLine(StringBuilder builder, Integer type, String label, String data) {
         builder.append(VCARD_PROPERTY_EMAIL);
         builder.append(VCARD_ATTR_SEPARATOR);
 
+        if (type == null) {
+            type = Email.TYPE_OTHER;
+        }
+
         switch (type) {
         case Email.TYPE_CUSTOM:
-            if (label.equals(
-                    android.provider.Contacts.ContactMethodsColumns.MOBILE_EMAIL_TYPE_NAME)) {
+            if (android.provider.Contacts.ContactMethodsColumns.MOBILE_EMAIL_TYPE_NAME
+                        .equals(label)) {
                 builder.append(Constants.ATTR_TYPE_CELL);
-            } else if (mUsesAndroidProperty && VCardUtils.containsOnlyAlphaDigitHyphen(label)){
+            } else if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
+                        && VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
                 builder.append("X-");
                 builder.append(label);
             } else {
@@ -1257,11 +1259,15 @@
         builder.append(VCARD_COL_SEPARATOR);
     }
 
-    private void appendVCardTelephoneLine(StringBuilder builder, int type,
-            String label, String encodedData) {
+    private void appendVCardTelephoneLine(StringBuilder builder, Integer type, String label,
+            String encodedData) {
         builder.append(VCARD_PROPERTY_TEL);
         builder.append(VCARD_ATTR_SEPARATOR);
 
+        if (type == null) {
+            type = Phone.TYPE_OTHER;
+        }
+
         switch (type) {
         case Phone.TYPE_HOME:
             appendTypeAttributes(builder, Arrays.asList(
@@ -1295,8 +1301,8 @@
             builder.append(Constants.ATTR_TYPE_VOICE);
             break;
         case Phone.TYPE_CUSTOM:
-            if (mUsesAndroidProperty) {
-                VCardUtils.containsOnlyAlphaDigitHyphen(label);
+            if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
+                        && VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
                 builder.append("X-" + label);
             } else {
                 // Just ignore the custom type.
@@ -1316,11 +1322,10 @@
     /**
      * Appends phone type string which may not be available in some devices.
      */
-    private void appendUncommonPhoneType(StringBuilder builder, int type) {
+    private void appendUncommonPhoneType(StringBuilder builder, Integer type) {
         if (mIsDoCoMo) {
             // The previous implementation for DoCoMo had been conservative
-            // about
-            // miscellaneous types.
+            // about miscellaneous types.
             builder.append(Constants.ATTR_TYPE_VOICE);
         } else {
             String phoneAttribute = VCardUtils.getPhoneAttributeString(type);
diff --git a/core/java/android/pim/vcard/VCardUtils.java b/core/java/android/pim/vcard/VCardUtils.java
index b7b706f..ffceade 100644
--- a/core/java/android/pim/vcard/VCardUtils.java
+++ b/core/java/android/pim/vcard/VCardUtils.java
@@ -75,7 +75,7 @@
         sPhoneTypesSetUnknownToContacts.add(Constants.ATTR_TYPE_VIDEO);
     }
     
-    public static String getPhoneAttributeString(int type) {
+    public static String getPhoneAttributeString(Integer type) {
         return sKnownPhoneTypesMap_ItoS.get(type);
     }
     
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index fc39573..08a2a9f 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -1456,8 +1456,10 @@
         if (!TextUtils.isEmpty(summary)) {
             sb.append(summary).append(' ');
         }
-        // Drop the last space
-        sb.setLength(sb.length() - 1);
+        if (sb.length() > 0) {
+            // Drop the last space
+            sb.setLength(sb.length() - 1);
+        }
         return sb;
     }
 
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 31d43ee..d354ccf 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -298,6 +298,15 @@
         }
 
         /**
+         * Build a {@link #CONTENT_LOOKUP_URI} lookup {@link Uri} using the
+         * given {@link Contacts#_ID} and {@link Contacts#LOOKUP_KEY}.
+         */
+        public static Uri getLookupUri(long contactId, String lookupKey) {
+            return ContentUris.withAppendedId(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
+                    lookupKey), contactId);
+        }
+
+        /**
          * Computes a content URI (see {@link #CONTENT_URI}) given a lookup URI.
          * <p>
          * Returns null if the contact cannot be found.
@@ -523,7 +532,7 @@
         /**
          * Aggregation mode: aggregate at the time the raw contact is inserted/updated.
          */
-        public static final int AGGREGATION_MODE_IMMEDITATE = 1;
+        public static final int AGGREGATION_MODE_IMMEDIATE = 1;
 
         /**
          * If {@link #AGGREGATION_MODE} is {@link #AGGREGATION_MODE_SUSPENDED}, changes
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index d9fcb53..a24e0d21 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -25,7 +25,6 @@
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothError;
 import android.bluetooth.BluetoothIntent;
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetoothA2dp;
@@ -81,20 +80,20 @@
             String action = intent.getAction();
             BluetoothDevice device =
                     intent.getParcelableExtra(BluetoothIntent.DEVICE);
-            if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION)) {
-                int state = intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE,
-                                               BluetoothError.ERROR);
+            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+                                               BluetoothAdapter.ERROR);
                 switch (state) {
-                case BluetoothAdapter.BLUETOOTH_STATE_ON:
+                case BluetoothAdapter.STATE_ON:
                     onBluetoothEnable();
                     break;
-                case BluetoothAdapter.BLUETOOTH_STATE_TURNING_OFF:
+                case BluetoothAdapter.STATE_TURNING_OFF:
                     onBluetoothDisable();
                     break;
                 }
             } else if (action.equals(BluetoothIntent.BOND_STATE_CHANGED_ACTION)) {
                 int bondState = intent.getIntExtra(BluetoothIntent.BOND_STATE,
-                                                   BluetoothError.ERROR);
+                                                   BluetoothDevice.ERROR);
                 switch(bondState) {
                 case BluetoothDevice.BOND_BONDED:
                     setSinkPriority(device, BluetoothA2dp.PRIORITY_AUTO);
@@ -134,7 +133,7 @@
 
         mAdapter = (BluetoothAdapter) context.getSystemService(Context.BLUETOOTH_SERVICE);
 
-        mIntentFilter = new IntentFilter(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION);
+        mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
         mIntentFilter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
         mIntentFilter.addAction(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION);
         mContext.registerReceiver(mReceiver, mIntentFilter);
@@ -273,7 +272,7 @@
         mAudioManager.setParameters(BLUETOOTH_ENABLED + "=false");
     }
 
-    public synchronized int connectSink(BluetoothDevice device) {
+    public synchronized boolean connectSink(BluetoothDevice device) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                 "Need BLUETOOTH_ADMIN permission");
         if (DBG) log("connectSink(" + device + ")");
@@ -284,11 +283,11 @@
                 BluetoothA2dp.STATE_CONNECTED,
                 BluetoothA2dp.STATE_PLAYING,
                 BluetoothA2dp.STATE_DISCONNECTING}).size() != 0) {
-            return BluetoothError.ERROR;
+            return false;
         }
 
         if (mAudioDevices.get(device) == null && !addAudioSink(device))
-            return BluetoothError.ERROR;
+            return false;
 
         int state = mAudioDevices.get(device);
 
@@ -296,44 +295,44 @@
         case BluetoothA2dp.STATE_CONNECTED:
         case BluetoothA2dp.STATE_PLAYING:
         case BluetoothA2dp.STATE_DISCONNECTING:
-            return BluetoothError.ERROR;
+            return false;
         case BluetoothA2dp.STATE_CONNECTING:
-            return BluetoothError.SUCCESS;
+            return true;
         }
 
         String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
         if (path == null)
-            return BluetoothError.ERROR;
+            return false;
 
         // State is DISCONNECTED
         if (!connectSinkNative(path)) {
-            return BluetoothError.ERROR;
+            return false;
         }
-        return BluetoothError.SUCCESS;
+        return true;
     }
 
-    public synchronized int disconnectSink(BluetoothDevice device) {
+    public synchronized boolean disconnectSink(BluetoothDevice device) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                 "Need BLUETOOTH_ADMIN permission");
         if (DBG) log("disconnectSink(" + device + ")");
 
         String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
         if (path == null) {
-            return BluetoothError.ERROR;
+            return false;
         }
 
         switch (getSinkState(device)) {
         case BluetoothA2dp.STATE_DISCONNECTED:
-            return BluetoothError.ERROR;
+            return false;
         case BluetoothA2dp.STATE_DISCONNECTING:
-            return BluetoothError.SUCCESS;
+            return true;
         }
 
         // State is CONNECTING or CONNECTED or PLAYING
         if (!disconnectSinkNative(path)) {
-            return BluetoothError.ERROR;
+            return false;
         } else {
-            return BluetoothError.SUCCESS;
+            return true;
         }
     }
 
@@ -359,15 +358,14 @@
                 BluetoothA2dp.PRIORITY_OFF);
     }
 
-    public synchronized int setSinkPriority(BluetoothDevice device, int priority) {
+    public synchronized boolean setSinkPriority(BluetoothDevice device, int priority) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                 "Need BLUETOOTH_ADMIN permission");
         if (!BluetoothDevice.checkBluetoothAddress(device.getAddress())) {
-            return BluetoothError.ERROR;
+            return false;
         }
         return Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.getBluetoothA2dpSinkPriorityKey(device.getAddress()), priority) ?
-                BluetoothError.SUCCESS : BluetoothError.ERROR;
+                Settings.Secure.getBluetoothA2dpSinkPriorityKey(device.getAddress()), priority);
     }
 
     private synchronized void onSinkPropertyChanged(String path, String []propValues) {
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 8cef3a2..b5eb9ac 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -20,7 +20,6 @@
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothError;
 import android.bluetooth.BluetoothIntent;
 import android.bluetooth.BluetoothUuid;
 import android.content.Context;
@@ -169,7 +168,7 @@
 
     private void onCreatePairedDeviceResult(String address, int result) {
         address = address.toUpperCase();
-        if (result == BluetoothError.SUCCESS) {
+        if (result == BluetoothDevice.BOND_SUCCESS) {
             mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDED);
             if (mBluetoothService.getBondState().isAutoPairingAttemptsInProgress(address)) {
                 mBluetoothService.getBondState().clearPinAttempts(address);
@@ -240,6 +239,11 @@
     }
 
     /*package*/ void onPropertyChanged(String[] propValues) {
+        if (mBluetoothService.isAdapterPropertiesEmpty()) {
+            // We have got a property change before
+            // we filled up our cache.
+            mBluetoothService.getAllProperties();
+        }
         String name = propValues[0];
         if (name.equals("Name")) {
             Intent intent = new Intent(BluetoothIntent.NAME_CHANGED_ACTION);
@@ -260,8 +264,8 @@
                     pairable.equals("true"),
                     discoverable.equals("true"));
             if (mode >= 0) {
-                Intent intent = new Intent(BluetoothIntent.SCAN_MODE_CHANGED_ACTION);
-                intent.putExtra(BluetoothIntent.SCAN_MODE, mode);
+                Intent intent = new Intent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
+                intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, mode);
                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                 mContext.sendBroadcast(intent, BLUETOOTH_PERM);
             }
@@ -366,7 +370,7 @@
         address = address.toUpperCase();
         mPasskeyAgentRequestData.put(address, new Integer(nativeData));
 
-        if (mBluetoothService.getBluetoothState() == BluetoothAdapter.BLUETOOTH_STATE_TURNING_OFF) {
+        if (mBluetoothService.getBluetoothState() == BluetoothAdapter.STATE_TURNING_OFF) {
             // shutdown path
             mBluetoothService.cancelPairingUserInput(address);
             return null;
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index b168850..6482c4c 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -27,7 +27,6 @@
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothError;
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothIntent;
 import android.bluetooth.IBluetooth;
@@ -102,7 +101,7 @@
             disableNative();
         }
 
-        mBluetoothState = BluetoothAdapter.BLUETOOTH_STATE_OFF;
+        mBluetoothState = BluetoothAdapter.STATE_OFF;
         mIsDiscovering = false;
         mAdapterProperties = new HashMap<String, String>();
         mDeviceProperties = new HashMap<String, Map<String,String>>();
@@ -128,7 +127,7 @@
 
     public boolean isEnabled() {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        return mBluetoothState == BluetoothAdapter.BLUETOOTH_STATE_ON;
+        return mBluetoothState == BluetoothAdapter.STATE_ON;
     }
 
     public int getBluetoothState() {
@@ -153,9 +152,9 @@
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
 
         switch (mBluetoothState) {
-        case BluetoothAdapter.BLUETOOTH_STATE_OFF:
+        case BluetoothAdapter.STATE_OFF:
             return true;
-        case BluetoothAdapter.BLUETOOTH_STATE_ON:
+        case BluetoothAdapter.STATE_ON:
             break;
         default:
             return false;
@@ -163,7 +162,7 @@
         if (mEnableThread != null && mEnableThread.isAlive()) {
             return false;
         }
-        setBluetoothState(BluetoothAdapter.BLUETOOTH_STATE_TURNING_OFF);
+        setBluetoothState(BluetoothAdapter.STATE_TURNING_OFF);
 
         // Allow 3 seconds for profiles to gracefully disconnect
         // TODO: Introduce a callback mechanism so that each profile can notify
@@ -175,7 +174,7 @@
 
 
     private synchronized void finishDisable(boolean saveSetting) {
-        if (mBluetoothState != BluetoothAdapter.BLUETOOTH_STATE_TURNING_OFF) {
+        if (mBluetoothState != BluetoothAdapter.STATE_TURNING_OFF) {
             return;
         }
         mEventLoop.stop();
@@ -189,8 +188,8 @@
         }
 
         // update mode
-        Intent intent = new Intent(BluetoothIntent.SCAN_MODE_CHANGED_ACTION);
-        intent.putExtra(BluetoothIntent.SCAN_MODE, BluetoothAdapter.SCAN_MODE_NONE);
+        Intent intent = new Intent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
+        intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.SCAN_MODE_NONE);
         mContext.sendBroadcast(intent, BLUETOOTH_PERM);
 
         mIsDiscovering = false;
@@ -200,7 +199,7 @@
             persistBluetoothOnSetting(false);
         }
 
-        setBluetoothState(BluetoothAdapter.BLUETOOTH_STATE_OFF);
+        setBluetoothState(BluetoothAdapter.STATE_OFF);
 
         // Log bluetooth off to battery stats.
         long ident = Binder.clearCallingIdentity();
@@ -237,13 +236,13 @@
         if (mIsAirplaneSensitive && isAirplaneModeOn()) {
             return false;
         }
-        if (mBluetoothState != BluetoothAdapter.BLUETOOTH_STATE_OFF) {
+        if (mBluetoothState != BluetoothAdapter.STATE_OFF) {
             return false;
         }
         if (mEnableThread != null && mEnableThread.isAlive()) {
             return false;
         }
-        setBluetoothState(BluetoothAdapter.BLUETOOTH_STATE_TURNING_ON);
+        setBluetoothState(BluetoothAdapter.STATE_TURNING_ON);
         mEnableThread = new EnableThread(saveSetting);
         mEnableThread.start();
         return true;
@@ -251,7 +250,7 @@
 
     /** Forcibly restart Bluetooth if it is on */
     /* package */ synchronized void restart() {
-        if (mBluetoothState != BluetoothAdapter.BLUETOOTH_STATE_ON) {
+        if (mBluetoothState != BluetoothAdapter.STATE_ON) {
             return;
         }
         mRestart = true;
@@ -267,9 +266,9 @@
 
         if (DBG) log("Bluetooth state " + mBluetoothState + " -> " + state);
 
-        Intent intent = new Intent(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION);
-        intent.putExtra(BluetoothIntent.BLUETOOTH_PREVIOUS_STATE, mBluetoothState);
-        intent.putExtra(BluetoothIntent.BLUETOOTH_STATE, state);
+        Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
+        intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, mBluetoothState);
+        intent.putExtra(BluetoothAdapter.EXTRA_STATE, state);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
 
         mBluetoothState = state;
@@ -357,8 +356,8 @@
             mEnableThread = null;
 
             setBluetoothState(res ?
-                              BluetoothAdapter.BLUETOOTH_STATE_ON :
-                              BluetoothAdapter.BLUETOOTH_STATE_OFF);
+                              BluetoothAdapter.STATE_ON :
+                              BluetoothAdapter.STATE_OFF);
 
             if (res) {
                 // Update mode
@@ -411,7 +410,7 @@
                         ));
 
         public synchronized void loadBondState() {
-            if (mBluetoothState != BluetoothAdapter.BLUETOOTH_STATE_TURNING_ON) {
+            if (mBluetoothState != BluetoothAdapter.STATE_TURNING_ON) {
                 return;
             }
             String []bonds = null;
@@ -538,6 +537,10 @@
         }
     }
 
+    /*package*/ synchronized boolean isAdapterPropertiesEmpty() {
+        return mAdapterProperties.isEmpty();
+    }
+
     /*package*/synchronized void getAllProperties() {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
         mAdapterProperties.clear();
@@ -629,17 +632,22 @@
     public synchronized boolean setScanMode(int mode) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                 "Need BLUETOOTH_ADMIN permission");
-        boolean pairable = false, discoverable = false;
-        String modeString = scanModeToBluezString(mode);
-        if (modeString.equals("off")) {
+        boolean pairable = false;
+        boolean discoverable = false;
+        switch (mode) {
+        case BluetoothAdapter.SCAN_MODE_NONE:
             pairable = false;
             discoverable = false;
-        } else if (modeString.equals("pariable")) {
+            break;
+        case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
             pairable = true;
             discoverable = false;
-        } else if (modeString.equals("discoverable")) {
+        case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
             pairable = true;
             discoverable = true;
+        default:
+            Log.w(TAG, "Requested invalid scan mode " + mode);
+            return false;
         }
         setPropertyBoolean("Pairable", pairable);
         setPropertyBoolean("Discoverable", discoverable);
@@ -705,7 +713,7 @@
     public synchronized int getScanMode() {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
         if (!isEnabled())
-            return BluetoothError.ERROR;
+            return BluetoothAdapter.SCAN_MODE_NONE;
 
         boolean pairable = getProperty("Pairable").equals("true");
         boolean discoverable = getProperty("Discoverable").equals("true");
@@ -801,7 +809,7 @@
     public synchronized int getBondState(String address) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
         if (!BluetoothDevice.checkBluetoothAddress(address)) {
-            return BluetoothError.ERROR;
+            return BluetoothDevice.ERROR;
         }
         return mBondState.getBondState(address.toUpperCase());
     }
@@ -975,7 +983,7 @@
     public int getRemoteServiceChannel(String address, String uuid) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
         if (!BluetoothDevice.checkBluetoothAddress(address)) {
-            return BluetoothError.ERROR_IPC;
+            return BluetoothDevice.ERROR;
         }
         return getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid, 0x0004);
     }
@@ -1099,16 +1107,16 @@
         pw.println("\nmIsAirplaneSensitive = " + mIsAirplaneSensitive + "\n");
 
         switch(mBluetoothState) {
-        case BluetoothAdapter.BLUETOOTH_STATE_OFF:
+        case BluetoothAdapter.STATE_OFF:
             pw.println("\nBluetooth OFF\n");
             return;
-        case BluetoothAdapter.BLUETOOTH_STATE_TURNING_ON:
+        case BluetoothAdapter.STATE_TURNING_ON:
             pw.println("\nBluetooth TURNING ON\n");
             return;
-        case BluetoothAdapter.BLUETOOTH_STATE_TURNING_OFF:
+        case BluetoothAdapter.STATE_TURNING_OFF:
             pw.println("\nBluetooth TURNING OFF\n");
             return;
-        case BluetoothAdapter.BLUETOOTH_STATE_ON:
+        case BluetoothAdapter.STATE_ON:
             pw.println("\nBluetooth ON\n");
         }
 
diff --git a/core/java/android/syncml/pim/PropertyNode.java b/core/java/android/syncml/pim/PropertyNode.java
index 983ecb8..3a5c994 100644
--- a/core/java/android/syncml/pim/PropertyNode.java
+++ b/core/java/android/syncml/pim/PropertyNode.java
@@ -28,6 +28,7 @@
 import java.util.Map.Entry;
 import java.util.regex.Pattern;
 
+@Deprecated
 public class PropertyNode {
 
     public String propName;
diff --git a/core/java/android/syncml/pim/VBuilder.java b/core/java/android/syncml/pim/VBuilder.java
index 4528645..b6cb674 100644
--- a/core/java/android/syncml/pim/VBuilder.java
+++ b/core/java/android/syncml/pim/VBuilder.java
@@ -18,6 +18,7 @@
 
 import java.util.List;
 
+@Deprecated
 public interface VBuilder {
     void start();
 
diff --git a/core/java/android/syncml/pim/VBuilderCollection.java b/core/java/android/syncml/pim/VBuilderCollection.java
index f09c1c4..06e3100 100644
--- a/core/java/android/syncml/pim/VBuilderCollection.java
+++ b/core/java/android/syncml/pim/VBuilderCollection.java
@@ -19,6 +19,7 @@
 import java.util.Collection;
 import java.util.List;
 
+@Deprecated
 public class VBuilderCollection implements VBuilder {
 
     private final Collection<VBuilder> mVBuilderCollection;
diff --git a/core/java/android/syncml/pim/VDataBuilder.java b/core/java/android/syncml/pim/VDataBuilder.java
index f6e5b65..db8a299 100644
--- a/core/java/android/syncml/pim/VDataBuilder.java
+++ b/core/java/android/syncml/pim/VDataBuilder.java
@@ -36,6 +36,7 @@
  * VNode: standy by a vcard instance.
  * PropertyNode: standy by a property line of a card.
  */
+@Deprecated
 public class VDataBuilder implements VBuilder {
     static private String LOG_TAG = "VDATABuilder"; 
     
diff --git a/core/java/android/syncml/pim/VNode.java b/core/java/android/syncml/pim/VNode.java
index 9015415..378a9d1 100644
--- a/core/java/android/syncml/pim/VNode.java
+++ b/core/java/android/syncml/pim/VNode.java
@@ -18,6 +18,7 @@
 
 import java.util.ArrayList;
 
+@Deprecated
 public class VNode {
 
     public String VName;
diff --git a/core/java/android/syncml/pim/VParser.java b/core/java/android/syncml/pim/VParser.java
index 57c5f7a..14d2875 100644
--- a/core/java/android/syncml/pim/VParser.java
+++ b/core/java/android/syncml/pim/VParser.java
@@ -25,6 +25,7 @@
  * This interface is used to parse the V format files, such as VCard & VCal
  *
  */
+@Deprecated
 abstract public class VParser {
     // Assume that "iso-8859-1" is able to map "all" 8bit characters to some unicode and
     // decode the unicode to the original charset. If not, this setting will cause some bug. 
diff --git a/core/java/android/syncml/pim/vcalendar/CalendarStruct.java b/core/java/android/syncml/pim/vcalendar/CalendarStruct.java
deleted file mode 100644
index 3388ada..0000000
--- a/core/java/android/syncml/pim/vcalendar/CalendarStruct.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2007 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.syncml.pim.vcalendar;
-
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * Same comment as ContactStruct.
- */
-public class CalendarStruct{
-
-    public static class EventStruct{
-        public String description;
-        public String dtend;
-        public String dtstart;
-        public String duration;
-        public String has_alarm;
-        public String last_date;
-        public String rrule;
-        public String status;
-        public String title;
-        public String event_location;
-        public String uid;
-        public List<String> reminderList;
-
-        public void addReminderList(String method){
-            if(reminderList == null)
-                reminderList = new ArrayList<String>();
-            reminderList.add(method);
-        }
-    }
-
-    public String timezone;
-    public List<EventStruct> eventList;
-
-    public void addEventList(EventStruct stru){
-        if(eventList == null)
-            eventList = new ArrayList<EventStruct>();
-        eventList.add(stru);
-    }
-}
diff --git a/core/java/android/syncml/pim/vcalendar/VCalComposer.java b/core/java/android/syncml/pim/vcalendar/VCalComposer.java
deleted file mode 100644
index 18b6719..0000000
--- a/core/java/android/syncml/pim/vcalendar/VCalComposer.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2007 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.syncml.pim.vcalendar;
-
-/**
- * vCalendar string composer class
- */
-public class VCalComposer {
-
-    public final static String VERSION_VCALENDAR10 = "vcalendar1.0";
-    public final static String VERSION_VCALENDAR20 = "vcalendar2.0";
-
-    public final static int VERSION_VCAL10_INT = 1;
-    public final static int VERSION_VCAL20_INT = 2;
-
-    private static String mNewLine = "\r\n";
-    private String mVersion = null;
-
-    public VCalComposer() {
-    }
-
-    /**
-     * Create a vCalendar String.
-     * @param struct see more from CalendarStruct class
-     * @param vcalversion MUST be VERSION_VCAL10 /VERSION_VCAL20
-     * @return vCalendar string
-     * @throws VcalException if version is invalid or create failed
-     */
-    public String createVCal(CalendarStruct struct, int vcalversion)
-                                                throws VCalException{
-
-        StringBuilder returnStr = new StringBuilder();
-
-        //Version check
-        if(vcalversion != 1 && vcalversion != 2)
-            throw new VCalException("version not match 1.0 or 2.0.");
-        if (vcalversion == 1)
-            mVersion = VERSION_VCALENDAR10;
-        else
-            mVersion = VERSION_VCALENDAR20;
-
-        //Build vCalendar:
-        returnStr.append("BEGIN:VCALENDAR").append(mNewLine);
-
-        if(vcalversion == VERSION_VCAL10_INT)
-            returnStr.append("VERSION:1.0").append(mNewLine);
-        else
-            returnStr.append("VERSION:2.0").append(mNewLine);
-
-        returnStr.append("PRODID:vCal ID default").append(mNewLine);
-
-        if(!isNull(struct.timezone)){
-            if(vcalversion == VERSION_VCAL10_INT)
-                returnStr.append("TZ:").append(struct.timezone).append(mNewLine);
-            else//down here MUST have
-                returnStr.append("BEGIN:VTIMEZONE").append(mNewLine).
-                    append("TZID:vCal default").append(mNewLine).
-                    append("BEGIN:STANDARD").append(mNewLine).
-                    append("DTSTART:16010101T000000").append(mNewLine).
-                    append("TZOFFSETFROM:").append(struct.timezone).append(mNewLine).
-                    append("TZOFFSETTO:").append(struct.timezone).append(mNewLine).
-                    append("END:STANDARD").append(mNewLine).
-                    append("END:VTIMEZONE").append(mNewLine);
-        }
-        //Build VEVNET
-        for(int i = 0; i < struct.eventList.size(); i++){
-            String str = buildEventStr( struct.eventList.get(i) );
-            returnStr.append(str);
-        }
-
-        //Build VTODO
-        //TODO
-
-        returnStr.append("END:VCALENDAR").append(mNewLine).append(mNewLine);
-
-        return returnStr.toString();
-    }
-
-    private String buildEventStr(CalendarStruct.EventStruct stru){
-
-        StringBuilder strbuf = new StringBuilder();
-
-        strbuf.append("BEGIN:VEVENT").append(mNewLine);
-
-        if(!isNull(stru.uid))
-            strbuf.append("UID:").append(stru.uid).append(mNewLine);
-
-        if(!isNull(stru.description))
-            strbuf.append("DESCRIPTION:").
-            append(foldingString(stru.description)).append(mNewLine);
-
-        if(!isNull(stru.dtend))
-            strbuf.append("DTEND:").append(stru.dtend).append(mNewLine);
-
-        if(!isNull(stru.dtstart))
-            strbuf.append("DTSTART:").append(stru.dtstart).append(mNewLine);
-
-        if(!isNull(stru.duration))
-            strbuf.append("DUE:").append(stru.duration).append(mNewLine);
-
-        if(!isNull(stru.event_location))
-            strbuf.append("LOCATION:").append(stru.event_location).append(mNewLine);
-
-        if(!isNull(stru.last_date))
-            strbuf.append("COMPLETED:").append(stru.last_date).append(mNewLine);
-
-        if(!isNull(stru.rrule))
-            strbuf.append("RRULE:").append(stru.rrule).append(mNewLine);
-
-        if(!isNull(stru.title))
-            strbuf.append("SUMMARY:").append(stru.title).append(mNewLine);
-
-        if(!isNull(stru.status)){
-            String stat = "TENTATIVE";
-            switch (Integer.parseInt(stru.status)){
-            case 0://Calendar.Calendars.STATUS_TENTATIVE
-                stat = "TENTATIVE";
-                break;
-            case 1://Calendar.Calendars.STATUS_CONFIRMED
-                stat = "CONFIRMED";
-                break;
-            case 2://Calendar.Calendars.STATUS_CANCELED
-                stat = "CANCELLED";
-                break;
-            }
-            strbuf.append("STATUS:").append(stat).append(mNewLine);
-        }
-        //Alarm
-        if(!isNull(stru.has_alarm)
-            && stru.reminderList != null
-            && stru.reminderList.size() > 0){
-
-            if (mVersion.equals(VERSION_VCALENDAR10)){
-                String prefix = "";
-                for(String method : stru.reminderList){
-                    switch (Integer.parseInt(method)){
-                    case 0:
-                        prefix = "DALARM";
-                        break;
-                    case 1:
-                        prefix = "AALARM";
-                        break;
-                    case 2:
-                        prefix = "MALARM";
-                        break;
-                    case 3:
-                    default:
-                        prefix = "DALARM";
-                        break;
-                    }
-                    strbuf.append(prefix).append(":default").append(mNewLine);
-                }
-            }else {//version 2.0 only support audio-method now.
-                strbuf.append("BEGIN:VALARM").append(mNewLine).
-                       append("ACTION:AUDIO").append(mNewLine).
-                       append("TRIGGER:-PT10M").append(mNewLine).
-                       append("END:VALARM").append(mNewLine);
-            }
-        }
-        strbuf.append("END:VEVENT").append(mNewLine);
-        return strbuf.toString();
-    }
-
-    /** Alter str to folding supported format. */
-    private String foldingString(String str){
-        return str.replaceAll("\r\n", "\n").replaceAll("\n", "\r\n ");
-    }
-
-    /** is null */
-    private boolean isNull(String str){
-        if(str == null || str.trim().equals(""))
-            return true;
-        return false;
-    }
-}
diff --git a/core/java/android/syncml/pim/vcalendar/VCalException.java b/core/java/android/syncml/pim/vcalendar/VCalException.java
deleted file mode 100644
index 48ea134..0000000
--- a/core/java/android/syncml/pim/vcalendar/VCalException.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2007 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.syncml.pim.vcalendar;
-
-public class VCalException extends java.lang.Exception{
-    // constructors
-
-    /**
-     * Constructs a VCalException object
-     */
-
-    public VCalException()
-    {
-    }
-
-    /**
-     * Constructs a VCalException object
-     *
-     * @param message the error message
-     */
-
-    public VCalException( String message )
-    {
-        super( message );
-    }
-
-}
diff --git a/core/java/android/syncml/pim/vcalendar/VCalParser.java b/core/java/android/syncml/pim/vcalendar/VCalParser.java
deleted file mode 100644
index bc2d598..0000000
--- a/core/java/android/syncml/pim/vcalendar/VCalParser.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2007 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.syncml.pim.vcalendar;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import android.util.Config;
-import android.util.Log;
-
-import android.syncml.pim.VDataBuilder;
-import android.syncml.pim.VParser;
-
-public class VCalParser{
-
-    private final static String TAG = "VCalParser";
-
-    public final static String VERSION_VCALENDAR10 = "vcalendar1.0";
-    public final static String VERSION_VCALENDAR20 = "vcalendar2.0";
-
-    private VParser mParser = null;
-    private String mVersion = null;
-
-    public VCalParser() {
-    }
-
-    public boolean parse(String vcalendarStr, VDataBuilder builder)
-            throws VCalException {
-
-        vcalendarStr = verifyVCal(vcalendarStr);
-        try{
-            boolean isSuccess = mParser.parse(
-                    new ByteArrayInputStream(vcalendarStr.getBytes()),
-                    "US-ASCII", builder);
-
-            if (!isSuccess) {
-                if (mVersion.equals(VERSION_VCALENDAR10)) {
-                    if(Config.LOGD)
-                        Log.d(TAG, "Parse failed for vCal 1.0 parser."
-                            + " Try to use 2.0 parser.");
-                    mVersion = VERSION_VCALENDAR20;
-                    return parse(vcalendarStr, builder);
-                }else
-                    throw new VCalException("parse failed.(even use 2.0 parser)");
-            }
-        }catch (IOException e){
-            throw new VCalException(e.getMessage());
-        }
-        return true;
-    }
-
-    /**
-     * Verify vCalendar string, and initialize mVersion according to it.
-     * */
-    private String verifyVCal(String vcalStr) {
-
-        //Version check
-        judgeVersion(vcalStr);
-
-        vcalStr = vcalStr.replaceAll("\r\n", "\n");
-        String[] strlist = vcalStr.split("\n");
-
-        StringBuilder replacedStr = new StringBuilder();
-
-        for (int i = 0; i < strlist.length; i++) {
-            if (strlist[i].indexOf(":") < 0) {
-                if (strlist[i].length() == 0 && strlist[i + 1].indexOf(":") > 0)
-                    replacedStr.append(strlist[i]).append("\r\n");
-                else
-                    replacedStr.append(" ").append(strlist[i]).append("\r\n");
-            } else
-                replacedStr.append(strlist[i]).append("\r\n");
-        }
-        if(Config.LOGD)Log.d(TAG, "After verify:\r\n" + replacedStr.toString());
-
-        return replacedStr.toString();
-    }
-
-    /**
-     * If version not given. Search from vcal string of the VERSION property.
-     * Then instance mParser to appropriate parser.
-     */
-    private void judgeVersion(String vcalStr) {
-
-        if (mVersion == null) {
-            int versionIdx = vcalStr.indexOf("\nVERSION:");
-
-            mVersion = VERSION_VCALENDAR10;
-
-            if (versionIdx != -1){
-                String versionStr = vcalStr.substring(
-                        versionIdx, vcalStr.indexOf("\n", versionIdx + 1));
-                if (versionStr.indexOf("2.0") > 0)
-                    mVersion = VERSION_VCALENDAR20;
-            }
-        }
-        if (mVersion.equals(VERSION_VCALENDAR10))
-            mParser = new VCalParser_V10();
-        if (mVersion.equals(VERSION_VCALENDAR20))
-            mParser = new VCalParser_V20();
-    }
-}
-
diff --git a/core/java/android/syncml/pim/vcalendar/VCalParser_V10.java b/core/java/android/syncml/pim/vcalendar/VCalParser_V10.java
deleted file mode 100644
index 1b251f3..0000000
--- a/core/java/android/syncml/pim/vcalendar/VCalParser_V10.java
+++ /dev/null
@@ -1,1628 +0,0 @@
-/*
- * Copyright (C) 2007 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.syncml.pim.vcalendar;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import android.syncml.pim.VParser;
-
-public class VCalParser_V10 extends VParser {
-
-    /*
-     * The names of the properties whose value are not separated by ";"
-     */
-    private static final HashSet<String> mEvtPropNameGroup1 = new HashSet<String>(
-            Arrays.asList("ATTACH", "ATTENDEE", "DCREATED", "COMPLETED",
-                    "DESCRIPTION", "DUE", "DTEND", "EXRULE", "LAST-MODIFIED",
-                    "LOCATION", "RNUM", "PRIORITY", "RELATED-TO", "RRULE",
-                    "SEQUENCE", "DTSTART", "SUMMARY", "TRANSP", "URL", "UID",
-                    // above belong to simprop
-                    "CLASS", "STATUS"));
-
-    /*
-     * The names of properties whose value are separated by ";"
-     */
-    private static final HashSet<String> mEvtPropNameGroup2 = new HashSet<String>(
-            Arrays.asList("AALARM", "CATEGORIES", "DALARM", "EXDATE", "MALARM",
-                    "PALARM", "RDATE", "RESOURCES"));
-
-    private static final HashSet<String> mValueCAT = new HashSet<String>(Arrays
-            .asList("APPOINTMENT", "BUSINESS", "EDUCATION", "HOLIDAY",
-                    "MEETING", "MISCELLANEOUS", "PERSONAL", "PHONE CALL",
-                    "SICK DAY", "SPECIAL OCCASION", "TRAVEL", "VACATION"));
-
-    private static final HashSet<String> mValueCLASS = new HashSet<String>(Arrays
-            .asList("PUBLIC", "PRIVATE", "CONFIDENTIAL"));
-
-    private static final HashSet<String> mValueRES = new HashSet<String>(Arrays
-            .asList("CATERING", "CHAIRS", "EASEL", "PROJECTOR", "VCR",
-                    "VEHICLE"));
-
-    private static final HashSet<String> mValueSTAT = new HashSet<String>(Arrays
-            .asList("ACCEPTED", "NEEDS ACTION", "SENT", "TENTATIVE",
-                    "CONFIRMED", "DECLINED", "COMPLETED", "DELEGATED"));
-
-    /*
-     * The names of properties whose value can contain escape characters
-     */
-    private static final HashSet<String> mEscAllowedProps = new HashSet<String>(
-            Arrays.asList("DESCRIPTION", "SUMMARY", "AALARM", "DALARM",
-                    "MALARM", "PALARM"));
-
-    private static final HashMap<String, HashSet<String>> mSpecialValueSetMap =
-        new HashMap<String, HashSet<String>>();
-
-    static {
-        mSpecialValueSetMap.put("CATEGORIES", mValueCAT);
-        mSpecialValueSetMap.put("CLASS", mValueCLASS);
-        mSpecialValueSetMap.put("RESOURCES", mValueRES);
-        mSpecialValueSetMap.put("STATUS", mValueSTAT);
-    }
-
-    public VCalParser_V10() {
-    }
-
-    protected int parseVFile(int offset) {
-        return parseVCalFile(offset);
-    }
-
-    private int parseVCalFile(int offset) {
-        int ret = 0, sum = 0;
-
-        /* remove wsls */
-        while (PARSE_ERROR != (ret = parseWsls(offset))) {
-            offset += ret;
-            sum += ret;
-        }
-
-        ret = parseVCal(offset); // BEGIN:VCAL ... END:VCAL
-        if (PARSE_ERROR != ret) {
-            offset += ret;
-            sum += ret;
-        } else {
-            return PARSE_ERROR;
-        }
-
-        /* remove wsls */
-        while (PARSE_ERROR != (ret = parseWsls(offset))) {
-            offset += ret;
-            sum += ret;
-        }
-        return sum;
-    }
-
-    /**
-     * "BEGIN" [ws] ":" [ws] "VCALENDAR" [ws] 1*crlf calprop calentities [ws]
-     * *crlf "END" [ws] ":" [ws] "VCALENDAR" [ws] 1*CRLF
-     */
-    private int parseVCal(int offset) {
-        int ret = 0, sum = 0;
-
-        /* BEGIN */
-        ret = parseString(offset, "BEGIN", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // ":"
-        ret = parseString(offset, ":", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // "VCALENDAR
-        ret = parseString(offset, "VCALENDAR", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.startRecord("VCALENDAR");
-        }
-
-        /* [ws] */
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // 1*CRLF
-        ret = parseCrlf(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
-            offset += ret;
-            sum += ret;
-        }
-
-        // calprop
-        ret = parseCalprops(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // calentities
-        ret = parseCalentities(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // *CRLF
-        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
-            offset += ret;
-            sum += ret;
-        }
-
-        // "END"
-        ret = parseString(offset, "END", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // ":"
-        // ":"
-        ret = parseString(offset, ":", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // "VCALENDAR"
-        ret = parseString(offset, "VCALENDAR", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.endRecord();
-        }
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // 1 * CRLF
-        ret = parseCrlf(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
-            offset += ret;
-            sum += ret;
-        }
-
-        return sum;
-    }
-
-    /**
-     * calprops * CRLF calprop / calprop
-     */
-    private int parseCalprops(int offset) {
-        int ret = 0, sum = 0;
-
-        if (mBuilder != null) {
-            mBuilder.startProperty();
-        }
-        ret = parseCalprop(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.endProperty();
-        }
-
-        for (;;) {
-            /* *CRLF */
-            while (PARSE_ERROR != (ret = parseCrlf(offset))) {
-                offset += ret;
-                sum += ret;
-            }
-            // follow VEVENT ,it wont reach endProperty
-            if (mBuilder != null) {
-                mBuilder.startProperty();
-            }
-            ret = parseCalprop(offset);
-            if (PARSE_ERROR == ret) {
-                break;
-            }
-            offset += ret;
-            sum += ret;
-            if (mBuilder != null) {
-                mBuilder.endProperty();
-            }
-        }
-
-        return sum;
-    }
-
-    /**
-     * calentities *CRLF calentity / calentity
-     */
-    private int parseCalentities(int offset) {
-        int ret = 0, sum = 0;
-
-        ret = parseCalentity(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        for (;;) {
-            /* *CRLF */
-            while (PARSE_ERROR != (ret = parseCrlf(offset))) {
-                offset += ret;
-                sum += ret;
-            }
-
-            ret = parseCalentity(offset);
-            if (PARSE_ERROR == ret) {
-                break;
-            }
-            offset += ret;
-            sum += ret;
-        }
-
-        return sum;
-    }
-
-    /**
-     * calprop = DAYLIGHT/ GEO/ PRODID/ TZ/ VERSION
-     */
-    private int parseCalprop(int offset) {
-        int ret = 0;
-
-        ret = parseCalprop0(offset, "DAYLIGHT");
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseCalprop0(offset, "GEO");
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseCalprop0(offset, "PRODID");
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseCalprop0(offset, "TZ");
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseCalprop1(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-        return PARSE_ERROR;
-    }
-
-    /**
-     * evententity / todoentity
-     */
-    private int parseCalentity(int offset) {
-        int ret = 0;
-
-        ret = parseEvententity(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseTodoentity(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-        return PARSE_ERROR;
-
-    }
-
-    /**
-     * propName [params] ":" value CRLF
-     */
-    private int parseCalprop0(int offset, String propName) {
-        int ret = 0, sum = 0, start = 0;
-
-        ret = parseString(offset, propName, true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyName(propName);
-        }
-
-        ret = parseParams(offset);
-        if (PARSE_ERROR != ret) {
-            offset += ret;
-            sum += ret;
-        }
-
-        ret = parseString(offset, ":", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        start = offset;
-        ret = parseValue(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            ArrayList<String> v = new ArrayList<String>();
-            v.add(mBuffer.substring(start, offset));
-            mBuilder.propertyValues(v);
-        }
-
-        ret = parseCrlf(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        sum += ret;
-
-        return sum;
-    }
-
-    /**
-     * "VERSION" [params] ":" "1.0" CRLF
-     */
-    private int parseCalprop1(int offset) {
-        int ret = 0, sum = 0;
-
-        ret = parseString(offset, "VERSION", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyName("VERSION");
-        }
-
-        ret = parseParams(offset);
-        if (PARSE_ERROR != ret) {
-            offset += ret;
-            sum += ret;
-        }
-
-        ret = parseString(offset, ":", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        ret = parseString(offset, "1.0", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            ArrayList<String> v = new ArrayList<String>();
-            v.add("1.0");
-            mBuilder.propertyValues(v);
-        }
-        ret = parseCrlf(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        sum += ret;
-
-        return sum;
-    }
-
-    /**
-     * "BEGIN" [ws] ":" [ws] "VEVENT" [ws] 1*CRLF entprops [ws] *CRLF "END" [ws]
-     * ":" [ws] "VEVENT" [ws] 1*CRLF
-     */
-    private int parseEvententity(int offset) {
-        int ret = 0, sum = 0;
-
-        ret = parseString(offset, "BEGIN", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // ":"
-        ret = parseString(offset, ":", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // "VEVNET"
-        ret = parseString(offset, "VEVENT", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.startRecord("VEVENT");
-        }
-
-        /* [ws] */
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // 1*CRLF
-        ret = parseCrlf(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
-            offset += ret;
-            sum += ret;
-        }
-
-        ret = parseEntprops(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // *CRLF
-        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
-            offset += ret;
-            sum += ret;
-        }
-
-        // "END"
-        ret = parseString(offset, "END", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // ":"
-        ret = parseString(offset, ":", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // "VEVENT"
-        ret = parseString(offset, "VEVENT", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.endRecord();
-        }
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // 1 * CRLF
-        ret = parseCrlf(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
-            offset += ret;
-            sum += ret;
-        }
-
-        return sum;
-    }
-
-    /**
-     * "BEGIN" [ws] ":" [ws] "VTODO" [ws] 1*CRLF entprops [ws] *CRLF "END" [ws]
-     * ":" [ws] "VTODO" [ws] 1*CRLF
-     */
-    private int parseTodoentity(int offset) {
-        int ret = 0, sum = 0;
-
-        ret = parseString(offset, "BEGIN", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // ":"
-        ret = parseString(offset, ":", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // "VTODO"
-        ret = parseString(offset, "VTODO", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.startRecord("VTODO");
-        }
-
-        // 1*CRLF
-        ret = parseCrlf(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
-            offset += ret;
-            sum += ret;
-        }
-
-        ret = parseEntprops(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // *CRLF
-        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
-            offset += ret;
-            sum += ret;
-        }
-
-        // "END"
-        ret = parseString(offset, "END", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // ":"
-        ret = parseString(offset, ":", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // "VTODO"
-        ret = parseString(offset, "VTODO", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.endRecord();
-        }
-
-        // [ws]
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        // 1 * CRLF
-        ret = parseCrlf(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        while (PARSE_ERROR != (ret = parseCrlf(offset))) {
-            offset += ret;
-            sum += ret;
-        }
-
-        return sum;
-    }
-
-    /**
-     * entprops *CRLF entprop / entprop
-     */
-    private int parseEntprops(int offset) {
-        int ret = 0, sum = 0;
-        if (mBuilder != null) {
-            mBuilder.startProperty();
-        }
-
-        ret = parseEntprop(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.endProperty();
-        }
-
-        for (;;) {
-            while (PARSE_ERROR != (ret = parseCrlf(offset))) {
-                offset += ret;
-                sum += ret;
-            }
-            if (mBuilder != null) {
-                mBuilder.startProperty();
-            }
-
-            ret = parseEntprop(offset);
-            if (PARSE_ERROR == ret) {
-                break;
-            }
-            offset += ret;
-            sum += ret;
-            if (mBuilder != null) {
-                mBuilder.endProperty();
-            }
-        }
-        return sum;
-    }
-
-    /**
-     * for VEVENT,VTODO prop. entprop0 / entprop1
-     */
-    private int parseEntprop(int offset) {
-        int ret = 0;
-        ret = parseEntprop0(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseEntprop1(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-        return PARSE_ERROR;
-    }
-
-    /**
-     * Same with card. ";" [ws] paramlist
-     */
-    private int parseParams(int offset) {
-        int ret = 0, sum = 0;
-
-        ret = parseString(offset, ";", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        ret = parseParamlist(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        sum += ret;
-
-        return sum;
-    }
-
-    /**
-     * Same with card. paramlist [ws] ";" [ws] param / param
-     */
-    private int parseParamlist(int offset) {
-        int ret = 0, sum = 0;
-
-        ret = parseParam(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        int offsetTemp = offset;
-        int sumTemp = sum;
-        for (;;) {
-            ret = removeWs(offsetTemp);
-            offsetTemp += ret;
-            sumTemp += ret;
-
-            ret = parseString(offsetTemp, ";", false);
-            if (PARSE_ERROR == ret) {
-                return sum;
-            }
-            offsetTemp += ret;
-            sumTemp += ret;
-
-            ret = removeWs(offsetTemp);
-            offsetTemp += ret;
-            sumTemp += ret;
-
-            ret = parseParam(offsetTemp);
-            if (PARSE_ERROR == ret) {
-                break;
-            }
-            offsetTemp += ret;
-            sumTemp += ret;
-
-            // offset = offsetTemp;
-            sum = sumTemp;
-        }
-        return sum;
-    }
-
-    /**
-     * param0 - param7 / knowntype
-     */
-    private int parseParam(int offset) {
-        int ret = 0;
-
-        ret = parseParam0(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseParam1(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseParam2(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseParam3(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseParam4(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseParam5(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseParam6(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseParam7(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        int start = offset;
-        ret = parseKnownType(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamType(null);
-            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
-        }
-
-        return ret;
-    }
-
-    /**
-     * simprop AND "CLASS" AND "STATUS" The value of these properties are not
-     * seperated by ";"
-     *
-     * [ws] simprop [params] ":" value CRLF
-     */
-    private int parseEntprop0(int offset) {
-        int ret = 0, sum = 0, start = 0;
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        String propName = getWord(offset).toUpperCase();
-        if (!mEvtPropNameGroup1.contains(propName)) {
-            if (PARSE_ERROR == parseXWord(offset))
-                return PARSE_ERROR;
-        }
-        ret = propName.length();
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyName(propName);
-        }
-
-        ret = parseParams(offset);
-        if (PARSE_ERROR != ret) {
-            offset += ret;
-            sum += ret;
-        }
-
-        ret = parseString(offset, ":", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        start = offset;
-        ret = parseValue(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            ArrayList<String> v = new ArrayList<String>();
-            v.add(exportEntpropValue(propName, mBuffer.substring(start,
-                            offset)));
-            mBuilder.propertyValues(v);
-            // Filter value,match string, REFER:RFC
-            if (PARSE_ERROR == valueFilter(propName, v))
-                return PARSE_ERROR;
-        }
-
-        ret = parseCrlf(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        sum += ret;
-        return sum;
-    }
-
-    /**
-     * other event prop names except simprop AND "CLASS" AND "STATUS" The value
-     * of these properties are seperated by ";" [ws] proper name [params] ":"
-     * value CRLF
-     */
-    private int parseEntprop1(int offset) {
-        int ret = 0, sum = 0;
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        String propName = getWord(offset).toUpperCase();
-        if (!mEvtPropNameGroup2.contains(propName)) {
-            return PARSE_ERROR;
-        }
-        ret = propName.length();
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyName(propName);
-        }
-
-        ret = parseParams(offset);
-        if (PARSE_ERROR != ret) {
-            offset += ret;
-            sum += ret;
-        }
-
-        ret = parseString(offset, ":", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        int start = offset;
-        ret = parseValue(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        // mutil-values
-        if (mBuilder != null) {
-            int end = 0;
-            ArrayList<String> v = new ArrayList<String>();
-            Pattern p = Pattern
-                    .compile("([^;\\\\]*(\\\\[\\\\;:,])*[^;\\\\]*)(;?)");
-            Matcher m = p.matcher(mBuffer.substring(start, offset));
-            while (m.find()) {
-                String s = exportEntpropValue(propName, m.group(1));
-                v.add(s);
-                end = m.end();
-                if (offset == start + end) {
-                    String endValue = m.group(3);
-                    if (";".equals(endValue)) {
-                        v.add("");
-                    }
-                    break;
-                }
-            }
-            mBuilder.propertyValues(v);
-            // Filter value,match string, REFER:RFC
-            if (PARSE_ERROR == valueFilter(propName, v))
-                return PARSE_ERROR;
-        }
-
-        ret = parseCrlf(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        sum += ret;
-        return sum;
-    }
-
-    /**
-     * "TYPE" [ws] = [ws] ptypeval
-     */
-    private int parseParam0(int offset) {
-        int ret = 0, sum = 0, start = offset;
-
-        ret = parseString(offset, "TYPE", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamType(mBuffer.substring(start, offset));
-        }
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        ret = parseString(offset, "=", false);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        start = offset;
-        ret = parsePtypeval(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
-        }
-        return sum;
-    }
-
-    /**
-     * ["VALUE" [ws] "=" [ws]] pvalueval
-     */
-    private int parseParam1(int offset) {
-        int ret = 0, sum = 0, start = offset;
-        boolean flag = false;
-
-        ret = parseString(offset, "VALUE", true);
-        if (PARSE_ERROR != ret) {
-            offset += ret;
-            sum += ret;
-            flag = true;
-        }
-        if (flag == true && mBuilder != null) {
-            mBuilder.propertyParamType(mBuffer.substring(start, offset));
-        }
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        ret = parseString(offset, "=", true);
-        if (PARSE_ERROR != ret) {
-            if (flag == false) { // "VALUE" does not exist
-                return PARSE_ERROR;
-            }
-            offset += ret;
-            sum += ret;
-        } else {
-            if (flag == true) { // "VALUE" exists
-                return PARSE_ERROR;
-            }
-        }
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        start = offset;
-        ret = parsePValueVal(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
-        }
-
-        return sum;
-    }
-
-    /** ["ENCODING" [ws] "=" [ws]] pencodingval */
-    private int parseParam2(int offset) {
-        int ret = 0, sum = 0, start = offset;
-        boolean flag = false;
-
-        ret = parseString(offset, "ENCODING", true);
-        if (PARSE_ERROR != ret) {
-            offset += ret;
-            sum += ret;
-            flag = true;
-        }
-        if (flag == true && mBuilder != null) {
-            mBuilder.propertyParamType(mBuffer.substring(start, offset));
-        }
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        ret = parseString(offset, "=", true);
-        if (PARSE_ERROR != ret) {
-            if (flag == false) { // "VALUE" does not exist
-                return PARSE_ERROR;
-            }
-            offset += ret;
-            sum += ret;
-        } else {
-            if (flag == true) { // "VALUE" exists
-                return PARSE_ERROR;
-            }
-        }
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        start = offset;
-        ret = parsePEncodingVal(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
-        }
-
-        return sum;
-    }
-
-    /**
-     * "CHARSET" [WS] "=" [WS] charsetval
-     */
-    private int parseParam3(int offset) {
-        int ret = 0, sum = 0, start = offset;
-
-        ret = parseString(offset, "CHARSET", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamType(mBuffer.substring(start, offset));
-        }
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        ret = parseString(offset, "=", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        start = offset;
-        ret = parseCharsetVal(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
-        }
-
-        return sum;
-    }
-
-    /**
-     * "LANGUAGE" [ws] "=" [ws] langval
-     */
-    private int parseParam4(int offset) {
-        int ret = 0, sum = 0, start = offset;
-
-        ret = parseString(offset, "LANGUAGE", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamType(mBuffer.substring(start, offset));
-        }
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        ret = parseString(offset, "=", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        start = offset;
-        ret = parseLangVal(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
-        }
-
-        return sum;
-    }
-
-    /**
-     * "ROLE" [ws] "=" [ws] roleval
-     */
-    private int parseParam5(int offset) {
-        int ret = 0, sum = 0, start = offset;
-
-        ret = parseString(offset, "ROLE", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamType(mBuffer.substring(start, offset));
-        }
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        ret = parseString(offset, "=", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        start = offset;
-        ret = parseRoleVal(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
-        }
-
-        return sum;
-    }
-
-    /**
-     * "STATUS" [ws] = [ws] statuval
-     */
-    private int parseParam6(int offset) {
-        int ret = 0, sum = 0, start = offset;
-
-        ret = parseString(offset, "STATUS", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamType(mBuffer.substring(start, offset));
-        }
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        ret = parseString(offset, "=", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        start = offset;
-        ret = parseStatuVal(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
-        }
-
-        return sum;
-
-    }
-
-    /**
-     * XWord [ws] "=" [ws] word
-     */
-    private int parseParam7(int offset) {
-        int ret = 0, sum = 0, start = offset;
-
-        ret = parseXWord(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamType(mBuffer.substring(start, offset));
-        }
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        ret = parseString(offset, "=", true);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        start = offset;
-        ret = parseWord(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-        if (mBuilder != null) {
-            mBuilder.propertyParamValue(mBuffer.substring(start, offset));
-        }
-
-        return sum;
-
-    }
-
-    /*
-     * "WAVE" / "PCM" / "VCARD" / XWORD
-     */
-    private int parseKnownType(int offset) {
-        int ret = 0;
-
-        ret = parseString(offset, "WAVE", true);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseString(offset, "PCM", true);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseString(offset, "VCARD", true);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseXWord(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        return PARSE_ERROR;
-    }
-
-    /*
-     * knowntype / Xword
-     */
-    private int parsePtypeval(int offset) {
-        int ret = 0;
-
-        ret = parseKnownType(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseXWord(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        return PARSE_ERROR;
-    }
-
-    /**
-     * "ATTENDEE" / "ORGANIZER" / "OWNER" / XWORD
-     */
-    private int parseRoleVal(int offset) {
-        int ret = 0;
-
-        ret = parseString(offset, "ATTENDEE", true);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseString(offset, "ORGANIZER", true);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseString(offset, "OWNER", true);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseXWord(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        return PARSE_ERROR;
-    }
-
-    /**
-     * "ACCEPTED" / "NEED ACTION" / "SENT" / "TENTATIVE" / "CONFIRMED" /
-     * "DECLINED" / "COMPLETED" / "DELEGATED / XWORD
-     */
-    private int parseStatuVal(int offset) {
-        int ret = 0;
-
-        ret = parseString(offset, "ACCEPTED", true);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseString(offset, "NEED ACTION", true);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseString(offset, "TENTATIVE", true);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-        ret = parseString(offset, "CONFIRMED", true);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-        ret = parseString(offset, "DECLINED", true);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-        ret = parseString(offset, "COMPLETED", true);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-        ret = parseString(offset, "DELEGATED", true);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        ret = parseXWord(offset);
-        if (PARSE_ERROR != ret) {
-            return ret;
-        }
-
-        return PARSE_ERROR;
-    }
-
-    /**
-     * Check 4 special propName and it's value to match Hash.
-     *
-     * @return PARSE_ERROR:value not match. 1:go on,like nothing happen.
-     */
-    private int valueFilter(String propName, ArrayList<String> values) {
-        if (propName == null || propName.equals("") || values == null
-                || values.isEmpty())
-            return 1; // go on, like nothing happen.
-
-        if (mSpecialValueSetMap.containsKey(propName)) {
-            for (String value : values) {
-                if (!mSpecialValueSetMap.get(propName).contains(value)) {
-                    if (!value.startsWith("X-"))
-                        return PARSE_ERROR;
-                }
-            }
-        }
-
-        return 1;
-    }
-
-    /**
-     *
-     * Translate escape characters("\\", "\;") which define in vcalendar1.0
-     * spec. But for fault tolerance, we will translate "\:" and "\,", which
-     * isn't define in vcalendar1.0 explicitly, as the same behavior as other
-     * client.
-     *
-     * Though vcalendar1.0 spec does not defined the value of property
-     * "description", "summary", "aalarm", "dalarm", "malarm" and "palarm" could
-     * contain escape characters, we do support escape characters in these
-     * properties.
-     *
-     * @param str:
-     *            the value string will be translated.
-     * @return the string which do not contain any escape character in
-     *         vcalendar1.0
-     */
-    private String exportEntpropValue(String propName, String str) {
-        if (null == propName || null == str)
-            return null;
-        if ("".equals(propName) || "".equals(str))
-            return "";
-
-        if (!mEscAllowedProps.contains(propName))
-            return str;
-
-        String tmp = str.replace("\\\\", "\n\r\n");
-        tmp = tmp.replace("\\;", ";");
-        tmp = tmp.replace("\\:", ":");
-        tmp = tmp.replace("\\,", ",");
-        tmp = tmp.replace("\n\r\n", "\\");
-        return tmp;
-    }
-}
diff --git a/core/java/android/syncml/pim/vcalendar/VCalParser_V20.java b/core/java/android/syncml/pim/vcalendar/VCalParser_V20.java
deleted file mode 100644
index 5748379..0000000
--- a/core/java/android/syncml/pim/vcalendar/VCalParser_V20.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2007 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.syncml.pim.vcalendar;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.HashSet;
-
-import android.syncml.pim.VBuilder;
-
-public class VCalParser_V20 extends VCalParser_V10 {
-    private static final String V10LINEBREAKER = "\r\n";
-
-    private static final HashSet<String> acceptableComponents = new HashSet<String>(
-            Arrays.asList("VEVENT", "VTODO", "VALARM", "VTIMEZONE"));
-
-    private static final HashSet<String> acceptableV20Props = new HashSet<String>(
-            Arrays.asList("DESCRIPTION", "DTEND", "DTSTART", "DUE",
-                    "COMPLETED", "RRULE", "STATUS", "SUMMARY", "LOCATION"));
-
-    private boolean hasTZ = false; // MUST only have one TZ property
-
-    private String[] lines;
-
-    private int index;
-
-    @Override
-    public boolean parse(InputStream is, String encoding, VBuilder builder)
-            throws IOException {
-        // get useful info for android calendar, and alter to vcal 1.0
-        byte[] bytes = new byte[is.available()];
-        is.read(bytes);
-        String scStr = new String(bytes);
-        StringBuilder v10str = new StringBuilder("");
-
-        lines = splitProperty(scStr);
-        index = 0;
-
-        if ("BEGIN:VCALENDAR".equals(lines[index]))
-            v10str.append("BEGIN:VCALENDAR" + V10LINEBREAKER);
-        else
-            return false;
-        index++;
-        if (false == parseV20Calbody(lines, v10str)
-                || index > lines.length - 1)
-            return false;
-
-        if (lines.length - 1 == index && "END:VCALENDAR".equals(lines[index]))
-            v10str.append("END:VCALENDAR" + V10LINEBREAKER);
-        else
-            return false;
-
-        return super.parse(
-                // use vCal 1.0 parser
-                new ByteArrayInputStream(v10str.toString().getBytes()),
-                encoding, builder);
-    }
-
-    /**
-     * Parse and pick acceptable iCalendar body and translate it to
-     * calendarV1.0 format.
-     * @param lines iCalendar components/properties line list.
-     * @param buffer calendarV10 format string buffer
-     * @return true for success, or false
-     */
-    private boolean parseV20Calbody(String[] lines, StringBuilder buffer) {
-        try {
-            while (!"VERSION:2.0".equals(lines[index]))
-                index++;
-            buffer.append("VERSION:1.0" + V10LINEBREAKER);
-
-            index++;
-            for (; index < lines.length - 1; index++) {
-                String[] keyAndValue = lines[index].split(":", 2);
-                String key = keyAndValue[0];
-                String value = keyAndValue[1];
-
-                if ("BEGIN".equals(key.trim())) {
-                    if (!key.equals(key.trim()))
-                        return false; // MUST be "BEGIN:componentname"
-                    index++;
-                    if (false == parseV20Component(value, buffer))
-                        return false;
-                }
-            }
-        } catch (ArrayIndexOutOfBoundsException e) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Parse and pick acceptable calendar V2.0's component and translate it to
-     * V1.0 format.
-     * @param compName component name
-     * @param buffer calendarV10 format string buffer
-     * @return true for success, or false
-     * @throws ArrayIndexOutOfBoundsException
-     */
-    private boolean parseV20Component(String compName, StringBuilder buffer)
-            throws ArrayIndexOutOfBoundsException {
-        String endTag = "END:" + compName;
-        String[] propAndValue;
-        String propName, value;
-
-        if (acceptableComponents.contains(compName)) {
-            if ("VEVENT".equals(compName) || "VTODO".equals(compName)) {
-                buffer.append("BEGIN:" + compName + V10LINEBREAKER);
-                while (!endTag.equals(lines[index])) {
-                    propAndValue = lines[index].split(":", 2);
-                    propName = propAndValue[0].split(";", 2)[0];
-                    value = propAndValue[1];
-
-                    if ("".equals(lines[index]))
-                        buffer.append(V10LINEBREAKER);
-                    else if (acceptableV20Props.contains(propName)) {
-                        buffer.append(propName + ":" + value + V10LINEBREAKER);
-                    } else if ("BEGIN".equals(propName.trim())) {
-                        // MUST be BEGIN:VALARM
-                        if (propName.equals(propName.trim())
-                                && "VALARM".equals(value)) {
-                            buffer.append("AALARM:default" + V10LINEBREAKER);
-                            while (!"END:VALARM".equals(lines[index]))
-                                index++;
-                        } else
-                            return false;
-                    }
-                    index++;
-                } // end while
-                buffer.append(endTag + V10LINEBREAKER);
-            } else if ("VALARM".equals(compName)) { // VALARM component MUST
-                // only appear within either VEVENT or VTODO
-                return false;
-            } else if ("VTIMEZONE".equals(compName)) {
-                do {
-                    if (false == hasTZ) {// MUST only have 1 time TZ property
-                        propAndValue = lines[index].split(":", 2);
-                        propName = propAndValue[0].split(";", 2)[0];
-
-                        if ("TZOFFSETFROM".equals(propName)) {
-                            value = propAndValue[1];
-                            buffer.append("TZ" + ":" + value + V10LINEBREAKER);
-                            hasTZ = true;
-                        }
-                    }
-                    index++;
-                } while (!endTag.equals(lines[index]));
-            } else
-                return false;
-        } else {
-            while (!endTag.equals(lines[index]))
-                index++;
-        }
-
-        return true;
-    }
-
-    /** split ever property line to String[], not split folding line. */
-    private String[] splitProperty(String scStr) {
-        /*
-         * Property splitted by \n, and unfold folding lines by removing
-         * CRLF+LWSP-char
-         */
-        scStr = scStr.replaceAll("\r\n", "\n").replaceAll("\n ", "")
-                .replaceAll("\n\t", "");
-        String[] strs = scStr.split("\n");
-        return strs;
-    }
-}
diff --git a/core/java/android/syncml/pim/vcalendar/package.html b/core/java/android/syncml/pim/vcalendar/package.html
deleted file mode 100644
index cb4ca46..0000000
--- a/core/java/android/syncml/pim/vcalendar/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<BODY>
-Support classes for SyncML.
-{@hide}
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/core/java/android/syncml/pim/vcard/ContactStruct.java b/core/java/android/syncml/pim/vcard/ContactStruct.java
index 4b4c394..687c1b4 100644
--- a/core/java/android/syncml/pim/vcard/ContactStruct.java
+++ b/core/java/android/syncml/pim/vcard/ContactStruct.java
@@ -49,8 +49,11 @@
  * This class standy by the person-contact in
  * Android system, we must use this class instance as parameter to transmit to
  * VCardComposer so that create vCard string.
+ * 
+ * @deprecated Please use the new code in android.pim.vcard
  */
 // TODO: rename the class name, next step
+@Deprecated
 public class ContactStruct {
     private static final String LOG_TAG = "ContactStruct";
     
diff --git a/core/java/android/syncml/pim/vcard/VCardComposer.java b/core/java/android/syncml/pim/vcard/VCardComposer.java
index 192736a..9823015 100644
--- a/core/java/android/syncml/pim/vcard/VCardComposer.java
+++ b/core/java/android/syncml/pim/vcard/VCardComposer.java
@@ -29,7 +29,10 @@
 
 /**
  * Compose VCard string
+ * 
+ * @depricated Please use the code in android.pim.vcard
  */
+@Deprecated
 public class VCardComposer {
     final public static int VERSION_VCARD21_INT = 1;
 
diff --git a/core/java/android/syncml/pim/vcard/VCardDataBuilder.java b/core/java/android/syncml/pim/vcard/VCardDataBuilder.java
index f2a2733..5fd8fdf 100644
--- a/core/java/android/syncml/pim/vcard/VCardDataBuilder.java
+++ b/core/java/android/syncml/pim/vcard/VCardDataBuilder.java
@@ -47,7 +47,10 @@
  * If we store all VNode entries in memory like VDataBuilder.java,
  * OutOfMemoryError may be thrown. Thus, this class push each VCard entry into
  * ContentResolver immediately.
+ * 
+ * @depricated Please use the code in android.pim.vcard
  */
+@Deprecated
 public class VCardDataBuilder implements VBuilder {
     static private String LOG_TAG = "VCardDataBuilder"; 
     
diff --git a/core/java/android/syncml/pim/vcard/VCardEntryCounter.java b/core/java/android/syncml/pim/vcard/VCardEntryCounter.java
index 03cd1d9..11372ce 100644
--- a/core/java/android/syncml/pim/vcard/VCardEntryCounter.java
+++ b/core/java/android/syncml/pim/vcard/VCardEntryCounter.java
@@ -20,6 +20,10 @@
 
 import android.syncml.pim.VBuilder;
 
+/**
+ * @depricated Please use the code in android.pim.vcard
+ */
+@Deprecated
 public class VCardEntryCounter implements VBuilder {
     private int mCount;
     
diff --git a/core/java/android/syncml/pim/vcard/VCardException.java b/core/java/android/syncml/pim/vcard/VCardException.java
index 35b31ec..326aa7f 100644
--- a/core/java/android/syncml/pim/vcard/VCardException.java
+++ b/core/java/android/syncml/pim/vcard/VCardException.java
@@ -16,6 +16,10 @@
 
 package android.syncml.pim.vcard;
 
+/**
+ * @depricated Please use the code in android.pim.vcard
+ */
+@Deprecated
 public class VCardException extends java.lang.Exception{
     // constructors
 
diff --git a/core/java/android/syncml/pim/vcard/VCardNestedException.java b/core/java/android/syncml/pim/vcard/VCardNestedException.java
index def6f3b7..5c49e40 100644
--- a/core/java/android/syncml/pim/vcard/VCardNestedException.java
+++ b/core/java/android/syncml/pim/vcard/VCardNestedException.java
@@ -18,7 +18,10 @@
 
 /**
  * VCardException thrown when VCard is nested without VCardParser's being notified.
+ *
+ * @depricated Please use the code in android.pim.vcard
  */
+@Deprecated
 public class VCardNestedException extends VCardException {
     public VCardNestedException() {}
     public VCardNestedException(String message) {
diff --git a/core/java/android/syncml/pim/vcard/VCardParser.java b/core/java/android/syncml/pim/vcard/VCardParser.java
index 9a590dd..a562973 100644
--- a/core/java/android/syncml/pim/vcard/VCardParser.java
+++ b/core/java/android/syncml/pim/vcard/VCardParser.java
@@ -23,6 +23,10 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 
+/**
+ * @deprecated Please use the code in android.pim.vcard
+ */
+@Deprecated
 public class VCardParser {
 
     // TODO: fix this.
diff --git a/core/java/android/syncml/pim/vcard/VCardParser_V21.java b/core/java/android/syncml/pim/vcard/VCardParser_V21.java
index d865668..75ce564 100644
--- a/core/java/android/syncml/pim/vcard/VCardParser_V21.java
+++ b/core/java/android/syncml/pim/vcard/VCardParser_V21.java
@@ -31,7 +31,10 @@
 
 /**
  * This class is used to parse vcard. Please refer to vCard Specification 2.1.
+ *
+ * @deprecated Please use the code in android.pim.vcard
  */
+@Deprecated
 public class VCardParser_V21 {
     private static final String LOG_TAG = "VCardParser_V21";
     
diff --git a/core/java/android/syncml/pim/vcard/VCardParser_V30.java b/core/java/android/syncml/pim/vcard/VCardParser_V30.java
index e67525e..3aca258 100644
--- a/core/java/android/syncml/pim/vcard/VCardParser_V30.java
+++ b/core/java/android/syncml/pim/vcard/VCardParser_V30.java
@@ -25,7 +25,10 @@
 /**
  * This class is used to parse vcard3.0. <br>
  * Please refer to vCard Specification 3.0 (http://tools.ietf.org/html/rfc2426)
+ * 
+ * @deprecated Please use the code in android.pim.vcard
  */
+@Deprecated
 public class VCardParser_V30 extends VCardParser_V21 {
     private static final String LOG_TAG = "VCardParser_V30";
     
diff --git a/core/java/android/syncml/pim/vcard/VCardSourceDetector.java b/core/java/android/syncml/pim/vcard/VCardSourceDetector.java
index 8c48391..6873f04 100644
--- a/core/java/android/syncml/pim/vcard/VCardSourceDetector.java
+++ b/core/java/android/syncml/pim/vcard/VCardSourceDetector.java
@@ -26,8 +26,10 @@
 /**
  * Class which tries to detects the source of the vCard from its properties.
  * Currently this implementation is very premature.
- * @hide
+ * 
+ * @deprecated Please use the code in android.pim.vcard
  */
+@Deprecated
 public class VCardSourceDetector implements VBuilder {
     // Should only be used in package. 
     static final int TYPE_UNKNOWN = 0;
diff --git a/core/java/android/syncml/pim/vcard/VCardVersionException.java b/core/java/android/syncml/pim/vcard/VCardVersionException.java
index 1ca88d1..14bb45b 100644
--- a/core/java/android/syncml/pim/vcard/VCardVersionException.java
+++ b/core/java/android/syncml/pim/vcard/VCardVersionException.java
@@ -17,8 +17,11 @@
 package android.syncml.pim.vcard;
 
 /**
- * VCardException used only when the version of the vCard is different. 
+ * VCardException used only when the version of the vCard is different.
+ * 
+ * @deprecated Please use the code in android.pim.vcard
  */
+@Deprecated
 public class VCardVersionException extends VCardException {
     public VCardVersionException() {
     }
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index ea879ed9..1426aef 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -124,6 +124,8 @@
     };
     
     boolean mRequestedVisible = false;
+    boolean mWindowVisibility = false;
+    boolean mViewVisibility = false;
     int mRequestedWidth = -1;
     int mRequestedHeight = -1;
     int mRequestedFormat = PixelFormat.OPAQUE;
@@ -176,12 +178,22 @@
         mSession = getWindowSession();
         mLayout.token = getWindowToken();
         mLayout.setTitle("SurfaceView");
+        mViewVisibility = getVisibility() == VISIBLE;
     }
 
     @Override
     protected void onWindowVisibilityChanged(int visibility) {
         super.onWindowVisibilityChanged(visibility);
-        mRequestedVisible = visibility == VISIBLE;
+        mWindowVisibility = visibility == VISIBLE;
+        mRequestedVisible = mWindowVisibility && mViewVisibility;
+        updateWindow(false);
+    }
+
+    @Override
+    public void setVisibility(int visibility) {
+        super.setVisibility(visibility);
+        mViewVisibility = visibility == VISIBLE;
+        mRequestedVisible = mWindowVisibility && mViewVisibility;
         updateWindow(false);
     }
     
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index e96ba11..db6b74f 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -455,8 +455,6 @@
             mJSInterfaceMap.remove(interfaceName);
         }
         mJSInterfaceMap.put(interfaceName, obj);
-        nativeAddJavascriptInterface(0, mJSInterfaceMap.get(interfaceName),
-                interfaceName);
     }
 
     /**
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 1a5b2eb..aee8a6d 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -410,7 +410,8 @@
                 mStatusCode == HTTP_MOVED_PERMANENTLY ||
                 mStatusCode == HTTP_TEMPORARY_REDIRECT) && 
                 mNativeLoader != 0) {
-            if (!mFromCache && URLUtil.isNetworkUrl(mUrl)) {
+            if (!mFromCache && mRequestHandle != null
+                    && !mRequestHandle.getMethod().equals("POST")) {
                 mCacheResult = CacheManager.createCacheFile(mUrl, mStatusCode,
                         headers, mMimeType, false);
             }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 8a986fa..8446475 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -46,6 +46,7 @@
 import android.util.AttributeSet;
 import android.util.EventLog;
 import android.util.Log;
+import android.util.TypedValue;
 import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -2048,6 +2049,10 @@
     protected int computeHorizontalScrollRange() {
         if (mDrawHistory) {
             return mHistoryWidth;
+        } else if (mLastWidthSent == mContentWidth) {
+            // special case to avoid rounding error. Otherwise we may get a
+            // faked scrollbar sometimes.
+            return getViewWidth();
         } else {
             return contentToViewDimension(mContentWidth);
         }
@@ -2061,7 +2066,14 @@
         if (mDrawHistory) {
             return mHistoryHeight;
         } else {
-            int height = contentToViewDimension(mContentHeight);
+            int height;
+            // special case to avoid rounding error. Otherwise we may get a
+            // faked scrollbar sometimes.
+            if (mLastHeightSent == mContentHeight) {
+                height = getViewHeight();
+            } else {
+                height = contentToViewDimension(mContentHeight);
+            }
             if (mFindIsUp) {
                 height += FIND_HEIGHT;
             }
@@ -2768,7 +2780,8 @@
                 mZoomScale = 0;
                 if (mNeedToAdjustWebTextView) {
                     mNeedToAdjustWebTextView = false;
-                    mWebTextView.setTextSize(contentToViewDimension(
+                    mWebTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+                            contentToViewDimension(
                             nativeFocusCandidateTextSize()));
                     Rect bounds = nativeFocusCandidateNodeBounds();
                     Rect vBox = contentToView(bounds);
@@ -3333,7 +3346,8 @@
             // Initialize our generation number.
             mTextGeneration = 0;
         }
-        mWebTextView.setTextSize(contentToViewDimension(nativeFocusCandidateTextSize()));
+        mWebTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+                contentToViewDimension(nativeFocusCandidateTextSize()));
         Rect visibleRect = new Rect();
         calcOurContentVisibleRect(visibleRect);
         // Note that sendOurVisibleRect calls viewToContent, so the coordinates
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index 4c9451e..9e1f325 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -185,7 +185,7 @@
         
         try {
             bluetoothOff = bluetooth == null ||
-                           bluetooth.getBluetoothState() == BluetoothAdapter.BLUETOOTH_STATE_OFF;
+                           bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
             if (!bluetoothOff) {
                 Log.w(TAG, "Disabling Bluetooth...");
                 bluetooth.disable(false);  // disable but don't persist new state
@@ -213,7 +213,7 @@
             if (!bluetoothOff) {
                 try {
                     bluetoothOff =
-                            bluetooth.getBluetoothState() == BluetoothAdapter.BLUETOOTH_STATE_OFF;
+                            bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
                 } catch (RemoteException ex) {
                     Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
                     bluetoothOff = true;
diff --git a/core/java/com/android/internal/widget/NumberPicker.java b/core/java/com/android/internal/widget/NumberPicker.java
index 0424ced..ae08eca 100644
--- a/core/java/com/android/internal/widget/NumberPicker.java
+++ b/core/java/com/android/internal/widget/NumberPicker.java
@@ -36,7 +36,7 @@
 
 public class NumberPicker extends LinearLayout implements OnClickListener,
         OnFocusChangeListener, OnLongClickListener {
-        
+
     public interface OnChangedListener {
         void onChanged(NumberPicker picker, int oldVal, int newVal);
     }
@@ -51,7 +51,7 @@
      * most efficient way to do this; it avoids creating temporary objects
      * on every call to format().
      */
-    public static final NumberPicker.Formatter TWO_DIGIT_FORMATTER = 
+    public static final NumberPicker.Formatter TWO_DIGIT_FORMATTER =
             new NumberPicker.Formatter() {
                 final StringBuilder mBuilder = new StringBuilder();
                 final java.util.Formatter mFmt = new java.util.Formatter(mBuilder);
@@ -63,7 +63,7 @@
                     return mFmt.toString();
                 }
         };
-    
+
     private final Handler mHandler;
     private final Runnable mRunnable = new Runnable() {
         public void run() {
@@ -81,21 +81,21 @@
     private final InputFilter mNumberInputFilter;
 
     private String[] mDisplayedValues;
-    private int mStart;
-    private int mEnd;
-    private int mCurrent;
-    private int mPrevious;
+    protected int mStart;
+    protected int mEnd;
+    protected int mCurrent;
+    protected int mPrevious;
     private OnChangedListener mListener;
     private Formatter mFormatter;
     private long mSpeed = 300;
-    
+
     private boolean mIncrement;
     private boolean mDecrement;
-    
+
     public NumberPicker(Context context) {
         this(context, null);
     }
-    
+
     public NumberPicker(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
@@ -117,7 +117,7 @@
         mDecrementButton.setOnClickListener(this);
         mDecrementButton.setOnLongClickListener(this);
         mDecrementButton.setNumberPicker(this);
-        
+
         mText = (EditText) findViewById(R.id.timepicker_input);
         mText.setOnFocusChangeListener(this);
         mText.setFilters(new InputFilter[] {inputFilter});
@@ -127,7 +127,7 @@
             setEnabled(false);
         }
     }
-    
+
     @Override
     public void setEnabled(boolean enabled) {
         super.setEnabled(enabled);
@@ -135,19 +135,19 @@
         mDecrementButton.setEnabled(enabled);
         mText.setEnabled(enabled);
     }
-    
+
     public void setOnChangeListener(OnChangedListener listener) {
         mListener = listener;
     }
-    
+
     public void setFormatter(Formatter formatter) {
         mFormatter = formatter;
     }
-    
+
     /**
      * Set the range of numbers allowed for the number picker. The current
      * value will be automatically set to the start.
-     * 
+     *
      * @param start the start of the range (inclusive)
      * @param end the end of the range (inclusive)
      */
@@ -157,12 +157,12 @@
         mCurrent = start;
         updateView();
     }
-    
+
     /**
      * Set the range of numbers allowed for the number picker. The current
      * value will be automatically set to the start. Also provide a mapping
      * for values used to display to the user.
-     * 
+     *
      * @param start the start of the range (inclusive)
      * @param end the end of the range (inclusive)
      * @param displayedValues the values displayed to the user.
@@ -174,7 +174,7 @@
         mCurrent = start;
         updateView();
     }
-    
+
     public void setCurrent(int current) {
         mCurrent = current;
         updateView();
@@ -187,7 +187,7 @@
     public void setSpeed(long speed) {
         mSpeed = speed;
     }
-    
+
     public void onClick(View v) {
         validateInput(mText);
         if (!mText.hasFocus()) mText.requestFocus();
@@ -199,15 +199,15 @@
             changeCurrent(mCurrent - 1);
         }
     }
-    
+
     private String formatNumber(int value) {
         return (mFormatter != null)
                 ? mFormatter.toString(value)
                 : String.valueOf(value);
     }
- 
-    private void changeCurrent(int current) {
-        
+
+    protected void changeCurrent(int current) {
+
         // Wrap around the values if we go past the start or end
         if (current > mEnd) {
             current = mStart;
@@ -219,15 +219,15 @@
         notifyChange();
         updateView();
     }
-    
-    private void notifyChange() {
+
+    protected void notifyChange() {
         if (mListener != null) {
             mListener.onChanged(this, mPrevious, mCurrent);
         }
     }
 
-    private void updateView() {
-        
+    protected void updateView() {
+
         /* If we don't have displayed values then use the
          * current number else find the correct value in the
          * displayed values for the current number.
@@ -239,7 +239,7 @@
         }
         mText.setSelection(mText.getText().length());
     }
-    
+
     private void validateCurrentView(CharSequence str) {
         int val = getSelectedPos(str.toString());
         if ((val >= mStart) && (val <= mEnd)) {
@@ -253,7 +253,7 @@
     }
 
     public void onFocusChange(View v, boolean hasFocus) {
-        
+
         /* When focus is lost check that the text field
          * has valid values.
          */
@@ -280,12 +280,12 @@
      * to inform us when the long click has ended.
      */
     public boolean onLongClick(View v) {
-        
+
         /* The text view may still have focus so clear it's focus which will
          * trigger the on focus changed and any typed values to be pulled.
          */
         mText.clearFocus();
-        
+
         if (R.id.increment == v.getId()) {
             mIncrement = true;
             mHandler.post(mRunnable);
@@ -295,22 +295,22 @@
         }
         return true;
     }
-    
+
     public void cancelIncrement() {
         mIncrement = false;
     }
-    
+
     public void cancelDecrement() {
         mDecrement = false;
     }
-    
+
     private static final char[] DIGIT_CHARACTERS = new char[] {
         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
     };
-    
+
     private NumberPickerButton mIncrementButton;
     private NumberPickerButton mDecrementButton;
-    
+
     private class NumberPickerInputFilter implements InputFilter {
         public CharSequence filter(CharSequence source, int start, int end,
                 Spanned dest, int dstart, int dend) {
@@ -331,7 +331,7 @@
             return "";
         }
     }
-    
+
     private class NumberRangeKeyListener extends NumberKeyListener {
 
         // XXX This doesn't allow for range limits when controlled by a
@@ -339,12 +339,12 @@
         public int getInputType() {
             return InputType.TYPE_CLASS_NUMBER;
         }
-        
+
         @Override
         protected char[] getAcceptedChars() {
             return DIGIT_CHARACTERS;
         }
-        
+
         @Override
         public CharSequence filter(CharSequence source, int start, int end,
                 Spanned dest, int dstart, int dend) {
@@ -381,21 +381,21 @@
             return Integer.parseInt(str);
         } else {
             for (int i = 0; i < mDisplayedValues.length; i++) {
-                
+
                 /* Don't force the user to type in jan when ja will do */
                 str = str.toLowerCase();
                 if (mDisplayedValues[i].toLowerCase().startsWith(str)) {
                     return mStart + i;
                 }
             }
-            
+
             /* The user might have typed in a number into the month field i.e.
              * 10 instead of OCT so support that too.
              */
             try {
                 return Integer.parseInt(str);
             } catch (NumberFormatException e) {
-                
+
                 /* Ignore as if it's not a number we don't care */
             }
         }
diff --git a/core/jni/android_media_ToneGenerator.cpp b/core/jni/android_media_ToneGenerator.cpp
index a4388de..07bb1ab 100644
--- a/core/jni/android_media_ToneGenerator.cpp
+++ b/core/jni/android_media_ToneGenerator.cpp
@@ -38,7 +38,7 @@
 };
 static fields_t fields;
 
-static jboolean android_media_ToneGenerator_startTone(JNIEnv *env, jobject thiz, jint toneType) {
+static jboolean android_media_ToneGenerator_startTone(JNIEnv *env, jobject thiz, jint toneType, jint durationMs) {
     LOGV("android_media_ToneGenerator_startTone: %x\n", (int)thiz);
 
     ToneGenerator *lpToneGen = (ToneGenerator *)env->GetIntField(thiz,
@@ -48,7 +48,7 @@
         return false;
     }
 
-    return lpToneGen->startTone(toneType);
+    return lpToneGen->startTone(toneType, durationMs);
 }
 
 static void android_media_ToneGenerator_stopTone(JNIEnv *env, jobject thiz) {
@@ -120,7 +120,7 @@
 // ----------------------------------------------------------------------------
 
 static JNINativeMethod gMethods[] = {
-    { "startTone", "(I)Z", (void *)android_media_ToneGenerator_startTone },
+    { "startTone", "(II)Z", (void *)android_media_ToneGenerator_startTone },
     { "stopTone", "()V", (void *)android_media_ToneGenerator_stopTone },
     { "release", "()V", (void *)android_media_ToneGenerator_release },
     { "native_setup", "(II)V", (void *)android_media_ToneGenerator_native_setup },
diff --git a/core/res/res/drawable-hdpi/scrollbar_handle_accelerated_anim2.9.png b/core/res/res/drawable-hdpi/scrollbar_handle_accelerated_anim2.9.png
index b540cd3..c916780 100644
--- a/core/res/res/drawable-hdpi/scrollbar_handle_accelerated_anim2.9.png
+++ b/core/res/res/drawable-hdpi/scrollbar_handle_accelerated_anim2.9.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 6945f9e..dc8bf2f 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -15,7 +15,7 @@
                                 <div id="announcement" style="width:275px">
                                   <p>The second Android Developer Challenge has begun! In this contest,
                                   real-world users will help review and score applications and the overall winner will 
-                                  take away $250,000. The deadline for submissions was August 31, 2009 and judging by users has started.</p>
+                                  take away $250,000. The deadline for submissions was August 31, 2009.</p>
                                   <p><a href="http://code.google.com/android/adc/">Learn more about ADC 2 &raquo;</a></p>
                                 </div> <!-- end annoucement -->
                             </div> <!-- end annoucement-block -->  
diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h
index eafa661..ea6bf5d 100644
--- a/include/media/ToneGenerator.h
+++ b/include/media/ToneGenerator.h
@@ -154,7 +154,7 @@
     ToneGenerator(int streamType, float volume);
     ~ToneGenerator();
 
-    bool startTone(int toneType);
+    bool startTone(int toneType, int durationMs = -1);
     void stopTone();
 
     bool isInited() { return (mState == TONE_IDLE)?false:true;}
@@ -246,6 +246,7 @@
     // NOTE: because mTotalSmp, mNextSegSmp are stored on 32 bit, current design will operate properly
     // only if tone duration is less than about 27 Hours(@44100Hz sampling rate). If this time is exceeded,
     // no crash will occur but tone sequence will show a glitch.
+    unsigned int mMaxSmp;  // Maximum number of audio samples played (maximun tone duration)
 
     unsigned short mCurSegment;  // Current segment index in ToneDescriptor segments[]
     unsigned short mCurCount;  // Current sequence repeat count
diff --git a/include/media/stagefright/AMRExtractor.h b/include/media/stagefright/AMRExtractor.h
new file mode 100644
index 0000000..c8710d3
--- /dev/null
+++ b/include/media/stagefright/AMRExtractor.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#ifndef AMR_EXTRACTOR_H_
+
+#define AMR_EXTRACTOR_H_
+
+#include <media/stagefright/MediaExtractor.h>
+
+namespace android {
+
+class String8;
+
+class AMRExtractor : public MediaExtractor {
+public:
+    AMRExtractor(const sp<DataSource> &source);
+
+    virtual size_t countTracks();
+    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<MetaData> getTrackMetaData(size_t index);
+
+    static sp<MetaData> makeAMRFormat(bool isWide);
+
+protected:
+    virtual ~AMRExtractor();
+
+private:
+    sp<DataSource> mDataSource;
+    status_t mInitCheck;
+    bool mIsWide;
+
+    AMRExtractor(const AMRExtractor &);
+    AMRExtractor &operator=(const AMRExtractor &);
+};
+
+bool SniffAMR(
+        const sp<DataSource> &source, String8 *mimeType, float *confidence);
+
+}  // namespace android
+
+#endif  // AMR_EXTRACTOR_H_
diff --git a/include/media/stagefright/MP3Extractor.h b/include/media/stagefright/MP3Extractor.h
index 4e1f3c3..11ba01d 100644
--- a/include/media/stagefright/MP3Extractor.h
+++ b/include/media/stagefright/MP3Extractor.h
@@ -30,9 +30,9 @@
     // Extractor assumes ownership of "source".
     MP3Extractor(const sp<DataSource> &source);
 
-    size_t countTracks();
-    sp<MediaSource> getTrack(size_t index);
-    sp<MetaData> getTrackMetaData(size_t index);
+    virtual size_t countTracks();
+    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<MetaData> getTrackMetaData(size_t index);
 
 protected:
     virtual ~MP3Extractor();
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index ac45481..7f99553 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -138,6 +138,7 @@
     void setComponentRole();
 
     void setAMRFormat();
+    void setAMRWBFormat();
     void setAACFormat(int32_t numChannels, int32_t sampleRate);
 
     status_t setVideoPortFormatType(
diff --git a/include/utils/threads.h b/include/utils/threads.h
index e9b0788..0fc533f 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -408,6 +408,9 @@
     volatile bool           mExitPending;
     volatile bool           mRunning;
             sp<Thread>      mHoldSelf;
+#if HAVE_ANDROID_OS
+            int             mTid;
+#endif
 };
 
 
diff --git a/keystore/java/android/security/CertTool.java b/keystore/java/android/security/CertTool.java
index 6caeb3e..88d6e3d 100644
--- a/keystore/java/android/security/CertTool.java
+++ b/keystore/java/android/security/CertTool.java
@@ -16,6 +16,12 @@
 
 package android.security;
 
+import android.content.Context;
+import android.content.Intent;
+import android.security.Keystore;
+import android.text.TextUtils;
+import android.util.Log;
+
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.security.cert.Certificate;
@@ -23,16 +29,11 @@
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.UnrecoverableKeyException;
-
-import android.content.Context;
-import android.content.Intent;
-import android.security.Keystore;
-import android.text.TextUtils;
-import android.util.Log;
+import java.util.ArrayList;
 
 /**
  * The CertTool class provides the functions to list the certs/keys,
- * generate the certificate request(csr) and store the certificate into
+ * generate the certificate request(csr) and store certificates into
  * keystore.
  *
  * {@hide}
@@ -51,19 +52,129 @@
     /** Keystore namespace for user private keys. */
     public static final String USER_KEY = "USRKEY";
 
+    /** Action string for adding certificates to keystore. */
     public static final String ACTION_ADD_CREDENTIAL =
             "android.security.ADD_CREDENTIAL";
-    public static final String KEY_TYPE_NAME = "typeName";
-    public static final String KEY_ITEM = "item";
-    public static final String KEY_NAMESPACE = "namespace";
-    public static final String KEY_DESCRIPTION = "description";
 
+    /** Action string for installing certificates to keystore from sdcard. */
+    public static final String ACTION_INSTALL_CERT_FROM_SDCARD =
+            "android.security.INSTALL_CERT_FROM_SDCARD";
+
+    /** Dialog title for adding a CA certificate. */
     public static final String TITLE_CA_CERT = "CA Certificate";
+
+    /** Dialog title for adding a user certificate. */
     public static final String TITLE_USER_CERT = "User Certificate";
-    public static final String TITLE_PKCS12_KEYSTORE = "PKCS12 Keystore";
+
+    /** Dialog title for adding a user private key. */
     public static final String TITLE_PRIVATE_KEY = "Private Key";
+
+    /** Dialog title for adding a PKCS12 keystore. */
+    public static final String TITLE_PKCS12_KEYSTORE = "PKCS12 Keystore";
+
     public static final int INCORRECT_PKCS12_PASSPHRASE = -100;
 
+    /**
+     * The builder class for building an add-credential-to-keystore intent.
+     */
+    public static class AddCredentialIntentBuilder {
+        private Intent mIntent;
+        private int mCount;
+
+        /**
+         * Creates a builder to build a add-credential-to-keystore intent.
+         *
+         * @param title title of the dialog for adding this credential
+         * @param descriptions description strings to show on the dialog
+         */
+        public AddCredentialIntentBuilder(String title,
+                String... descriptions) {
+            Intent intent = new Intent(ACTION_ADD_CREDENTIAL);
+            intent.putExtra(KEY_TITLE, title);
+
+            int i = 0;
+            for (String description : descriptions) {
+                intent.putExtra(KEY_DESCRIPTION + (i++), description);
+            }
+            mIntent = intent;
+        }
+
+        /**
+         * Adds credential data to the intent.
+         *
+         * @param namespace the namespace of the keystore to add the credential
+         *      data to
+         * @param data the credential data
+         * @return this builder
+         */
+        public AddCredentialIntentBuilder addCredential(String namespace,
+                byte[] data) {
+            mIntent.putExtra(KEY_NAMESPACE + mCount, namespace);
+            mIntent.putExtra(KEY_ITEM + mCount, data);
+            mCount++;
+            return this;
+        }
+
+        /** Returns the intent. */
+        public Intent build() {
+            return mIntent;
+        }
+    }
+
+    /**
+     * Request for adding credential data to keystore.
+     */
+    public static class AddCredentialRequest {
+        private Intent mIntent;
+
+        /**
+         * Creates an add-credential-data-to-keystore request.
+         *
+         * @param intent an add-credential-data-to-keystore intent
+         * @see AddCredentialIntentBuilder
+         */
+        public AddCredentialRequest(Intent intent) {
+            mIntent = intent;
+        }
+
+        /** Returns the dialog title. */
+        public String getTitle() {
+            return mIntent.getStringExtra(KEY_TITLE);
+        }
+
+        /**
+         * Returns the i'th credential data.
+         * @return the data or null if not exists
+         */
+        public byte[] getDataAt(int i) {
+            return mIntent.getByteArrayExtra(KEY_ITEM + i);
+        }
+
+        /**
+         * Returns the namespace of the i'th credential data.
+         * @return the namespace string or null if missing
+         */
+        public String getNamespaceAt(int i) {
+            return mIntent.getStringExtra(KEY_NAMESPACE + i);
+        }
+
+        /** Returns the descriptions of the credential data. */
+        public String[] getDescriptions() {
+            ArrayList<String> list = new ArrayList<String>();
+            for (int i = 0; ; i++) {
+                String s = mIntent.getStringExtra(KEY_DESCRIPTION + i);
+                if (s == null) break;
+                list.add(s);
+            }
+            return list.toArray(new String[list.size()]);
+        }
+    }
+
+    private static final String KEY_TITLE = "typeName";
+    private static final String KEY_ITEM = "item";
+    private static final String KEY_NAMESPACE = "namespace";
+    private static final String KEY_DESCRIPTION = "description";
+
     private static final String TAG = "CertTool";
     private static final String UNKNOWN = "Unknown";
     private static final String ISSUER_NAME = "Issuer Name:";
@@ -86,33 +197,55 @@
     private native String getPrivateKeyPEM(int handle);
     private native void freeX509Certificate(int handle);
 
-    private static CertTool singleton = null;
+    private static CertTool sSingleton = null;
 
     private CertTool() { }
 
     public static final CertTool getInstance() {
-        if (singleton == null) {
-            singleton = new CertTool();
+        if (sSingleton == null) {
+            sSingleton = new CertTool();
         }
-        return singleton;
+        return sSingleton;
     }
 
+    /**
+     * Gets the full key to retrieve the user private key from the keystore.
+     * @see #getAllUserCertificateKeys()
+     */
     public String getUserPrivateKey(String key) {
         return USER_KEY + KEYNAME_DELIMITER + key;
     }
 
+    /**
+     * Gets the full key to retrieve the user certificate from the keystore.
+     * @see #getAllUserCertificateKeys()
+     */
     public String getUserCertificate(String key) {
         return USER_CERTIFICATE + KEYNAME_DELIMITER + key;
     }
 
+    /**
+     * Gets the full key to retrieve the CA certificate from the keystore.
+     * @see #getAllCaCertificateKeys()
+     */
     public String getCaCertificate(String key) {
         return CA_CERTIFICATE + KEYNAME_DELIMITER + key;
     }
 
+    /**
+     * Gets all the keys to the user certificates/private keys stored in the
+     * keystore.
+     * @see #getUserCertificate(String)
+     * @see #getUserPrivateKey(String)
+     */
     public String[] getAllUserCertificateKeys() {
         return sKeystore.listKeys(USER_KEY);
     }
 
+    /**
+     * Gets all the keys to the CA certificates stored in the keystore.
+     * @see #getCaCertificate(String)
+     */
     public String[] getAllCaCertificateKeys() {
         return sKeystore.listKeys(CA_CERTIFICATE);
     }
@@ -126,29 +259,21 @@
         return 1024;
     }
 
+    /**
+     * Generates a key pair.
+     *
+     * @param keyStrengthIndex index to the array of supported key strengths;
+     *      see {@link #getSupportedKeyStrenghs()}
+     * @param challenge the challenge string for generating the pair
+     * @param dirName (not used)
+     * @return a certificate request from the resulted public key
+     */
     public String generateKeyPair(int keyStrengthIndex, String challenge,
             String dirName) {
         return generateCertificateRequest(getKeyLength(keyStrengthIndex),
                 challenge);
     }
 
-    private Intent prepareIntent(String title, byte[] data, String namespace,
-            String issuer, String distinctName) {
-        Intent intent = new Intent(ACTION_ADD_CREDENTIAL);
-        intent.putExtra(KEY_TYPE_NAME, title);
-        intent.putExtra(KEY_ITEM + "0", data);
-        intent.putExtra(KEY_NAMESPACE + "0", namespace);
-        intent.putExtra(KEY_DESCRIPTION + "0", ISSUER_NAME + issuer);
-        intent.putExtra(KEY_DESCRIPTION + "1", DISTINCT_NAME + distinctName);
-        return intent;
-    }
-
-    private void addExtraIntentInfo(Intent intent, String namespace,
-            String data) {
-        intent.putExtra(KEY_ITEM + "1", data.getBytes());
-        intent.putExtra(KEY_NAMESPACE + "1", namespace);
-    }
-
     private int extractAndStoreKeysFromPkcs12(int handle, String keyname) {
         int ret, i = 0;
         String pemData;
@@ -171,6 +296,7 @@
         return 0;
     }
 
+    /** Adds a PKCS12 keystore to the keystore. */
     public int addPkcs12Keystore(byte[] p12Data, String password,
             String keyname) {
         int handle, ret;
@@ -184,27 +310,35 @@
         return ret;
     }
 
+    /**
+     * Adds a certificate to the keystore.
+     *
+     * @param data the certificate data
+     * @param context the context to send an add-credential-to-keystore intent
+     */
     public synchronized void addCertificate(byte[] data, Context context) {
         int handle;
         Intent intent = null;
 
         Log.i("CertTool", "addCertificate()");
         if (isPkcs12Keystore(data)) {
-            intent = prepareIntent(TITLE_PKCS12_KEYSTORE, data, USER_KEY,
-                    UNKNOWN, UNKNOWN);
+            intent = prepareIntent(TITLE_PKCS12_KEYSTORE, UNKNOWN, UNKNOWN)
+                    .addCredential(USER_KEY, data).build();
         } else if ((handle = generateX509Certificate(data)) != 0) {
             String issuer = getIssuerDN(handle);
             String distinctName = getCertificateDN(handle);
             String privateKeyPEM = getPrivateKeyPEM(handle);
             if (isCaCertificate(handle)) {
-                intent = prepareIntent(TITLE_CA_CERT, data, CA_CERTIFICATE,
-                        issuer, distinctName);
+                intent = prepareIntent(TITLE_CA_CERT, issuer, distinctName)
+                        .addCredential(CA_CERTIFICATE, data).build();
             } else {
-                intent = prepareIntent(TITLE_USER_CERT, data, USER_CERTIFICATE,
-                        issuer, distinctName);
+                AddCredentialIntentBuilder builder =
+                        prepareIntent(TITLE_USER_CERT, issuer, distinctName)
+                        .addCredential(USER_CERTIFICATE, data);
                 if (!TextUtils.isEmpty(privateKeyPEM)) {
-                    addExtraIntentInfo(intent, USER_KEY, privateKeyPEM);
+                    builder.addCredential(USER_KEY, privateKeyPEM.getBytes());
                 }
+                intent = builder.build();
             }
             freeX509Certificate(handle);
         }
@@ -214,4 +348,10 @@
             Log.w("CertTool", "incorrect data for addCertificate()");
         }
     }
+
+    private AddCredentialIntentBuilder prepareIntent(
+            String title, String issuer, String distinctName) {
+        return new AddCredentialIntentBuilder(title, ISSUER_NAME + issuer,
+                DISTINCT_NAME + distinctName);
+    }
 }
diff --git a/keystore/java/android/security/Keystore.java b/keystore/java/android/security/Keystore.java
index a6cfbca..a706c89 100644
--- a/keystore/java/android/security/Keystore.java
+++ b/keystore/java/android/security/Keystore.java
@@ -22,8 +22,9 @@
  */
 
 public abstract class Keystore {
-    private static final String TAG = "Keystore";
-    private static final String[] NOTFOUND = new String[0];
+    /** Action to unlock (or initialize) the keystore. */
+    public static final String ACTION_UNLOCK_CREDENTIAL_STORAGE =
+            "android.security.UNLOCK_CREDENTIAL_STORAGE";
 
     // Keystore States
     public static final int BOOTUP = 0;
@@ -31,8 +32,9 @@
     public static final int LOCKED = 2;
     public static final int UNLOCKED = 3;
 
-    /**
-     */
+    private static final String TAG = "Keystore";
+    private static final String[] NOTFOUND = new String[0];
+
     public static Keystore getInstance() {
         return new FileKeystore();
     }
@@ -53,7 +55,6 @@
         private static final String CA_CERTIFICATE = "CaCertificate";
         private static final String USER_CERTIFICATE = "UserCertificate";
         private static final String USER_KEY = "UserPrivateKey";
-        private static final String COMMAND_DELIMITER = " ";
         private static final ServiceCommand mServiceCommand =
                 new ServiceCommand(SERVICE_NAME);
 
@@ -80,7 +81,7 @@
         @Override
         public int changePassword(String oldPassword, String newPassword) {
             Reply result = mServiceCommand.execute(ServiceCommand.PASSWD,
-                    oldPassword + " " + newPassword);
+                    oldPassword + "\0" + newPassword + "\0");
             return (result != null) ? result.returnCode : -1;
         }
 
@@ -105,14 +106,14 @@
         @Override
         public int put(String namespace, String keyname, String value) {
             Reply result = mServiceCommand.execute(ServiceCommand.PUT_KEY,
-                    namespace + " " + keyname + " " + value);
+                    namespace + "\0" + keyname + "\0" + value);
             return (result != null) ? result.returnCode : -1;
         }
 
         @Override
         public String get(String namespace, String keyname) {
             Reply result = mServiceCommand.execute(ServiceCommand.GET_KEY,
-                    namespace + " " + keyname);
+                    namespace + "\0" + keyname + "\0");
             return (result != null) ? ((result.returnCode != 0) ? null :
                     new String(result.data, 0, result.len)) : null;
         }
@@ -120,7 +121,7 @@
         @Override
         public int remove(String namespace, String keyname) {
             Reply result = mServiceCommand.execute(ServiceCommand.REMOVE_KEY,
-                    namespace + " " + keyname);
+                    namespace + "\0" + keyname + "\0");
             return (result != null) ? result.returnCode : -1;
         }
 
diff --git a/keystore/jni/cert.c b/keystore/jni/cert.c
index 91114d6..90f872e 100644
--- a/keystore/jni/cert.c
+++ b/keystore/jni/cert.c
@@ -18,7 +18,6 @@
 #define LOG_TAG "CertTool"
 
 #include <stdio.h>
-#include <openssl/engine.h>
 #include <openssl/pem.h>
 #include <openssl/pkcs12.h>
 #include <openssl/rsa.h>
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 8cb89c3..e2b6b51 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1160,7 +1160,7 @@
 
 bool AudioFlinger::MixerThread::threadLoop()
 {
-    unsigned long sleepTime = kBufferRecoveryInUsecs;
+    unsigned long sleepTime = 0;
     int16_t* curBuf = mMixBuffer;
     Vector< sp<Track> > tracksToRemove;
     size_t enabledTracks = 0;
@@ -1215,6 +1215,7 @@
                     }
 
                     standbyTime = systemTime() + kStandbyTimeInNsecs;
+                    sleepTime = 0;
                     continue;
                 }
             }
@@ -1222,14 +1223,31 @@
             enabledTracks = prepareTracks_l(activeTracks, &tracksToRemove);
        }
 
-        if (LIKELY(enabledTracks)) {
-            // mix buffers...
-            mAudioMixer->process(curBuf);
 
-            // output audio to hardware
-            if (mSuspended) {
-                usleep(kMaxBufferRecoveryInUsecs);
+        // output audio to hardware
+        if (mSuspended) {
+            usleep(kMaxBufferRecoveryInUsecs);
+        } else {
+            if (LIKELY(enabledTracks)) {
+                // mix buffers...
+                mAudioMixer->process(curBuf);
+                sleepTime = 0;
+                standbyTime = systemTime() + kStandbyTimeInNsecs;
             } else {
+                sleepTime += kBufferRecoveryInUsecs;
+                // There was nothing to mix this round, which means all
+                // active tracks were late. Sleep a little bit to give
+                // them another chance. If we're too late, write 0s to audio
+                // hardware to avoid underrun.
+                if (sleepTime < kMaxBufferRecoveryInUsecs) {
+                    usleep(kBufferRecoveryInUsecs);
+                } else {
+                    memset (curBuf, 0, mixBufferSize);
+                    sleepTime = 0;
+                }
+            }
+            // sleepTime == 0 means PCM data were written to mMixBuffer[]
+            if (sleepTime == 0) {
                 mLastWriteTime = systemTime();
                 mInWrite = true;
                 int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize);
@@ -1237,24 +1255,11 @@
                 mNumWrites++;
                 mInWrite = false;
                 mStandby = false;
-                nsecs_t temp = systemTime();
-                standbyTime = temp + kStandbyTimeInNsecs;
-                nsecs_t delta = temp - mLastWriteTime;
+                nsecs_t delta = systemTime() - mLastWriteTime;
                 if (delta > maxPeriod) {
                     LOGW("write blocked for %llu msecs", ns2ms(delta));
                     mNumDelayedWrites++;
                 }
-                sleepTime = kBufferRecoveryInUsecs;
-            }
-        } else {
-            // There was nothing to mix this round, which means all
-            // active tracks were late. Sleep a little bit to give
-            // them another chance. If we're too late, the audio
-            // hardware will zero-fill for us.
-            // LOGV("thread %p no buffers - usleep(%lu)", this, sleepTime);
-            usleep(sleepTime);
-            if (sleepTime < kMaxBufferRecoveryInUsecs) {
-                sleepTime += kBufferRecoveryInUsecs;
             }
         }
 
@@ -1568,7 +1573,7 @@
 
 bool AudioFlinger::DirectOutputThread::threadLoop()
 {
-    unsigned long sleepTime = kBufferRecoveryInUsecs;
+    unsigned long sleepTime = 0;
     sp<Track> trackToRemove;
     sp<Track> activeTrack;
     nsecs_t standbyTime = systemTime();
@@ -1618,6 +1623,7 @@
                     }
 
                     standbyTime = systemTime() + kStandbyTimeInNsecs;
+                    sleepTime = 0;
                     continue;
                 }
             }
@@ -1710,46 +1716,48 @@
             }
        }
 
-        if (activeTrack != 0) {
-            AudioBufferProvider::Buffer buffer;
-            size_t frameCount = mFrameCount;
-            curBuf = (int8_t *)mMixBuffer;
-            // output audio to hardware
-            mLastWriteTime = systemTime();
-            mInWrite = true;
-            while(frameCount) {
-                buffer.frameCount = frameCount;
-                activeTrack->getNextBuffer(&buffer);
-                if (UNLIKELY(buffer.raw == 0)) {
-                    memset(curBuf, 0, frameCount * mFrameSize);
-                    break;
+        // output audio to hardware
+        if (mSuspended) {
+            usleep(kMaxBufferRecoveryInUsecs);
+        } else {
+            if (activeTrack != 0) {
+                AudioBufferProvider::Buffer buffer;
+                size_t frameCount = mFrameCount;
+                curBuf = (int8_t *)mMixBuffer;
+                // output audio to hardware
+                while(frameCount) {
+                    buffer.frameCount = frameCount;
+                    activeTrack->getNextBuffer(&buffer);
+                    if (UNLIKELY(buffer.raw == 0)) {
+                        memset(curBuf, 0, frameCount * mFrameSize);
+                        break;
+                    }
+                    memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
+                    frameCount -= buffer.frameCount;
+                    curBuf += buffer.frameCount * mFrameSize;
+                    activeTrack->releaseBuffer(&buffer);
                 }
-                memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
-                frameCount -= buffer.frameCount;
-                curBuf += buffer.frameCount * mFrameSize;
-                activeTrack->releaseBuffer(&buffer);
-            }
-            if (mSuspended) {
-                usleep(kMaxBufferRecoveryInUsecs);
+                sleepTime = 0;
+                standbyTime = systemTime() + kStandbyTimeInNsecs;
             } else {
+                sleepTime += kBufferRecoveryInUsecs;
+                if (sleepTime < kMaxBufferRecoveryInUsecs) {
+                    usleep(kBufferRecoveryInUsecs);
+                } else {
+                    memset (mMixBuffer, 0, mFrameCount * mFrameSize);
+                    sleepTime = 0;
+                }
+            }
+
+            // sleepTime == 0 means PCM data were written to mMixBuffer[]
+            if (sleepTime == 0) {
+                mLastWriteTime = systemTime();
+                mInWrite = true;
                 int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
                 if (bytesWritten) mBytesWritten += bytesWritten;
                 mNumWrites++;
                 mInWrite = false;
                 mStandby = false;
-                nsecs_t temp = systemTime();
-                standbyTime = temp + kStandbyTimeInNsecs;
-                sleepTime = kBufferRecoveryInUsecs;
-            }
-        } else {
-            // There was nothing to mix this round, which means all
-            // active tracks were late. Sleep a little bit to give
-            // them another chance. If we're too late, the audio
-            // hardware will zero-fill for us.
-            //LOGV("no buffers - usleep(%lu)", sleepTime);
-            usleep(sleepTime);
-            if (sleepTime < kMaxBufferRecoveryInUsecs) {
-                sleepTime += kBufferRecoveryInUsecs;
             }
         }
 
diff --git a/libs/rs/java/Fall/Android.mk b/libs/rs/java/Fall/Android.mk
deleted file mode 100644
index 6366f63..0000000
--- a/libs/rs/java/Fall/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
-
-LOCAL_PACKAGE_NAME := FallRS
-
-include $(BUILD_PACKAGE)
diff --git a/libs/rs/java/Fall/AndroidManifest.xml b/libs/rs/java/Fall/AndroidManifest.xml
deleted file mode 100644
index f646d0d..0000000
--- a/libs/rs/java/Fall/AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.fall.rs">
-
-    <application android:label="FallRS">
-
-        <activity
-            android:screenOrientation="portrait"
-            android:name="Fall"
-            android:theme="@android:style/Theme.NoTitleBar">
-
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-
-        </activity>
-
-    </application>
-
-</manifest>
diff --git a/libs/rs/java/Fall/res/drawable-hdpi/leaves.png b/libs/rs/java/Fall/res/drawable-hdpi/leaves.png
deleted file mode 100644
index 9eddd66..0000000
--- a/libs/rs/java/Fall/res/drawable-hdpi/leaves.png
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Fall/res/drawable-hdpi/riverbed.jpg b/libs/rs/java/Fall/res/drawable-hdpi/riverbed.jpg
deleted file mode 100644
index 1698f28..0000000
--- a/libs/rs/java/Fall/res/drawable-hdpi/riverbed.jpg
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Fall/res/drawable-hdpi/sky.jpg b/libs/rs/java/Fall/res/drawable-hdpi/sky.jpg
deleted file mode 100644
index 565a63b..0000000
--- a/libs/rs/java/Fall/res/drawable-hdpi/sky.jpg
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Fall/res/raw/fall.c b/libs/rs/java/Fall/res/raw/fall.c
deleted file mode 100644
index e04e1ff..0000000
--- a/libs/rs/java/Fall/res/raw/fall.c
+++ /dev/null
@@ -1,478 +0,0 @@
-// 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.
-
-#pragma version(1)
-#pragma stateVertex(PVSky)
-#pragma stateFragment(PFBackground)
-#pragma stateFragmentStore(PFSBackground)
-
-#define RSID_STATE 0
-#define RSID_RIPPLE_MAP 1
-#define RSID_REFRACTION_MAP 2
-#define RSID_LEAVES 3
-#define RSID_DROP 4
-
-#define LEAF_STRUCT_FIELDS_COUNT 11
-#define LEAF_STRUCT_X 0
-#define LEAF_STRUCT_Y 1
-#define LEAF_STRUCT_SCALE 2
-#define LEAF_STRUCT_ANGLE 3
-#define LEAF_STRUCT_SPIN 4
-#define LEAF_STRUCT_U1 5
-#define LEAF_STRUCT_U2 6
-#define LEAF_STRUCT_ALTITUDE 7
-#define LEAF_STRUCT_RIPPLED 8
-#define LEAF_STRUCT_DELTAX 9
-#define LEAF_STRUCT_DELTAY 10
-
-#define LEAVES_TEXTURES_COUNT 4
-
-#define LEAF_SIZE 0.55f
-
-#define REFRACTION 1.333f
-#define DAMP 3
-
-#define DROP_RADIUS 2
-// The higher, the smaller the ripple
-#define RIPPLE_HEIGHT 10.0f
-
-float g_SkyOffsetX;
-float g_SkyOffsetY;
-
-struct vert_s {
-    float nx;
-    float ny;
-    float nz;
-    float s;
-    float t;
-    float x;
-    float y;
-    float z;
-};
-
-int offset(int x, int y, int width) {
-    return x + 1 + (y + 1) * (width + 2);
-}
-
-void dropWithStrength(int x, int y, int r, int s) {
-    int width = State->meshWidth;
-    int height = State->meshHeight;
-
-    if (x < r) x = r;
-    if (y < r) y = r;
-    if (x >= width - r) x = width - r - 1;
-    if (y >= height - r) y = height - r - 1;
-
-    x = width - x;
-
-    int rippleMapSize = State->rippleMapSize;
-    int index = State->rippleIndex;
-    int origin = offset(0, 0, width);
-
-    int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin);
-    int sqr = r * r;
-    float invs = 1.0f / s;
-
-    int h = 0;
-    for ( ; h < r; h += 1) {
-        int sqv = h * h;
-        int yn = origin + (y - h) * (width + 2);
-        int yp = origin + (y + h) * (width + 2);
-        int w = 0;
-        for ( ; w < r; w += 1) {
-            int squ = w * w;
-            if (squ + sqv < sqr) {
-                int v = -sqrtf((sqr - (squ + sqv)) << 16) * invs;
-                current[yn + x + w] = v;
-                current[yp + x + w] = v;
-                current[yn + x - w] = v;
-                current[yp + x - w] = v;
-            }
-        }
-    }
-}
-
-void drop(int x, int y, int r) {
-    dropWithStrength(x, y, r, 1);
-}
-
-void updateRipples() {
-    int rippleMapSize = State->rippleMapSize;
-    int width = State->meshWidth;
-    int height = State->meshHeight;
-    int index = State->rippleIndex;
-    int origin = offset(0, 0, width);
-
-    int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin);
-    int* next = loadArrayI32(RSID_RIPPLE_MAP, (1 - index) * rippleMapSize + origin);
-
-    storeI32(RSID_STATE, OFFSETOF_WorldState_rippleIndex, 1 - index);
-
-    int a = 1;
-    int b = width + 2;
-    int h = height;
-    while (h) {
-        int w = width;
-        while (w) {
-            int droplet = ((current[-b] + current[b] + current[-a] + current[a]) >> 1) - *next;
-            droplet -= (droplet >> DAMP);
-            *next = droplet;
-            current += 1;
-            next += 1;
-            w -= 1;
-        }
-        current += 2;
-        next += 2;
-        h -= 1;
-    }
-}
-
-int refraction(int d, int wave, int *map) {
-    int i = d;
-    if (i < 0) i = -i;
-    if (i > 512) i = 512;
-    int w = (wave + 0x10000) >> 8;
-    w &= ~(w >> 31);
-    int r = (map[i] * w) >> 3;
-    if (d < 0) {
-        return -r;
-    }
-    return r;
-}
-
-void generateRipples() {
-    int rippleMapSize = loadI32(RSID_STATE, OFFSETOF_WorldState_rippleMapSize);
-    int width = State->meshWidth;
-    int height = State->meshHeight;
-    int index = State->rippleIndex;
-    int origin = offset(0, 0, width);
-
-    int b = width + 2;
-
-    int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin);
-    int *map = loadArrayI32(RSID_REFRACTION_MAP, 0);
-    float *vertices = loadTriangleMeshVerticesF(NAMED_WaterMesh);
-    struct vert_s *vert = (struct vert_s *)vertices;
-
-    float fw = 1.f / width;
-    float fh = 1.f / height;
-    float fy = (1.0f / 512.0f) * (1.0f / RIPPLE_HEIGHT);
-
-    int h = height - 1;
-    while (h >= 0) {
-        int w = width - 1;
-        int wave = *current;
-        int offset = h * width;
-        struct vert_s *vtx = vert + offset + w;
-
-        while (w >= 0) {
-            int nextWave = current[1];
-            int dx = nextWave - wave;
-            int dy = current[b] - wave;
-
-            int offsetx = refraction(dx, wave, map) >> 16;
-            int u = (width - w) + offsetx;
-            u &= ~(u >> 31);
-            if (u >= width) u = width - 1;
-
-            int offsety = refraction(dy, wave, map) >> 16;
-            int v = (height - h) + offsety;
-            v &= ~(v >> 31);
-            if (v >= height) v = height - 1;
-
-            vtx->s = u * fw;
-            vtx->t = v * fh;
-            vtx->z = dy * fy;
-            vtx --;
-
-            w -= 1;
-            current += 1;
-            wave = nextWave;
-        }
-        h -= 1;
-        current += 2;
-    }
-
-    // Compute the normals for lighting
-    int y = 0;
-    for ( ; y < height; y += 1) {
-        int x = 0;
-        int yOffset = y * width;
-        struct vert_s *v = vert;
-
-        for ( ; x < width; x += 1) {
-            struct vec3_s n1, n2, n3;
-            vec3Sub(&n1, (struct vec3_s *)&(v+1)->x, (struct vec3_s *)&v->x);
-            vec3Sub(&n2, (struct vec3_s *)&(v+width)->x, (struct vec3_s *)&v->x);
-            vec3Cross(&n3, &n1, &n2);
-            vec3Norm(&n3);
-
-            // Average of previous normal and N1 x N2
-            vec3Sub(&n1, (struct vec3_s *)&(v+width+1)->x, (struct vec3_s *)&v->x);
-            vec3Cross(&n2, &n1, &n2);
-            vec3Add(&n3, &n3, &n2);
-            vec3Norm(&n3);
-
-            v->nx = n3.x;
-            v->ny = n3.y;
-            v->nz = -n3.z;
-            v += 1;
-
-            // reset Z
-            //vertices[(yOffset + x) << 3 + 7] = 0.0f;
-        }
-    }
-}
-
-float averageZ(float x1, float x2, float y1, float y2, float* vertices,
-        int meshWidth, int meshHeight, float glWidth, float glHeight) {
-
-    x1 = ((x1 + glWidth * 0.5f) / glWidth) * meshWidth;
-    x2 = ((x2 + glWidth * 0.5f) / glWidth) * meshWidth;
-    y1 = ((y1 + glHeight * 0.5f) / glHeight) * meshHeight;
-    y2 = ((y2 + glHeight * 0.5f) / glHeight) * meshHeight;
-
-    int quadX1 = clamp(x1, 0, meshWidth);
-    int quadX2 = clamp(x2, 0, meshWidth);
-    int quadY1 = clamp(y1, 0, meshHeight);
-    int quadY2 = clamp(y2, 0, meshHeight);
-
-    float z = 0.0f;
-    int vertexCount = 0;
-
-    int y = quadY1;
-    for ( ; y < quadY2; y += 1) {
-        int x = quadX1;
-        int yOffset = y * meshWidth;
-        for ( ; x < quadX2; x += 1) {
-            z += vertices[(yOffset + x) << 3 + 7];
-            vertexCount += 1;
-        }
-    }
-
-    return 55.0f * z / vertexCount;
-}
-
-void drawLeaf(int index, float* vertices, int meshWidth, int meshHeight,
-        float glWidth, float glHeight) {
-
-    float *leafStruct = loadArrayF(RSID_LEAVES, index);
-
-    float x = leafStruct[LEAF_STRUCT_X];
-    float x1 = x - LEAF_SIZE;
-    float x2 = x + LEAF_SIZE;
-
-    float y = leafStruct[LEAF_STRUCT_Y];
-    float y1 = y - LEAF_SIZE;
-    float y2 = y + LEAF_SIZE;
-
-    float u1 = leafStruct[LEAF_STRUCT_U1];
-    float u2 = leafStruct[LEAF_STRUCT_U2];
-
-    float z1 = 0.0f;
-    float z2 = 0.0f;
-    float z3 = 0.0f;
-    float z4 = 0.0f;
-
-    float a = leafStruct[LEAF_STRUCT_ALTITUDE];
-    float s = leafStruct[LEAF_STRUCT_SCALE];
-    float r = leafStruct[LEAF_STRUCT_ANGLE];
-
-    float tz = 0.0f;
-    if (a > 0.0f) {
-        tz = -a;
-    } else {
-//        z1 = averageZ(x1, x, y1, y, vertices, meshWidth, meshHeight, glWidth, glHeight);
-//        z2 = averageZ(x, x2, y1, y, vertices, meshWidth, meshHeight, glWidth, glHeight);
-//        z3 = averageZ(x, x2, y, y2, vertices, meshWidth, meshHeight, glWidth, glHeight);
-//        z4 = averageZ(x1, x, y, y2, vertices, meshWidth, meshHeight, glWidth, glHeight);
-    }
-
-    x1 -= x;
-    x2 -= x;
-    y1 -= y;
-    y2 -= y;
-
-    float matrix[16];
-    matrixLoadIdentity(matrix);
-    matrixTranslate(matrix, x, y, tz);
-    matrixScale(matrix, s, s, 1.0f);
-    matrixRotate(matrix, r, 0.0f, 0.0f, 1.0f);
-    vpLoadModelMatrix(matrix);
-
-    drawQuadTexCoords(x1, y1, z1, u1, 1.0f,
-                      x2, y1, z2, u2, 1.0f,
-                      x2, y2, z3, u2, 0.0f,
-                      x1, y2, z4, u1, 0.0f);
-
-    float spin = leafStruct[LEAF_STRUCT_SPIN];
-    if (a <= 0.0f) {
-        float rippled = leafStruct[LEAF_STRUCT_RIPPLED];
-        if (rippled < 0.0f) {
-            drop(((x + glWidth * 0.5f) / glWidth) * meshWidth,
-                 meshHeight - ((y + glHeight * 0.5f) / glHeight) * meshHeight,
-                 DROP_RADIUS);
-            spin /= 4.0f;
-            leafStruct[LEAF_STRUCT_SPIN] = spin;
-            leafStruct[LEAF_STRUCT_RIPPLED] = 1.0f;
-        } else {
-//            dropWithStrength(((x + glWidth / 2.0f) / glWidth) * meshWidth,
-//                meshHeight - ((y + glHeight / 2.0f) / glHeight) * meshHeight,
-//                2, 5);
-        }
-        leafStruct[LEAF_STRUCT_X] = x + leafStruct[LEAF_STRUCT_DELTAX];
-        leafStruct[LEAF_STRUCT_Y] = y + leafStruct[LEAF_STRUCT_DELTAY];
-        r += spin;
-        leafStruct[LEAF_STRUCT_ANGLE] = r;
-    } else {
-        a -= 0.005f;
-        leafStruct[LEAF_STRUCT_ALTITUDE] = a;
-        r += spin * 2.0f;
-        leafStruct[LEAF_STRUCT_ANGLE] = r;
-    }
-
-    if (-LEAF_SIZE * s + x > glWidth / 2.0f || LEAF_SIZE * s + x < -glWidth / 2.0f ||
-        LEAF_SIZE * s + y < -glHeight / 2.0f) {
-
-        int sprite = randf(LEAVES_TEXTURES_COUNT);
-        leafStruct[LEAF_STRUCT_X] = randf2(-1.0f, 1.0f);
-        leafStruct[LEAF_STRUCT_Y] = glHeight / 2.0f + LEAF_SIZE * 2 * randf(1.0f);
-        leafStruct[LEAF_STRUCT_SCALE] = randf2(0.4f, 0.5f);
-        leafStruct[LEAF_STRUCT_SPIN] = degf(randf2(-0.02f, 0.02f)) / 4.0f;
-        leafStruct[LEAF_STRUCT_U1] = sprite / (float) LEAVES_TEXTURES_COUNT;
-        leafStruct[LEAF_STRUCT_U2] = (sprite + 1) / (float) LEAVES_TEXTURES_COUNT;
-        leafStruct[LEAF_STRUCT_DELTAX] = randf2(-0.02f, 0.02f) / 60.0f;
-        leafStruct[LEAF_STRUCT_DELTAY] = -0.08f * randf2(0.9f, 1.1f) / 60.0f;
-    }
-}
-
-void drawLeaves() {
-    bindProgramFragment(NAMED_PFBackground);
-    bindProgramFragmentStore(NAMED_PFSLeaf);
-    bindProgramVertex(NAMED_PVSky);
-    bindTexture(NAMED_PFBackground, 0, NAMED_TLeaves);
-
-    int leavesCount = State->leavesCount;
-    int count = leavesCount * LEAF_STRUCT_FIELDS_COUNT;
-    int width = State->meshWidth;
-    int height = State->meshHeight;
-    float glWidth = State->glWidth;
-    float glHeight = State->glHeight;
-
-    float *vertices = loadTriangleMeshVerticesF(NAMED_WaterMesh);
-
-    int i = 0;
-    for ( ; i < count; i += LEAF_STRUCT_FIELDS_COUNT) {
-        drawLeaf(i, vertices, width, height, glWidth, glHeight);
-    }
-
-    float matrix[16];
-    matrixLoadIdentity(matrix);
-    vpLoadModelMatrix(matrix);
-}
-
-void drawRiverbed() {
-    bindTexture(NAMED_PFBackground, 0, NAMED_TRiverbed);
-
-    drawTriangleMesh(NAMED_WaterMesh);
-}
-
-void drawSky() {
-    color(1.0f, 1.0f, 1.0f, 0.8f);
-
-    bindProgramFragment(NAMED_PFSky);
-    bindProgramFragmentStore(NAMED_PFSLeaf);
-    bindTexture(NAMED_PFSky, 0, NAMED_TSky);
-
-    float x = g_SkyOffsetX + State->skySpeedX;
-    float y = g_SkyOffsetY + State->skySpeedY;
-
-    if (x > 1.0f) x = 0.0f;
-    if (x < -1.0f) x = 0.0f;
-    if (y > 1.0f) y = 0.0f;
-
-    g_SkyOffsetX = x;
-    g_SkyOffsetY = y;
-
-    float matrix[16];
-    matrixLoadTranslate(matrix, x, y, 0.0f);
-    vpLoadTextureMatrix(matrix);
-
-    drawTriangleMesh(NAMED_WaterMesh);
-
-    matrixLoadIdentity(matrix);
-    vpLoadTextureMatrix(matrix);
-}
-
-void drawLighting() {
-    ambient(0.0f, 0.0f, 0.0f, 1.0f);
-    diffuse(0.0f, 0.0f, 0.0f, 1.0f);
-    specular(0.44f, 0.44f, 0.44f, 1.0f);
-    shininess(40.0f);
-
-    bindProgramFragmentStore(NAMED_PFSBackground);
-    bindProgramFragment(NAMED_PFLighting);
-    bindProgramVertex(NAMED_PVLight);
-
-    drawTriangleMesh(NAMED_WaterMesh);
-}
-
-void drawNormals() {
-    int width = State->meshWidth;
-    int height = State->meshHeight;
-
-    float *vertices = loadTriangleMeshVerticesF(NAMED_WaterMesh);
-
-    bindProgramVertex(NAMED_PVSky);
-    bindProgramFragment(NAMED_PFLighting);
-
-    color(1.0f, 0.0f, 0.0f, 1.0f);
-
-    float scale = 1.0f / 10.0f;
-    int y = 0;
-    for ( ; y < height; y += 1) {
-        int yOffset = y * width;
-        int x = 0;
-        for ( ; x < width; x += 1) {
-            int offset = (yOffset + x) << 3;
-            float vx = vertices[offset + 5];
-            float vy = vertices[offset + 6];
-            float vz = vertices[offset + 7];
-            float nx = vertices[offset + 0];
-            float ny = vertices[offset + 1];
-            float nz = vertices[offset + 2];
-            drawLine(vx, vy, vz, vx + nx * scale, vy + ny * scale, vz + nz * scale);
-        }
-    }
-}
-
-int main(int index) {
-    if (Drop->dropX != -1) {
-        drop(Drop->dropX, Drop->dropY, DROP_RADIUS);
-        Drop->dropX = -1;
-        Drop->dropY = -1;
-    }
-
-    updateRipples();
-    generateRipples();
-    updateTriangleMesh(NAMED_WaterMesh);
-
-    drawRiverbed();
-    drawSky();
-    drawLighting();
-    drawLeaves();
-    //drawNormals();
-
-    return 1;
-}
diff --git a/libs/rs/java/Fall/src/com/android/fall/rs/Fall.java b/libs/rs/java/Fall/src/com/android/fall/rs/Fall.java
deleted file mode 100644
index b1d9b1d..0000000
--- a/libs/rs/java/Fall/src/com/android/fall/rs/Fall.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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 com.android.fall.rs;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-public class Fall extends Activity {
-    private FallView mView;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        mView = new FallView(this);
-        setContentView(mView);
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        mView.onResume();
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-        mView.onPause();
-
-        Runtime.getRuntime().exit(0);
-    }
-}
diff --git a/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java b/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java
deleted file mode 100644
index 33aa9ab..0000000
--- a/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * 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 com.android.fall.rs;
-
-import android.content.res.Resources;
-import android.renderscript.RenderScript;
-import android.renderscript.ScriptC;
-import android.renderscript.ProgramFragment;
-import android.renderscript.ProgramStore;
-import android.renderscript.ProgramVertex;
-import android.renderscript.Allocation;
-import android.renderscript.Sampler;
-import android.renderscript.Element;
-import android.renderscript.Light;
-import android.renderscript.Type;
-import static android.renderscript.Sampler.Value.LINEAR;
-import static android.renderscript.Sampler.Value.WRAP;
-import static android.renderscript.ProgramStore.DepthFunc.*;
-import static android.renderscript.ProgramStore.BlendDstFunc;
-import static android.renderscript.ProgramStore.BlendSrcFunc;
-import static android.renderscript.ProgramFragment.EnvMode.*;
-import static android.renderscript.Element.*;
-import android.graphics.BitmapFactory;
-import android.graphics.Bitmap;
-import static android.util.MathUtils.*;
-
-import java.util.TimeZone;
-
-class FallRS {
-    private static final int MESH_RESOLUTION = 48;
-
-    private static final int RSID_STATE = 0;
-
-    private static final int TEXTURES_COUNT = 3;
-    private static final int LEAVES_TEXTURES_COUNT = 4;
-    private static final int RSID_TEXTURE_RIVERBED = 0;
-    private static final int RSID_TEXTURE_LEAVES = 1;
-    private static final int RSID_TEXTURE_SKY = 2;
-
-    private static final int RSID_RIPPLE_MAP = 1;
-
-    private static final int RSID_REFRACTION_MAP = 2;
-
-    private static final int RSID_LEAVES = 3;
-    private static final int LEAVES_COUNT = 14;
-    private static final int LEAF_STRUCT_FIELDS_COUNT = 11;
-    private static final int LEAF_STRUCT_X = 0;
-    private static final int LEAF_STRUCT_Y = 1;
-    private static final int LEAF_STRUCT_SCALE = 2;
-    private static final int LEAF_STRUCT_ANGLE = 3;
-    private static final int LEAF_STRUCT_SPIN = 4;
-    private static final int LEAF_STRUCT_U1 = 5;
-    private static final int LEAF_STRUCT_U2 = 6;
-    private static final int LEAF_STRUCT_ALTITUDE = 7;
-    private static final int LEAF_STRUCT_RIPPLED = 8;
-    private static final int LEAF_STRUCT_DELTAX = 9;
-    private static final int LEAF_STRUCT_DELTAY = 10;
-
-    class Leaf {
-        float x;
-        float y;
-        float scale;
-        float angle;
-        float spin;
-        float u1;
-        float u2;
-        float altitude;
-        float rippled;
-        float deltaX;
-        float deltaY;
-    }
-
-    private static final int RSID_DROP = 4;
-
-    private Resources mResources;
-    private RenderScript mRS;
-
-    private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
-
-    private final int mWidth;
-    private final int mHeight;
-
-    @SuppressWarnings({"FieldCanBeLocal"})
-    private ProgramFragment mPfBackground;
-    @SuppressWarnings({"FieldCanBeLocal"})
-    private ProgramFragment mPfLighting;
-    @SuppressWarnings({"FieldCanBeLocal"})
-    private ProgramFragment mPfSky;
-    @SuppressWarnings({"FieldCanBeLocal"})
-    private ProgramStore mPfsBackground;
-    @SuppressWarnings({"FieldCanBeLocal"})
-    private ProgramStore mPfsLeaf;
-    @SuppressWarnings({"FieldCanBeLocal"})
-    private ProgramVertex mPvLight;
-    @SuppressWarnings({"FieldCanBeLocal"})
-    private ProgramVertex mPvSky;
-
-    private Allocation mState;
-    private Allocation mDropState;
-    private DropState mDrop;
-    private Type mStateType;
-    private Type mDropType;
-    private int mMeshWidth;
-
-    private int mMeshHeight;
-    @SuppressWarnings({"FieldCanBeLocal"})
-    private RenderScript.TriangleMesh mMesh;
-
-    private Allocation mRippleMap;
-    private Allocation mRefractionMap;
-
-    private Allocation mLeaves;
-    private float mGlHeight;
-
-    public FallRS(int width, int height) {
-        mWidth = width;
-        mHeight = height;
-        mOptionsARGB.inScaled = false;
-        mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
-    }
-
-    public void init(RenderScript rs, Resources res) {
-        mRS = rs;
-        mResources = res;
-        initRS();
-    }
-
-    private void initRS() {
-        createProgramVertex();
-        createProgramFragmentStore();
-        createProgramFragment();
-        createMesh();
-        createScriptStructures();
-        loadTextures();
-
-        ScriptC.Builder sb = new ScriptC.Builder(mRS);
-        sb.setType(mStateType, "State", RSID_STATE);
-        sb.setType(mDropType, "Drop", RSID_DROP);
-        sb.setScript(mResources, R.raw.fall);
-        sb.setRoot(true);
-
-        ScriptC script = sb.create();
-        script.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-        script.setTimeZone(TimeZone.getDefault().getID());
-
-        script.bindAllocation(mState, RSID_STATE);
-        script.bindAllocation(mRippleMap, RSID_RIPPLE_MAP);
-        script.bindAllocation(mRefractionMap, RSID_REFRACTION_MAP);
-        script.bindAllocation(mLeaves, RSID_LEAVES);
-        script.bindAllocation(mDropState, RSID_DROP);
-
-        mRS.contextBindRootScript(script);
-    }
-
-    private void createMesh() {
-        final RenderScript rs = mRS;
-        rs.triangleMeshBegin(Element.NORM_ST_XYZ_F32, Element.INDEX_16);
-
-        int wResolution;
-        int hResolution;
-
-        final int width = mWidth;
-        final int height = mHeight;
-
-        if (width < height) {
-            wResolution = MESH_RESOLUTION;
-            hResolution = (int) (MESH_RESOLUTION * height / (float) width);
-        } else {
-            wResolution = (int) (MESH_RESOLUTION * width / (float) height);
-            hResolution = MESH_RESOLUTION;
-        }
-
-        mGlHeight = 2.0f * height / (float) width;
-        final float glHeight = mGlHeight;
-
-        float quadWidth = 2.0f / (float) wResolution;
-        float quadHeight = glHeight / (float) hResolution;
-
-        wResolution += 2;
-        hResolution += 2;
-
-        for (int y = 0; y <= hResolution; y++) {
-            final boolean shift = (y & 0x1) == 0;
-            final float yOffset = y * quadHeight - glHeight / 2.0f - quadHeight;
-            final float t = 1.0f - y / (float) hResolution;
-            for (int x = 0; x <= wResolution; x++) {
-                if (shift) {
-                    rs.triangleMeshAddVertex_XYZ_ST_NORM(
-                            -1.0f + x * quadWidth - quadWidth, yOffset, 0.0f,
-                            x / (float) wResolution, t,
-                            0.0f, 0.0f, -1.0f);
-                } else {
-                    rs.triangleMeshAddVertex_XYZ_ST_NORM(
-                            -1.0f + x * quadWidth - quadWidth * 0.5f, yOffset, 0.0f,
-                            x / (float) wResolution, t,
-                            0.0f, 0.0f, -1.0f);
-                }
-            }
-        }
-
-        for (int y = 0; y < hResolution; y++) {
-            final boolean shift = (y & 0x1) == 0;
-            final int yOffset = y * (wResolution + 1);
-            for (int x = 0; x < wResolution; x++) {
-                final int index = yOffset + x;
-                final int iWR1 = index + wResolution + 1;
-                if (shift) {
-                    rs.triangleMeshAddTriangle(index, index + 1, iWR1);
-                    rs.triangleMeshAddTriangle(index + 1, iWR1 + 1, iWR1);
-                } else {
-                    rs.triangleMeshAddTriangle(index, iWR1 + 1, iWR1);
-                    rs.triangleMeshAddTriangle(index, index + 1, iWR1 + 1);
-                }
-            }
-        }
-
-        mMesh = rs.triangleMeshCreate();
-        mMesh.setName("WaterMesh");
-
-        mMeshWidth = wResolution + 1;
-        mMeshHeight = hResolution + 1;
-    }
-
-    private void createScriptStructures() {
-        final int rippleMapSize = (mMeshWidth + 2) * (mMeshHeight + 2);
-
-        createState(rippleMapSize);
-        createRippleMap(rippleMapSize);
-        createRefractionMap();
-        createLeaves();
-    }
-
-    private void createLeaves() {
-        final float[] leaves = new float[LEAVES_COUNT * LEAF_STRUCT_FIELDS_COUNT];
-        mLeaves = Allocation.createSized(mRS, USER_FLOAT, leaves.length);
-        for (int i = 0; i < leaves.length; i += LEAF_STRUCT_FIELDS_COUNT) {
-            createLeaf(leaves, i);
-        }
-        mLeaves.data(leaves);
-    }
-
-    private void createRefractionMap() {
-        final int[] refractionMap = new int[513];
-        float ir = 1.0f / 1.333f;
-        for (int i = 0; i < refractionMap.length; i++) {
-            float d = (float) Math.tan(Math.asin(Math.sin(Math.atan(i * (1.0f / 256.0f))) * ir));
-            refractionMap[i] = (int) Math.floor(d * (1 << 16) + 0.5f);
-        }
-        mRefractionMap = Allocation.createSized(mRS, USER_I32, refractionMap.length);
-        mRefractionMap.data(refractionMap);
-    }
-
-    private void createRippleMap(int rippleMapSize) {
-        final int[] rippleMap = new int[rippleMapSize * 2];
-        mRippleMap = Allocation.createSized(mRS, USER_I32, rippleMap.length);
-        mRippleMap.data(rippleMap);
-    }
-
-    static class WorldState {
-        public int frameCount;
-        public int width;
-        public int height;
-        public int meshWidth;
-        public int meshHeight;
-        public int rippleMapSize;
-        public int rippleIndex;
-        public int leavesCount;
-        public float glWidth;
-        public float glHeight;
-        public float skySpeedX;
-        public float skySpeedY;
-    }
-
-    static class DropState {
-        public int dropX;
-        public int dropY;
-    }
-
-    private void createState(int rippleMapSize) {
-        WorldState worldState = new WorldState();
-        worldState.width = mWidth;
-        worldState.height = mHeight;
-        worldState.meshWidth = mMeshWidth;
-        worldState.meshHeight = mMeshHeight;
-        worldState.rippleMapSize = rippleMapSize;
-        worldState.rippleIndex = 0;
-        worldState.leavesCount = LEAVES_COUNT;
-        worldState.glWidth = 2.0f;
-        worldState.glHeight = mGlHeight;
-        worldState.skySpeedX = random(-0.001f, 0.001f);
-        worldState.skySpeedY = random(0.00008f, 0.0002f);
-
-        mStateType = Type.createFromClass(mRS, WorldState.class, 1, "WorldState");
-        mState = Allocation.createTyped(mRS, mStateType);
-        mState.data(worldState);
-
-        mDrop = new DropState();
-        mDrop.dropX = -1;
-        mDrop.dropY = -1;
-
-        mDropType = Type.createFromClass(mRS, DropState.class, 1, "DropState");
-        mDropState = Allocation.createTyped(mRS, mDropType);
-        mDropState.data(mDrop);
-    }
-
-    private void createLeaf(float[] leaves, int index) {
-        int sprite = random(LEAVES_TEXTURES_COUNT);
-        //noinspection PointlessArithmeticExpression
-        leaves[index + LEAF_STRUCT_X] = random(-1.0f, 1.0f);
-        leaves[index + LEAF_STRUCT_Y] = random(-mGlHeight / 2.0f, mGlHeight / 2.0f);
-        leaves[index + LEAF_STRUCT_SCALE] = random(0.4f, 0.5f);
-        leaves[index + LEAF_STRUCT_ANGLE] = random(0.0f, 360.0f);
-        leaves[index + LEAF_STRUCT_SPIN] = degrees(random(-0.02f, 0.02f)) / 4.0f;
-        leaves[index + LEAF_STRUCT_U1] = sprite / (float) LEAVES_TEXTURES_COUNT;
-        leaves[index + LEAF_STRUCT_U2] = (sprite + 1) / (float) LEAVES_TEXTURES_COUNT;
-        leaves[index + LEAF_STRUCT_ALTITUDE] = -1.0f;
-        leaves[index + LEAF_STRUCT_RIPPLED] = 1.0f;
-        leaves[index + LEAF_STRUCT_DELTAX] = random(-0.02f, 0.02f) / 60.0f;
-        leaves[index + LEAF_STRUCT_DELTAY] = -0.08f * random(0.9f, 1.1f) / 60.0f;
-    }
-
-    private void loadTextures() {
-        final Allocation[] textures = new Allocation[TEXTURES_COUNT];
-        textures[RSID_TEXTURE_RIVERBED] = loadTexture(R.drawable.riverbed, "TRiverbed");
-        textures[RSID_TEXTURE_LEAVES] = loadTextureARGB(R.drawable.leaves, "TLeaves");
-        textures[RSID_TEXTURE_SKY] = loadTextureARGB(R.drawable.sky, "TSky");
-
-        final int count = textures.length;
-        for (int i = 0; i < count; i++) {
-            final Allocation texture = textures[i];
-            texture.uploadToTexture(0);
-        }
-    }
-
-    private Allocation loadTexture(int id, String name) {
-        final Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources,
-                id, RGB_565, false);
-        allocation.setName(name);
-        return allocation;
-    }
-
-    private Allocation loadTextureARGB(int id, String name) {
-        Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB);
-        final Allocation allocation = Allocation.createFromBitmap(mRS, b, RGBA_8888, false);
-        allocation.setName(name);
-        return allocation;
-    }
-
-    private void createProgramFragment() {
-        Sampler.Builder sampleBuilder = new Sampler.Builder(mRS);
-        sampleBuilder.setMin(LINEAR);
-        sampleBuilder.setMag(LINEAR);
-        sampleBuilder.setWrapS(WRAP);
-        sampleBuilder.setWrapT(WRAP);
-        Sampler sampler = sampleBuilder.create();
-
-        ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null);
-        builder.setTexEnable(true, 0);
-        builder.setTexEnvMode(REPLACE, 0);
-        mPfBackground = builder.create();
-        mPfBackground.setName("PFBackground");
-        mPfBackground.bindSampler(sampler, 0);
-
-        builder = new ProgramFragment.Builder(mRS, null, null);
-        builder.setTexEnable(false, 0);
-        mPfLighting = builder.create();
-        mPfLighting.setName("PFLighting");
-        mPfLighting.bindSampler(sampler, 0);
-
-        builder = new ProgramFragment.Builder(mRS, null, null);
-        builder.setTexEnable(true, 0);
-        builder.setTexEnvMode(MODULATE, 0);
-        mPfSky = builder.create();
-        mPfSky.setName("PFSky");
-        mPfSky.bindSampler(sampler, 0);
-    }
-
-    private void createProgramFragmentStore() {
-        ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null);
-        builder.setDepthFunc(ALWAYS);
-        builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
-        builder.setDitherEnable(false);
-        builder.setDepthMask(true);
-        mPfsBackground = builder.create();
-        mPfsBackground.setName("PFSBackground");
-
-        builder = new ProgramStore.Builder(mRS, null, null);
-        builder.setDepthFunc(ALWAYS);
-        builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
-        builder.setDitherEnable(false);
-        builder.setDepthMask(true);
-        mPfsLeaf = builder.create();
-        mPfsLeaf.setName("PFSLeaf");
-    }
-
-    private void createProgramVertex() {
-        ProgramVertex.MatrixAllocation pvOrthoAlloc = new ProgramVertex.MatrixAllocation(mRS);
-        pvOrthoAlloc.setupProjectionNormalized(mWidth, mHeight);
-
-        Light light = new Light.Builder(mRS).create();
-        light.setPosition(0.0f, 2.0f, -8.0f);
-
-        ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS, null, null);
-        builder.addLight(light);
-        mPvLight = builder.create();
-        mPvLight.bindAllocation(pvOrthoAlloc);
-        mPvLight.setName("PVLight");
-
-        builder = new ProgramVertex.Builder(mRS, null, null);
-        builder.setTextureMatrixEnable(true);
-        mPvSky = builder.create();
-        mPvSky.bindAllocation(pvOrthoAlloc);
-        mPvSky.setName("PVSky");
-    }
-
-    void addDrop(float x, float y) {
-        mDrop.dropX = (int) ((x / mWidth) * mMeshWidth);
-        mDrop.dropY = (int) ((y / mHeight) * mMeshHeight);
-        mDropState.data(mDrop);
-    }
-}
diff --git a/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java b/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java
deleted file mode 100644
index 7468d2b..0000000
--- a/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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 com.android.fall.rs;
-
-import android.content.Context;
-import android.view.SurfaceHolder;
-import android.view.MotionEvent;
-import android.view.KeyEvent;
-import android.renderscript.RenderScript;
-import android.renderscript.RSSurfaceView;
-
-class FallView extends RSSurfaceView {
-    private FallRS mRender;
-
-    public FallView(Context context) {
-        super(context);
-        setFocusable(true);
-        setFocusableInTouchMode(true);
-    }
-
-    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
-        super.surfaceChanged(holder, format, w, h);
-
-        RenderScript RS = createRenderScript(false);
-        mRender = new FallRS(w, h);
-        mRender.init(RS, getResources());
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        switch (event.getAction()) {
-            case MotionEvent.ACTION_DOWN:
-            case MotionEvent.ACTION_MOVE:
-                mRender.addDrop(event.getX(), event.getY());
-                try {
-                    Thread.sleep(16);
-                } catch (InterruptedException e) {
-                    // Ignore
-                }
-                break;
-        }
-        return true;
-    }
-}
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 651e7cf..d893f0a 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -103,10 +103,22 @@
     }
 
     // initialize EGL
-    const EGLint attribs[] = {
+    EGLint attribs[] = {
             EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
+            EGL_NONE,           0,
             EGL_NONE
     };
+
+    // debug: disable h/w rendering
+    char property[PROPERTY_VALUE_MAX];
+    if (property_get("debug.sf.hw", property, NULL) > 0) {
+        if (atoi(property) == 0) {
+            LOGW("H/W composition disabled");
+            attribs[2] = EGL_CONFIG_CAVEAT;
+            attribs[3] = EGL_SLOW_CONFIG;
+        }
+    }
+
     EGLint w, h, dummy;
     EGLint numConfigs=0;
     EGLSurface surface;
@@ -193,7 +205,6 @@
     mDpiY = mNativeWindow->ydpi;
     mRefreshRate = fbDev->fps; 
     
-    char property[PROPERTY_VALUE_MAX];
     /* Read density from build-specific ro.sf.lcd_density property
      * except if it is overridden by qemu.sf.lcd_density.
      */
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
index 00abd5a..e14f35b 100644
--- a/libs/surfaceflinger/LayerBlur.cpp
+++ b/libs/surfaceflinger/LayerBlur.cpp
@@ -24,6 +24,7 @@
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
+#include "clz.h"
 #include "BlurFilter.h"
 #include "LayerBlur.h"
 #include "SurfaceFlinger.h"
@@ -40,7 +41,8 @@
 LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
         const sp<Client>& client, int32_t i)
      : LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
-     mRefreshCache(true), mCacheAge(0), mTextureName(-1U)
+     mRefreshCache(true), mCacheAge(0), mTextureName(-1U), 
+     mWidthScale(1.0f), mHeightScale(1.0f)
 {
 }
 
@@ -164,11 +166,26 @@
             bl.format = GGL_PIXEL_FORMAT_RGB_565;
             bl.data = (GGLubyte*)pixels;            
             blurFilter(&bl, 8, 2);
-            
-            // NOTE: this works only because we have POT. we'd have to round the
-            // texture size up, otherwise.
-            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
-                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+
+            if (mFlags & (DisplayHardware::NPOT_EXTENSION)) {
+                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
+                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+                mWidthScale  = 1.0f / w;
+                mHeightScale =-1.0f / h;
+                mYOffset = 0;
+            } else {
+                GLuint tw = 1 << (31 - clz(w));
+                GLuint th = 1 << (31 - clz(h));
+                if (tw < w) tw <<= 1;
+                if (th < h) th <<= 1;
+                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0,
+                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
+                glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, 
+                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+                mWidthScale  = 1.0f / tw;
+                mHeightScale =-1.0f / th;
+                mYOffset = th-h;
+            }
 
             free((void*)pixels);
         }
@@ -184,7 +201,12 @@
             glDisable(GL_BLEND);
         }
 
-        glDisable(GL_DITHER);
+        if (mFlags & DisplayHardware::SLOW_CONFIG) {
+            glDisable(GL_DITHER);
+        } else {
+            glEnable(GL_DITHER);
+        }
+
         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -194,8 +216,8 @@
             // This is a very rare scenario.
             glMatrixMode(GL_TEXTURE);
             glLoadIdentity();
-            glScalef(1.0f/w, -1.0f/h, 1);
-            glTranslatef(-x, -y, 0);
+            glScalef(mWidthScale, mHeightScale, 1);
+            glTranslatef(-x, mYOffset - y, 0);
             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
             glVertexPointer(2, GL_FIXED, 0, mVertices);
             glTexCoordPointer(2, GL_FIXED, 0, mVertices);
@@ -205,6 +227,7 @@
                 glScissor(r.left, sy, r.width(), r.height());
                 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
             }       
+            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
         } else {
             // NOTE: this is marginally faster with the software gl, because
             // glReadPixels() reads the fb bottom-to-top, however we'll
@@ -221,8 +244,6 @@
             }
         }
     }
-
-    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 }
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h
index 0c3e6eb..bf36ae4 100644
--- a/libs/surfaceflinger/LayerBlur.h
+++ b/libs/surfaceflinger/LayerBlur.h
@@ -56,6 +56,9 @@
     mutable bool    mAutoRefreshPending;
             nsecs_t mCacheAge;
     mutable GLuint  mTextureName;
+    mutable GLfloat mWidthScale;
+    mutable GLfloat mHeightScale;
+    mutable GLfloat mYOffset;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 433b48e..bbfc54b9 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -133,6 +133,14 @@
     return false;
 }
 
+void LayerBuffer::serverDestroy()
+{
+    sp<Source> source(clearSource());
+    if (source != 0) {
+        source->destroy();
+    }
+}
+
 /**
  * This creates a "buffer" source for this surface
  */
@@ -354,7 +362,7 @@
 {    
     ISurface::BufferHeap buffers;
     { // scope for the lock
-        Mutex::Autolock _l(mLock);
+        Mutex::Autolock _l(mBufferSourceLock);
         buffers = mBufferHeap;
         if (buffers.heap != 0) {
             const size_t memorySize = buffers.heap->getSize();
@@ -379,7 +387,7 @@
 
 void LayerBuffer::BufferSource::unregisterBuffers()
 {
-    Mutex::Autolock _l(mLock);
+    Mutex::Autolock _l(mBufferSourceLock);
     mBufferHeap.heap.clear();
     mBuffer.clear();
     mLayer.invalidate();
@@ -387,13 +395,13 @@
 
 sp<LayerBuffer::Buffer> LayerBuffer::BufferSource::getBuffer() const
 {
-    Mutex::Autolock _l(mLock);
+    Mutex::Autolock _l(mBufferSourceLock);
     return mBuffer;
 }
 
 void LayerBuffer::BufferSource::setBuffer(const sp<LayerBuffer::Buffer>& buffer)
 {
-    Mutex::Autolock _l(mLock);
+    Mutex::Autolock _l(mBufferSourceLock);
     mBuffer = buffer;
 }
 
@@ -413,7 +421,7 @@
 
     status_t err = NO_ERROR;
     NativeBuffer src(ourBuffer->getBuffer());
-    const Rect& transformedBounds = mLayer.getTransformedBounds();
+    const Rect transformedBounds(mLayer.getTransformedBounds());
     copybit_device_t* copybit = mBlitEngine;
 
     if (copybit)  {
@@ -493,7 +501,7 @@
                 }
             }
 
-            const Rect& transformedBounds = mLayer.getTransformedBounds();
+            const Rect transformedBounds(mLayer.getTransformedBounds());
             const copybit_rect_t& drect =
                 reinterpret_cast<const copybit_rect_t&>(transformedBounds);
             const State& s(mLayer.drawingState());
@@ -583,9 +591,7 @@
 
     mOverlayHandle = overlay->getHandleRef(overlay);
     
-    // NOTE: here it's okay to acquire a reference to "this"m as long as
-    // the reference is not released before we leave the ctor.
-    sp<OverlayChannel> channel = new OverlayChannel(this);
+    sp<OverlayChannel> channel = new OverlayChannel( &layer );
 
     *overlayRef = new OverlayRef(mOverlayHandle, channel,
             mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
@@ -601,7 +607,6 @@
 
 void LayerBuffer::OverlaySource::onDraw(const Region& clip) const
 {
-    GLclampx color = 0x000018; //dark blue
     GLclampx red = 0;
     GLclampx green = 0;
     GLclampx blue = 0x1818;
@@ -626,14 +631,14 @@
         if (mVisibilityChanged || !mInitialized) {
             mVisibilityChanged = false;
             mInitialized = true;
-            const Rect& bounds = mLayer.getTransformedBounds();
+            const Rect bounds(mLayer.getTransformedBounds());
             int x = bounds.left;
             int y = bounds.top;
             int w = bounds.width();
             int h = bounds.height();
             
             // we need a lock here to protect "destroy"
-            Mutex::Autolock _l(mLock);
+            Mutex::Autolock _l(mOverlaySourceLock);
             if (mOverlay) {
                 overlay_control_device_t* overlay_dev = mOverlayDevice;
                 overlay_dev->setPosition(overlay_dev, mOverlay, x,y,w,h);
@@ -645,17 +650,11 @@
     }
 }
 
-void LayerBuffer::OverlaySource::serverDestroy() 
-{
-    mLayer.clearSource();
-    destroyOverlay();
-}
-
-void LayerBuffer::OverlaySource::destroyOverlay() 
+void LayerBuffer::OverlaySource::destroy()
 {
     // we need a lock here to protect "onVisibilityResolved"
-    Mutex::Autolock _l(mLock);
-    if (mOverlay) {
+    Mutex::Autolock _l(mOverlaySourceLock);
+    if (mOverlay && mOverlayDevice) {
         overlay_control_device_t* overlay_dev = mOverlayDevice;
         overlay_dev->destroyOverlay(overlay_dev, mOverlay);
         mOverlay = 0;
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index e539f68..0452818 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -49,6 +49,7 @@
         virtual void postBuffer(ssize_t offset);
         virtual void unregisterBuffers();
         virtual bool transformed() const;
+        virtual void destroy() { }
     protected:
         LayerBuffer& mLayer;
     };
@@ -81,10 +82,12 @@
     sp<Source> getSource() const;
     sp<Source> clearSource();
     void setNeedsBlending(bool blending);
-    const Rect& getTransformedBounds() const {
+    Rect getTransformedBounds() const {
         return mTransformedBounds;
     }
 
+    void serverDestroy();
+
 private:
     struct NativeBuffer {
         copybit_image_t   img;
@@ -123,8 +126,9 @@
         virtual void postBuffer(ssize_t offset);
         virtual void unregisterBuffers();
         virtual bool transformed() const;
+        virtual void destroy() { }
     private:
-        mutable Mutex                   mLock;
+        mutable Mutex                   mBufferSourceLock;
         sp<Buffer>                      mBuffer;
         status_t                        mStatus;
         ISurface::BufferHeap            mBufferHeap;
@@ -143,28 +147,23 @@
         virtual void onDraw(const Region& clip) const;
         virtual void onTransaction(uint32_t flags);
         virtual void onVisibilityResolved(const Transform& planeTransform);
+        virtual void destroy();
     private:
-        void serverDestroy(); 
-        void destroyOverlay(); 
+
         class OverlayChannel : public BnOverlay {
-            mutable Mutex mLock;
-            sp<OverlaySource> mSource;
+            wp<LayerBuffer> mLayer;
             virtual void destroy() {
-                sp<OverlaySource> source;
-                { // scope for the lock;
-                    Mutex::Autolock _l(mLock);
-                    source = mSource;
-                    mSource.clear();
-                }
-                if (source != 0) {
-                    source->serverDestroy();
+                sp<LayerBuffer> layer(mLayer.promote());
+                if (layer != 0) {
+                    layer->serverDestroy();
                 }
             }
         public:
-            OverlayChannel(const sp<OverlaySource>& source)
-                : mSource(source) {
+            OverlayChannel(const sp<LayerBuffer>& layer)
+                : mLayer(layer) {
             }
         };
+        
         friend class OverlayChannel;
         bool mVisibilityChanged;
 
@@ -176,7 +175,7 @@
         int32_t mFormat;
         int32_t mWidthStride;
         int32_t mHeightStride;
-        mutable Mutex mLock;
+        mutable Mutex mOverlaySourceLock;
         bool mInitialized;
     };
 
@@ -199,7 +198,7 @@
             return static_cast<LayerBuffer*>(Surface::getOwner().get());
         }
     };
-    
+
     mutable Mutex   mLock;
     sp<Source>      mSource;
     sp<Surface>     mSurface;
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 348dd68..9577044 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -40,4 +40,8 @@
 
 LOCAL_MODULE:= libui
 
+ifeq ($(TARGET_SIMULATOR),true)
+    LOCAL_LDLIBS += -lpthread
+endif
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 6be372c..ec3db09 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -655,6 +655,11 @@
     wp<Thread> weak(strong);
     self->mHoldSelf.clear();
 
+#if HAVE_ANDROID_OS
+    // this is very useful for debugging with gdb
+    self->mTid = gettid();
+#endif
+
     bool first = true;
 
     do {
@@ -685,7 +690,7 @@
             self->mExitPending = true;
             self->mLock.lock();
             self->mRunning = false;
-            self->mThreadExitedCondition.signal();
+            self->mThreadExitedCondition.broadcast();
             self->mLock.unlock();
             break;
         }
@@ -693,7 +698,7 @@
         // Release our strong reference, to let a chance to the thread
         // to die a peaceful death.
         strong.clear();
-        // And immediately, reacquire a strong reference for the next loop
+        // And immediately, re-acquire a strong reference for the next loop
         strong = weak.promote();
     } while(strong != 0);
     
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 754d5a2..665d353 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -758,6 +758,9 @@
 
     /** @see AudioManager#setSpeakerphoneOn() */
     public void setSpeakerphoneOn(boolean on){
+        if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
+            return;
+        }
         if (on) {
             AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_SPEAKER);
             mForcedUseForComm = AudioSystem.FORCE_SPEAKER;
@@ -778,6 +781,9 @@
 
     /** @see AudioManager#setBluetoothScoOn() */
     public void setBluetoothScoOn(boolean on){
+        if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
+            return;
+        }
         if (on) {
             AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_BT_SCO);
             AudioSystem.setForceUse(AudioSystem.FOR_RECORD, AudioSystem.FORCE_BT_SCO);
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index fcc76ca5..f6d30e0 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -493,6 +493,22 @@
             doScanFile(path, mimeType, lastModified, fileSize, false);
         }
 
+        private boolean isMetadataSupported(int fileType) {
+            if (mFileType == MediaFile.FILE_TYPE_MP3 ||
+                    mFileType == MediaFile.FILE_TYPE_MP4 ||
+                    mFileType == MediaFile.FILE_TYPE_M4A ||
+                    mFileType == MediaFile.FILE_TYPE_3GPP ||
+                    mFileType == MediaFile.FILE_TYPE_3GPP2 ||
+                    mFileType == MediaFile.FILE_TYPE_OGG ||
+                    mFileType == MediaFile.FILE_TYPE_AAC ||
+                    mFileType == MediaFile.FILE_TYPE_MID ||
+                    mFileType == MediaFile.FILE_TYPE_WMA) {
+                // we only extract metadata from MP3, M4A, OGG, MID, AAC and WMA files.
+                // check MP4 files, to determine if they contain only audio.
+                return true;
+            }
+            return false;
+        }
         public Uri doScanFile(String path, String mimeType, long lastModified, long fileSize, boolean scanAlways) {
             Uri result = null;
 //            long t1 = System.currentTimeMillis();
@@ -508,16 +524,7 @@
                     boolean music = (lowpath.indexOf(MUSIC_DIR) > 0) ||
                         (!ringtones && !notifications && !alarms && !podcasts);
 
-                    if (mFileType == MediaFile.FILE_TYPE_MP3 ||
-                            mFileType == MediaFile.FILE_TYPE_MP4 ||
-                            mFileType == MediaFile.FILE_TYPE_M4A ||
-                            mFileType == MediaFile.FILE_TYPE_3GPP ||
-                            mFileType == MediaFile.FILE_TYPE_3GPP2 ||
-                            mFileType == MediaFile.FILE_TYPE_OGG ||
-                            mFileType == MediaFile.FILE_TYPE_MID ||
-                            mFileType == MediaFile.FILE_TYPE_WMA) {
-                        // we only extract metadata from MP3, M4A, OGG, MID and WMA files.
-                        // check MP4 files, to determine if they contain only audio.
+                    if( isMetadataSupported(mFileType) ) {
                         processFile(path, mimeType, this);
                     } else if (MediaFile.isImageFileType(mFileType)) {
                         // we used to compute the width and height but it's not worth it
diff --git a/media/java/android/media/ToneGenerator.java b/media/java/android/media/ToneGenerator.java
index c60a1ac..d4ae80f 100644
--- a/media/java/android/media/ToneGenerator.java
+++ b/media/java/android/media/ToneGenerator.java
@@ -744,7 +744,7 @@
      * This method starts the playback of a tone of the specified type.
      * only one tone can play at a time: if a tone is playing while this method is called,
      * this tone is stopped and replaced by the one requested.
-     * @param toneType   The type of tone generate chosen from the following list:
+     * @param toneType   The type of tone generated chosen from the following list:
      * <ul>
      * <li>{@link #TONE_DTMF_0}
      * <li>{@link #TONE_DTMF_1}
@@ -846,7 +846,18 @@
      * </ul>
      * @see #ToneGenerator(int, int)
     */
-    public native boolean startTone(int toneType);
+    public boolean startTone(int toneType) {
+        return startTone(toneType, -1);
+    }
+
+    /**
+     * This method starts the playback of a tone of the specified type for the specified duration.
+     * @param toneType   The type of tone generated @see #startTone(int).
+     * @param durationMs  The tone duration in milliseconds. If the tone is limited in time by definition,
+     * the actual duration will be the minimum of durationMs and the defined tone duration. Setting durationMs to -1,
+     * is equivalent to calling #startTone(int).
+    */
+    public native boolean startTone(int toneType, int durationMs);
 
     /**
      * This method stops the tone currently playing playback.
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 799c349..4008bfd 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -791,7 +791,6 @@
 //        generators, instantiates output audio track.
 //
 //    Input:
-//        toneType:        Type of tone generated (values in enum tone_type)
 //        streamType:        Type of stream used for tone playback (enum AudioTrack::stream_type)
 //        volume:            volume applied to tone (0.0 to 1.0)
 //
@@ -869,13 +868,16 @@
 //    Description:    Starts tone playback.
 //
 //    Input:
-//        none
+//        toneType:        Type of tone generated (values in enum tone_type)
+//        durationMs:      The tone duration in milliseconds. If the tone is limited in time by definition,
+//              the actual duration will be the minimum of durationMs and the defined tone duration.
+//              Ommiting or setting durationMs to -1 does not limit tone duration.
 //
 //    Output:
 //        none
 //
 ////////////////////////////////////////////////////////////////////////////////
-bool ToneGenerator::startTone(int toneType) {
+bool ToneGenerator::startTone(int toneType, int durationMs) {
     bool lResult = false;
 
     if ((toneType < 0) || (toneType >= NUM_TONES))
@@ -896,6 +898,17 @@
     toneType = getToneForRegion(toneType);
     mpNewToneDesc = &sToneDescriptors[toneType];
 
+    if (durationMs == -1) {
+        mMaxSmp = TONEGEN_INF;
+    } else {
+        if (durationMs > (int)(TONEGEN_INF / mSamplingRate)) {
+            mMaxSmp = (durationMs / 1000) * mSamplingRate;
+        } else {
+            mMaxSmp = (durationMs * mSamplingRate) / 1000;
+        }
+        LOGV("startTone, duration limited to %d ms", durationMs);
+    }
+
     if (mState == TONE_INIT) {
         if (prepareWave()) {
             LOGV("Immediate start, time %d\n", (unsigned int)(systemTime()/1000000));
@@ -1102,11 +1115,17 @@
 
 
         // Exit if tone sequence is over
-        if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) {
+        if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0 ||
+            lpToneGen->mTotalSmp > lpToneGen->mMaxSmp) {
             if (lpToneGen->mState == TONE_PLAYING) {
                 lpToneGen->mState = TONE_STOPPING;
             }
-            goto audioCallback_EndLoop;
+            if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) {
+                goto audioCallback_EndLoop;
+            }
+            // fade out before stopping if maximum duraiton reached
+            lWaveCmd = WaveGenerator::WAVEGEN_STOP;
+            lpToneGen->mNextSegSmp = TONEGEN_INF; // forced to skip state machine management below
         }
 
         if (lpToneGen->mTotalSmp > lpToneGen->mNextSegSmp) {
diff --git a/media/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp
new file mode 100644
index 0000000..4772aca
--- /dev/null
+++ b/media/libstagefright/AMRExtractor.cpp
@@ -0,0 +1,238 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AMRExtractor"
+#include <utils/Log.h>
+
+#include <media/stagefright/AMRExtractor.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class AMRSource : public MediaSource {
+public:
+    AMRSource(const sp<DataSource> &source, bool isWide);
+
+    virtual status_t start(MetaData *params = NULL);
+    virtual status_t stop();
+
+    virtual sp<MetaData> getFormat();
+
+    virtual status_t read(
+            MediaBuffer **buffer, const ReadOptions *options = NULL);
+
+protected:
+    virtual ~AMRSource();
+
+private:
+    sp<DataSource> mDataSource;
+    bool mIsWide;
+
+    off_t mOffset;
+    int64_t mCurrentTimeUs;
+    bool mStarted;
+    MediaBufferGroup *mGroup;
+
+    AMRSource(const AMRSource &);
+    AMRSource &operator=(const AMRSource &);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+AMRExtractor::AMRExtractor(const sp<DataSource> &source)
+    : mDataSource(source),
+      mInitCheck(NO_INIT) {
+    String8 mimeType;
+    float confidence;
+    if (SniffAMR(mDataSource, &mimeType, &confidence)) {
+        mInitCheck = OK;
+        mIsWide = (mimeType == "audio/amr-wb");
+    }
+}
+
+AMRExtractor::~AMRExtractor() {
+}
+
+size_t AMRExtractor::countTracks() {
+    return mInitCheck == OK ? 1 : 0;
+}
+
+sp<MediaSource> AMRExtractor::getTrack(size_t index) {
+    if (mInitCheck != OK || index != 0) {
+        return NULL;
+    }
+
+    return new AMRSource(mDataSource, mIsWide);
+}
+
+sp<MetaData> AMRExtractor::getTrackMetaData(size_t index) {
+    if (mInitCheck != OK || index != 0) {
+        return NULL;
+    }
+
+    return makeAMRFormat(mIsWide);
+}
+
+// static
+sp<MetaData> AMRExtractor::makeAMRFormat(bool isWide) {
+    sp<MetaData> meta = new MetaData;
+    meta->setCString(kKeyMIMEType, isWide ? "audio/amr-wb" : "audio/3gpp");
+    meta->setInt32(kKeyChannelCount, 1);
+    meta->setInt32(kKeySampleRate, isWide ? 16000 : 8000);
+
+    return meta;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+AMRSource::AMRSource(const sp<DataSource> &source, bool isWide)
+    : mDataSource(source),
+      mIsWide(isWide),
+      mOffset(mIsWide ? 9 : 6),
+      mCurrentTimeUs(0),
+      mStarted(false),
+      mGroup(NULL) {
+}
+
+AMRSource::~AMRSource() {
+    if (mStarted) {
+        stop();
+    }
+}
+
+status_t AMRSource::start(MetaData *params) {
+    CHECK(!mStarted);
+
+    mOffset = mIsWide ? 9 : 6;
+    mCurrentTimeUs = 0;
+    mGroup = new MediaBufferGroup;
+    mGroup->add_buffer(new MediaBuffer(128));
+    mStarted = true;
+
+    return OK;
+}
+
+status_t AMRSource::stop() {
+    CHECK(mStarted);
+
+    delete mGroup;
+    mGroup = NULL;
+
+    mStarted = false;
+    return OK;
+}
+
+sp<MetaData> AMRSource::getFormat() {
+    return AMRExtractor::makeAMRFormat(mIsWide);
+}
+
+status_t AMRSource::read(
+        MediaBuffer **out, const ReadOptions *options) {
+    *out = NULL;
+
+    uint8_t header;
+    ssize_t n = mDataSource->read_at(mOffset, &header, 1);
+
+    if (n < 1) {
+        return ERROR_IO;
+    }
+
+    MediaBuffer *buffer;
+    status_t err = mGroup->acquire_buffer(&buffer);
+    if (err != OK) {
+        return err;
+    }
+
+    if (header & 0x83) {
+        // Padding bits must be 0.
+
+        return ERROR_MALFORMED;
+    }
+
+    unsigned FT = (header >> 3) & 0x0f;
+
+    if (FT > 8 || (!mIsWide && FT > 7)) {
+        return ERROR_MALFORMED;
+    }
+
+    static const size_t kFrameSizeNB[8] = {
+        95, 103, 118, 134, 148, 159, 204, 244
+    };
+    static const size_t kFrameSizeWB[9] = {
+        132, 177, 253, 285, 317, 365, 397, 461, 477
+    };
+
+    size_t frameSize = mIsWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT];
+
+    // Round up bits to bytes and add 1 for the header byte.
+    frameSize = (frameSize + 7) / 8 + 1;
+
+    n = mDataSource->read_at(mOffset, buffer->data(), frameSize);
+
+    if (n != (ssize_t)frameSize) {
+        buffer->release();
+        buffer = NULL;
+
+        return ERROR_IO;
+    }
+
+    buffer->set_range(0, frameSize);
+    buffer->meta_data()->setInt32(
+            kKeyTimeUnits, (mCurrentTimeUs + 500) / 1000);
+    buffer->meta_data()->setInt32(
+            kKeyTimeScale, 1000);
+
+    mOffset += frameSize;
+    mCurrentTimeUs += 20000;  // Each frame is 20ms
+
+    *out = buffer;
+
+    return OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool SniffAMR(
+        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
+    char header[9];
+
+    if (source->read_at(0, header, sizeof(header)) != sizeof(header)) {
+        return false;
+    }
+
+    if (!memcmp(header, "#!AMR\n", 6)) {
+        *mimeType = "audio/3gpp";
+        *confidence = 0.5;
+
+        return true;
+    } else if (!memcmp(header, "#!AMR-WB\n", 9)) {
+        *mimeType = "audio/amr-wb";
+        *confidence = 0.5;
+
+        return true;
+    }
+
+    return false;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 20b0da2..c3a4722 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -2,6 +2,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:=                 \
+        AMRExtractor.cpp          \
         CachingDataSource.cpp     \
         DataSource.cpp            \
         FileSource.cpp            \
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 02a276b..daac539 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <media/stagefright/AMRExtractor.h>
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MP3Extractor.h>
@@ -84,6 +85,7 @@
 void DataSource::RegisterDefaultSniffers() {
     RegisterSniffer(SniffMP3);
     RegisterSniffer(SniffMPEG4);
+    RegisterSniffer(SniffAMR);
 }
 
 }  // namespace android
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index 5f78e12..8afa8e1 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "MediaExtractor"
 #include <utils/Log.h>
 
+#include <media/stagefright/AMRExtractor.h>
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/MP3Extractor.h>
 #include <media/stagefright/MPEG4Extractor.h>
@@ -47,6 +48,9 @@
         return new MPEG4Extractor(source);
     } else if (!strcasecmp(mime, "audio/mpeg")) {
         return new MP3Extractor(source);
+    } else if (!strcasecmp(mime, "audio/3gpp")
+            || !strcasecmp(mime, "audio/amr-wb")) {
+        return new AMRExtractor(source);
     }
 
     return NULL;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index d01d6af..2e02697 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -49,6 +49,8 @@
     { "audio/mpeg", "OMX.PV.mp3dec" },
     { "audio/3gpp", "OMX.TI.AMR.decode" },
     { "audio/3gpp", "OMX.PV.amrdec" },
+    { "audio/amr-wb", "OMX.TI.WBAMR.decode" },
+    { "audio/amr-wb", "OMX.PV.amrdec" },
     { "audio/mp4a-latm", "OMX.TI.AAC.decode" },
     { "audio/mp4a-latm", "OMX.PV.aacdec" },
     { "video/mp4v-es", "OMX.qcom.video.decoder.mpeg4" },
@@ -65,6 +67,7 @@
 static const CodecInfo kEncoderInfo[] = {
     { "audio/3gpp", "OMX.TI.AMR.encode" },
     { "audio/3gpp", "OMX.PV.amrencnb" },
+    { "audio/amr-wb", "OMX.TI.WBAMR.encode" },
     { "audio/mp4a-latm", "OMX.TI.AAC.encode" },
     { "audio/mp4a-latm", "OMX.PV.aacenc" },
     { "video/mp4v-es", "OMX.qcom.video.encoder.mpeg4" },
@@ -317,6 +320,9 @@
     if (!strcasecmp("audio/3gpp", mime)) {
         codec->setAMRFormat();
     }
+    if (!strcasecmp("audio/amr-wb", mime)) {
+        codec->setAMRWBFormat();
+    }
     if (!strcasecmp("audio/mp4a-latm", mime)) {
         int32_t numChannels, sampleRate;
         CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
@@ -673,6 +679,7 @@
     static const MimeToRole kMimeToRole[] = {
         { "audio/mpeg", "audio_decoder.mp3", "audio_encoder.mp3" },
         { "audio/3gpp", "audio_decoder.amrnb", "audio_encoder.amrnb" },
+        { "audio/amr-wb", "audio_decoder.amrwb", "audio_encoder.amrwb" },
         { "audio/mp4a-latm", "audio_decoder.aac", "audio_encoder.aac" },
         { "video/avc",  "video_decoder.avc", "video_encoder.avc" },
         { "video/mp4v-es", "video_decoder.mpeg4", "video_encoder.mpeg4" },
@@ -1548,6 +1555,37 @@
     }
 }
 
+void OMXCodec::setAMRWBFormat() {
+    if (!mIsEncoder) {
+        OMX_AUDIO_PARAM_AMRTYPE def;
+        InitOMXParams(&def);
+        def.nPortIndex = kPortIndexInput;
+
+        status_t err =
+            mOMX->get_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
+
+        CHECK_EQ(err, OK);
+
+        def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
+        def.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0;
+
+        err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
+        CHECK_EQ(err, OK);
+    }
+
+    ////////////////////////
+
+    if (mIsEncoder) {
+        sp<MetaData> format = mSource->getFormat();
+        int32_t sampleRate;
+        int32_t numChannels;
+        CHECK(format->findInt32(kKeySampleRate, &sampleRate));
+        CHECK(format->findInt32(kKeyChannelCount, &numChannels));
+
+        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
+    }
+}
+
 void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) {
     if (mIsEncoder) {
         setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
@@ -1621,6 +1659,15 @@
             break;
         }
 
+        case OMX_COLOR_Format16bitARGB4444:
+        case OMX_COLOR_Format16bitARGB1555:
+        case OMX_COLOR_Format16bitRGB565:
+        case OMX_COLOR_Format16bitBGR565:
+        {
+            def.nBufferSize = width * height * 2;
+            break;
+        }
+
         default:
             CHECK(!"Should not be here. Unknown color format.");
             break;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
index 3f2bc39..45a5e53 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
@@ -418,13 +418,13 @@
           "13", "Jaws Of Life", "2005", "19815424", "1", "m4a composer"},
       {"/sdcard/media_api/metaDataTestMedias/M4V/sample_iPod.m4v", null, null, 
           null, null, null, "20051220T202015.000Z", 
-          null, null, null, "3771392", "2", null},
+          null, null, null, "85500", "2", null},
       {"/sdcard/media_api/metaDataTestMedias/MIDI/MIDI.mid", null, "Suspended Animation", 
           "John Petrucci", null, null, "20070510T125223.000Z", 
           null, null, "2005", "231180", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/MP4/kung_fu_panda_h264.mp4", "2/0", "mp4 album Kung Fu Panda",
           "mp4 artist Kung Fu Panda", null, null, "20080517T091451.000Z", 
-          "41", "Kung Fu Panda", "2008", "5667840", "2", "mp4 composer"},
+          "41", "Kung Fu Panda", "2008", "77113", "2", "mp4 composer"},
       {"/sdcard/media_api/metaDataTestMedias/OGG/Ring_Classic_02.ogg", null, "Suspended Animation", 
           "John Petrucci", null, null, "20070510T125223.000Z", 
           null, null, "2005", "231180", "1", null},
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index 10680dd..f3127f3 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -19,7 +19,6 @@
 import android.app.AlertDialog;
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothError;
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothIntent;
 import android.bluetooth.BluetoothPbap;
@@ -362,7 +361,7 @@
                     || action.equals(Intent.ACTION_POWER_CONNECTED)) {
                 onBatteryOkay(intent);
             }
-            else if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION) ||
+            else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) ||
                     action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION) ||
                     action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION) ||
                     action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
@@ -507,7 +506,7 @@
         filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
         filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
         filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
-        filter.addAction(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION);
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
         filter.addAction(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION);
         filter.addAction(BluetoothA2dp.SINK_STATE_CHANGED_ACTION);
         filter.addAction(BluetoothPbap.PBAP_STATE_CHANGED_ACTION);
@@ -1072,10 +1071,9 @@
         int iconId = com.android.internal.R.drawable.stat_sys_data_bluetooth;
 
         String action = intent.getAction();
-        if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION)) {
-            int state = intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE,
-                                           BluetoothError.ERROR);
-            mBluetoothEnabled = state == BluetoothAdapter.BLUETOOTH_STATE_ON;
+        if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+            mBluetoothEnabled = state == BluetoothAdapter.STATE_ON;
         } else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) {
             mBluetoothHeadsetState = intent.getIntExtra(BluetoothIntent.HEADSET_STATE,
                     BluetoothHeadset.STATE_ERROR);
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index e818175..5203d3f 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -1189,17 +1189,9 @@
     List<DataConnection> getCurrentDataConnectionList ();
 
     /**
-     * Udpate LAC and CID in service state for currnet GSM netowrk registration
-     *
-     * If get different LAC and/or CID, notifyServiceState will be sent
-     *
-     * @param
-     * <strong>On failure</strong>,
-     * (((AsyncResult)response.obj).result) == null and
-     * (((AsyncResult)response.obj).exception) being an instance of
-     * com.android.internal.telephony.gsm.CommandException
+     * Update the ServiceState CellLocation for current network registration.
      */
-    void updateServiceLocation(Message response);
+    void updateServiceLocation();
 
     /**
      * Enable location update notifications.
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index 8683278..711a48c 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -566,8 +566,8 @@
         return mActivePhone.getCurrentDataConnectionList();
     }
 
-    public void updateServiceLocation(Message response) {
-        mActivePhone.updateServiceLocation(response);
+    public void updateServiceLocation() {
+        mActivePhone.updateServiceLocation();
     }
 
     public void enableLocationUpdates() {
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index cc13450..6892998 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -226,12 +226,43 @@
         setPowerStateToDesired();
     }
 
-    public void enableLocationUpdates() {
+    /**
+     * These two flags manage the behavior of the cell lock -- the
+     * lock should be held if either flag is true.  The intention is
+     * to allow temporary aquisition of the lock to get a single
+     * update.  Such a lock grab and release can thus be made to not
+     * interfere with more permanent lock holds -- in other words, the
+     * lock will only be released if both flags are false, and so
+     * releases by temporary users will only affect the lock state if
+     * there is no continuous user.
+     */
+    private boolean mWantContinuousLocationUpdates;
+    private boolean mWantSingleLocationUpdate;
+
+    public void enableSingleLocationUpdate() {
+        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
+        mWantSingleLocationUpdate = true;
         cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
     }
 
+    public void enableLocationUpdates() {
+        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
+        mWantContinuousLocationUpdates = true;
+        cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
+    }
+
+    protected void disableSingleLocationUpdate() {
+        mWantSingleLocationUpdate = false;
+        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
+            cm.setLocationUpdates(false, null);
+        }
+    }
+
     public void disableLocationUpdates() {
-        cm.setLocationUpdates(false, null);
+        mWantContinuousLocationUpdates = false;
+        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
+            cm.setLocationUpdates(false, null);
+        }
     }
 
     public abstract void handleMessage(Message msg);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index ff06bc0..dfc4889 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -500,8 +500,8 @@
         Log.e(LOG_TAG, "method setCallWaiting is NOT supported in CDMA!");
     }
 
-    public void updateServiceLocation(Message response) {
-        mSST.getLacAndCid(response);
+    public void updateServiceLocation() {
+        mSST.enableSingleLocationUpdate();
     }
 
     public void setDataRoamingEnabled(boolean enable) {
@@ -661,6 +661,10 @@
         mSST.enableLocationUpdates();
     }
 
+    public void disableLocationUpdates() {
+        mSST.disableLocationUpdates();
+    }
+
     /**
      * @deprecated
      */
@@ -741,10 +745,6 @@
         }
     }
 
-    public void disableLocationUpdates() {
-        mSST.disableLocationUpdates();
-    }
-
     public boolean getIccRecordsLoaded() {
         return mRuimRecords.getRecordsLoaded();
     }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 46e360b..9ac78eb 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -279,12 +279,6 @@
         cdmaForSubscriptionInfoReadyRegistrants.remove(h);
     }
 
-    public void
-    getLacAndCid(Message onComplete) {
-        cm.getRegistrationState(obtainMessage(
-                EVENT_GET_LOC_DONE_CDMA, onComplete));
-    }
-
     @Override
     public void handleMessage (Message msg) {
         AsyncResult ar;
@@ -377,22 +371,14 @@
                     }
                 }
 
-                // Only update if cell location really changed.
-                if (cellLoc.getBaseStationId() != baseStationData[0]
-                        || cellLoc.getBaseStationLatitude() != baseStationData[1]
-                        || cellLoc.getBaseStationLongitude() != baseStationData[2]) {
-                    cellLoc.setCellLocationData(baseStationData[0],
-                                                baseStationData[1],
-                                                baseStationData[2]);
-                   phone.notifyLocationChanged();
-                }
+                cellLoc.setCellLocationData(baseStationData[0],
+                        baseStationData[1], baseStationData[2]);
+                phone.notifyLocationChanged();
             }
 
-            if (ar.userObj != null) {
-                AsyncResult.forMessage(((Message) ar.userObj)).exception
-                = ar.exception;
-                ((Message) ar.userObj).sendToTarget();
-            }
+            // Release any temporary cell lock, which could have been
+            // aquired to allow a single-shot location update.
+            disableSingleLocationUpdate();
             break;
 
         case EVENT_POLL_STATE_REGISTRATION_CDMA:
@@ -487,7 +473,7 @@
             ar = (AsyncResult) msg.obj;
 
             if (ar.exception == null) {
-                getLacAndCid(null);
+                cm.getRegistrationState(obtainMessage(EVENT_GET_LOC_DONE_CDMA, null));
             }
             break;
 
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 2c20784..d17468c 100755
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -598,21 +598,20 @@
     }
 
     /**
-     * Calculate the next message id, starting at 0 and iteratively
-     * incrementing within the range 0..65535 remembering the state
+     * Calculate the next message id, starting at 1 and iteratively
+     * incrementing within the range 1..65535 remembering the state
      * via a persistent system property.  (See C.S0015-B, v2.0,
-     * 4.3.1.5)
+     * 4.3.1.5) Since this routine is expected to be accessed via via
+     * binder-call, and hence should be threadsafe, it has been
+     * synchronized.
      */
     private synchronized static int getNextMessageId() {
-        // The only (meaningful) way this code can be called is via
-        // binder-call into the Phone process.  All other calls will
-        // assumedly not be as with UID radio, and hence will be
-        // unable to modify the system property.  Synchronization has
-        // thus been added to this function conservatively -- if it
-        // can be conclusively reasoned to be unnecessary, it should
-        // be removed.
-        int msgId = SystemProperties.getInt(TelephonyProperties.PROPERTY_CDMA_MSG_ID, 0);
-        String nextMsgId = Integer.toString((msgId + 1) & 0xFFFF);
+        // Testing and dialog with partners has indicated that
+        // msgId==0 is (sometimes?) treated specially by lower levels.
+        // Specifically, the ID is not preserved for delivery ACKs.
+        // Hence, avoid 0 -- constraining the range to 1..65535.
+        int msgId = SystemProperties.getInt(TelephonyProperties.PROPERTY_CDMA_MSG_ID, 1);
+        String nextMsgId = Integer.toString((msgId % 0xFFFF) + 1);
         SystemProperties.set(TelephonyProperties.PROPERTY_CDMA_MSG_ID, nextMsgId);
         if (DBG_SMS) {
             Log.d(LOG_TAG, "next " + TelephonyProperties.PROPERTY_CDMA_MSG_ID + " = " + nextMsgId);
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index ac7331e..2fc2e13 100755
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -1099,8 +1099,8 @@
         return mDataConnection.getAllDataConnections();
     }
 
-    public void updateServiceLocation(Message response) {
-        mSST.getLacAndCid(response);
+    public void updateServiceLocation() {
+        mSST.enableSingleLocationUpdate();
     }
 
     public void enableLocationUpdates() {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 65463e5..003899b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -314,11 +314,6 @@
         return mDataRoaming;
     }
 
-    public void getLacAndCid(Message onComplete) {
-        cm.getRegistrationState(obtainMessage(
-                        EVENT_GET_LOC_DONE, onComplete));
-    }
-
     public void handleMessage (Message msg) {
         AsyncResult ar;
         int[] ints;
@@ -391,19 +386,13 @@
                             Log.w(LOG_TAG, "error parsing location: " + ex);
                         }
                     }
-
-                    // only update if lac or cid changed
-                    if (cellLoc.getCid() != cid || cellLoc.getLac() != lac) {
-                        cellLoc.setLacAndCid(lac, cid);
-                        phone.notifyLocationChanged();
-                    }
+                    cellLoc.setLacAndCid(lac, cid);
+                    phone.notifyLocationChanged();
                 }
 
-                if (ar.userObj != null) {
-                    AsyncResult.forMessage(((Message) ar.userObj)).exception
-                            = ar.exception;
-                    ((Message) ar.userObj).sendToTarget();
-                }
+                // Release any temporary cell lock, which could have been
+                // aquired to allow a single-shot location update.
+                disableSingleLocationUpdate();
                 break;
 
             case EVENT_POLL_STATE_REGISTRATION:
@@ -451,7 +440,7 @@
                 ar = (AsyncResult) msg.obj;
 
                 if (ar.exception == null) {
-                    getLacAndCid(null);
+                    cm.getRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
                 }
                 break;
 
diff --git a/tests/AndroidTests/src/com/android/unit_tests/GsmSmsTest.java b/tests/AndroidTests/src/com/android/unit_tests/GsmSmsTest.java
index 24698fb..8987d6b 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/GsmSmsTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/GsmSmsTest.java
@@ -20,53 +20,39 @@
 import com.android.internal.telephony.SmsHeader;
 import com.android.internal.telephony.gsm.SmsMessage;
 import com.android.internal.util.HexDump;
+
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import java.util.Iterator;
+import android.util.Log;
 
 public class GsmSmsTest extends AndroidTestCase {
 
     @SmallTest
-    public void testOne() throws Exception {
+    public void testAddressing() throws Exception {
         String pdu = "07914151551512f2040B916105551511f100006060605130308A04D4F29C0E";
-
         SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
         assertEquals("+14155551212", sms.getServiceCenterAddress());
         assertEquals("+16505551111", sms.getOriginatingAddress());
         assertEquals("Test", sms.getMessageBody());
-        //assertTrue(sms.scTimeMillis == 1152223383000L);
 
         pdu = "07914151551512f2040B916105551511f100036060924180008A0DA"
                 + "8695DAC2E8FE9296A794E07";
-
         sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
         assertEquals("+14155551212", sms.getServiceCenterAddress());
         assertEquals("+16505551111", sms.getOriginatingAddress());
         assertEquals("(Subject)Test", sms.getMessageBody());
+    }
 
-        /*        lines[0] = "+CMT: ,45";
-                lines[1] = "07914140279510F6440A8111110301003BF56070624111958A8C0B05040B8423F"
-                         + "000033702010106276170706C69636174696F6E2F766E642E7761702E6D6D732D"
-                         + "6D65737361676500AF848D018BB4848C8298524D66616E304A6D7135514141416"
-                         + "57341414141546741414E4E304141414141008D908918802B3136353032343836"
-                         + "3137392F545950453D504C4D4E009646573A20008A808E0222C788058103093A7"
-                         + "F836874";
-
-                sms = SMSMessage.createFromPdu(mContext, lines);
-        */
-
-        pdu = "07914140279510F6440A8111110301003BF56080207130138A8C0B05040B8423F"
+    @SmallTest
+    public void testUdh() throws Exception {
+        String pdu = "07914140279510F6440A8111110301003BF56080207130138A8C0B05040B8423F"
                 + "000032A02010106276170706C69636174696F6E2F766E642E7761702E6D6D732D"
                 + "6D65737361676500AF848D0185B4848C8298524E453955304A6D7135514141426"
                 + "66C414141414D7741414236514141414141008D908918802B3135313232393737"
                 + "3638332F545950453D504C4D4E008A808E022B918805810306977F83687474703"
                 + "A2F2F36";
-
-        sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
+        SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
         SmsHeader header = sms.getUserDataHeader();
         assertNotNull(header);
         assertNotNull(header.concatRef);
@@ -83,7 +69,6 @@
                 + "000032A0202362E3130322E3137312E3135302F524E453955304A6D7135514141"
                 + "42666C414141414D774141423651414141414100";
         sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
         header = sms.getUserDataHeader();
         assertNotNull(header);
         assertNotNull(header.concatRef);
@@ -95,46 +80,33 @@
         assertEquals(header.portAddrs.destPort, 2948);
         assertEquals(header.portAddrs.origPort, 9200);
         assertEquals(header.portAddrs.areEightBits, false);
+    }
 
-        /*
-        * UCS-2 encoded SMS
-        */
-
-        pdu = "07912160130300F4040B914151245584F600087010807121352B10212200A900AE00680065006C006C006F";
-
-        sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
+    @SmallTest
+    public void testUcs2() throws Exception {
+        String pdu = "07912160130300F4040B914151245584F600087010807121352B1021220"
+                + "0A900AE00680065006C006C006F";
+        SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
         assertEquals("\u2122\u00a9\u00aehello", sms.getMessageBody());
+    }
 
-        // Entire alphabet (minus the escape character)
-
-        /****
-         lines[0] = "+CMT: ";
-         lines[1] = "0001000A8114455245680000808080604028180E888462C168381E90886442A9582E988C06C0E9783EA09068442A994EA8946AC56AB95EB0986C46ABD96EB89C6EC7EBF97EC0A070482C1A8FC8A472C96C3A9FD0A8744AAD5AAFD8AC76CBED7ABFE0B0784C2E9BCFE8B47ACD6EBBDFF0B87C4EAFDBEFF8BC7ECFEFFBFF";
-         sms = SMSMessage.createFromPdu(mContext, lines);
-
-         System.out.println("full alphabet message body len: "
-         + sms.getMessageBody().length());
-
-         System.out.println("'" + sms.getMessageBody() +"'");
-
-         assertTrue(sms.getMessageBody().length() == 128);
-         ****/
-
+    @SmallTest
+    public void testMultipart() throws Exception {
         /*
-        * Multi-part text SMS with data in septets
-        */
-        pdu = "07916163838408F6440B816105224431F700007060217175830AA0050003"
+         * Multi-part text SMS with septet data.
+         */
+        String pdu = "07916163838408F6440B816105224431F700007060217175830AA0050003"
                 + "00020162B1582C168BC562B1582C168BC562B1582C168BC562B1582C"
                 + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C"
                 + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C"
                 + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C"
                 + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562";
-        sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
+        SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
         assertEquals(sms.getMessageBody(),
                 "1111111111111111111111111111111111111111"
-                        + "1111111111111111111111111111111111111111"
-                        + "1111111111111111111111111111111111111111"
-                        + "111111111111111111111111111111111");
+                + "1111111111111111111111111111111111111111"
+                + "1111111111111111111111111111111111111111"
+                + "111111111111111111111111111111111");
 
         pdu = "07916163838408F6440B816105224431F700007060217185000A23050003"
                 + "00020262B1582C168BC96432994C2693C96432994C2693C96432990C";
@@ -169,10 +141,6 @@
 
         sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
 
-//        System.out.println("originating address: "
-//                + (int) (sms.getOriginatingAddress().charAt(0)) + " "
-//                + (int) (sms.getOriginatingAddress().charAt(1)));
-
         assertTrue(sms.isReplace());
         assertEquals("\u0394@", sms.getOriginatingAddress());
         assertEquals(" ", sms.getMessageBody());
@@ -198,16 +166,8 @@
         assertTrue(sms.isMwiDontStore());
     }
 
-//    public void testTwo() throws Exception {
-//        // FIXME need an SMS-SUBMIT test
-//
-//        System.out.println(
-//                "SMS SUBMIT: " + SmsMessage.getSubmitPdu(null, "+14155551212", "test", false));
-//    }
-
     @SmallTest
     public void testEmailGateway() throws Exception {
-        // email gateway sms test
         String pdu = "07914151551512f204038105f300007011103164638a28e6f71b50c687db" +
                 "7076d9357eb7412f7a794e07cdeb6275794c07bde8e5391d247e93f3";
 
@@ -217,9 +177,11 @@
         assertTrue(sms.isEmail());
         assertEquals("foo@example.com", sms.getEmailFrom());
         assertEquals("foo@example.com", sms.getDisplayOriginatingAddress());
-        assertEquals("test subject", sms.getPseudoSubject());
-        assertEquals("test body", sms.getDisplayMessageBody());
-        assertEquals("test body", sms.getEmailBody());
+        // As of https://android-git.corp.google.com/g/#change,9324
+        // getPseudoSubject will always be empty, and any subject is not extracted.
+        assertEquals("", sms.getPseudoSubject());
+        assertEquals("test subject /test body", sms.getDisplayMessageBody());
+        assertEquals("test subject /test body", sms.getEmailBody());
 
         // email gateway sms test, including gsm extended character set.
         pdu = "07914151551512f204038105f400007011103105458a29e6f71b50c687db" +
@@ -245,7 +207,8 @@
 
         assertEquals("+14155551212", sms.getServiceCenterAddress());
         assertEquals("+16505551111", sms.getOriginatingAddress());
-        assertEquals("Test extended character table .,-!?@~_\\/&\"';^|:()<{}>[]=%*+#", sms.getMessageBody());
+        assertEquals("Test extended character table .,-!?@~_\\/&\"';^|:()<{}>[]=%*+#",
+                sms.getMessageBody());
     }
 
     @SmallTest
@@ -285,4 +248,5 @@
             assertEquals(reEncoded[i + 1], septets[i]);
         }
     }
+
 }
diff --git a/tests/CoreTests/android/webkit/CookieTest.java b/tests/CoreTests/android/webkit/CookieTest.java
index ea4422f..5c5a6a8 100644
--- a/tests/CoreTests/android/webkit/CookieTest.java
+++ b/tests/CoreTests/android/webkit/CookieTest.java
@@ -188,6 +188,6 @@
 
         mCookieManager.setCookie(url, "a=d");
         cookie = mCookieManager.getCookie(url + "/wee");
-        assertTrue(cookie.equals("a=b; a=c; a=d"));
+        assertTrue(cookie.equals("a=b; a=d"));
     }
 }