Merge change 26732 into eclair

* changes:
  Make ContactStruct explicitly set RawContacts.ACCOUNT_NAME and RawContacts.ACCOUNT_TYPE to null.
diff --git a/api/current.xml b/api/current.xml
index 2672d53..c8fbb52 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -2825,6 +2825,17 @@
  visibility="public"
 >
 </field>
+<field name="detachWallpaper"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843430"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="detailColumn"
  type="int"
  transient="false"
@@ -3562,6 +3573,17 @@
  visibility="public"
 >
 </field>
+<field name="finishOnCloseSystemDialogs"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843431"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="finishOnTaskLaunch"
  type="int"
  transient="false"
@@ -39174,6 +39196,17 @@
  visibility="public"
 >
 </field>
+<field name="FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="256"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="FLAG_FINISH_ON_TASK_LAUNCH"
  type="int"
  transient="false"
@@ -122092,6 +122125,17 @@
  visibility="public"
 >
 </field>
+<field name="PHONE_TYPE_CDMA"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="PHONE_TYPE_GSM"
  type="int"
  transient="false"
@@ -153724,6 +153768,19 @@
  visibility="public"
 >
 </method>
+<method name="onCloseSystemDialogs"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="reason" type="java.lang.String">
+</parameter>
+</method>
 <method name="onCreateContextMenu"
  return="void"
  abstract="false"
@@ -162482,6 +162539,17 @@
  visibility="protected"
 >
 </method>
+<method name="getDetachWallpaper"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getDuration"
  return="long"
  abstract="false"
@@ -162728,6 +162796,19 @@
 <parameter name="listener" type="android.view.animation.Animation.AnimationListener">
 </parameter>
 </method>
+<method name="setDetachWallpaper"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="detachWallpaper" type="boolean">
+</parameter>
+</method>
 <method name="setDuration"
  return="void"
  abstract="false"
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 99e513c..834a664 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -14,11 +14,14 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "BootAnimation"
+
 #include <stdint.h>
 #include <sys/types.h>
 #include <math.h>
 #include <fcntl.h>
 #include <utils/misc.h>
+#include <signal.h>
 
 #include <binder/IPCThreadState.h>
 #include <utils/threads.h>
@@ -58,13 +61,29 @@
 }
 
 void BootAnimation::onFirstRef() {
-    run("BootAnimation", PRIORITY_DISPLAY);
+    status_t err = mSession->linkToComposerDeath(this);
+    LOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
+    if (err == NO_ERROR) {
+        run("BootAnimation", PRIORITY_DISPLAY);
+    }
 }
 
-const sp<SurfaceComposerClient>& BootAnimation::session() const {
+sp<SurfaceComposerClient> BootAnimation::session() const {
     return mSession;
 }
 
+
+void BootAnimation::binderDied(const wp<IBinder>& who)
+{
+    // woah, surfaceflinger died!
+    LOGD("SurfaceFlinger died, exiting...");
+
+    // calling requestExit() is not enough here because the Surface code
+    // might be blocked on a condition variable that will never be updated.
+    kill( getpid(), SIGKILL );
+    requestExit();
+}
+
 status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
         const char* name) {
     Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 796077d..afd01fa 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -37,18 +37,19 @@
 
 // ---------------------------------------------------------------------------
 
-class BootAnimation : public Thread
+class BootAnimation : public Thread, public IBinder::DeathRecipient
 {
 public:
                 BootAnimation();
     virtual     ~BootAnimation();
 
-    const sp<SurfaceComposerClient>& session() const;
+    sp<SurfaceComposerClient> session() const;
 
 private:
     virtual bool        threadLoop();
     virtual status_t    readyToRun();
     virtual void        onFirstRef();
+    virtual void        binderDied(const wp<IBinder>& who);
 
     struct Texture {
         GLint   w;
diff --git a/cmds/keystore/certtool.h b/cmds/keystore/certtool.h
deleted file mode 100644
index 9b72bf7..0000000
--- a/cmds/keystore/certtool.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-**
-** Copyright 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 __CERTTOOL_H__
-#define __CERTTOOL_H__
-
-#include <stdio.h>
-#include <string.h>
-#include <cutils/sockets.h>
-#include <cutils/log.h>
-
-#include "common.h"
-#include "netkeystore.h"
-
-#define CERT_NAME_LEN (2 * MAX_KEY_NAME_LENGTH + 2)
-
-/*
- * The specific function 'get_cert' is used in daemons to get the key value
- * from keystore. Caller should allocate the buffer and the length of the buffer
- * should be MAX_KEY_VALUE_LENGTH.
- */
-static inline int get_cert(const char *certname, unsigned char *value, int *size)
-{
-    int count, fd, ret = -1;
-    LPC_MARSHAL cmd;
-    char delimiter[] = "_";
-    char *p = NULL;
-    char *context = NULL;
-    char *cname = (char*)cmd.data;
-
-    if ((certname == NULL) || (value == NULL)) {
-        LOGE("get_cert: certname or value is null\n");
-        return -1;
-    }
-
-    if (strlcpy(cname, certname, CERT_NAME_LEN) >= CERT_NAME_LEN) {
-        LOGE("get_cert: keyname is too long\n");
-        return -1;
-    }
-
-    fd = socket_local_client(SOCKET_PATH,
-                             ANDROID_SOCKET_NAMESPACE_RESERVED,
-                             SOCK_STREAM);
-    if (fd == -1) {
-        LOGE("Keystore service is not up and running.\n");
-        return -1;
-    }
-
-    cmd.opcode = GET;
-    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");
-        goto err;
-    }
-    if (read_marshal(fd, &cmd)) {
-        LOGE("Failed to read the result.\n");
-        goto err;
-    }
-
-    // copy the result if succeeded.
-    if (!cmd.retcode && cmd.len <= BUFFER_MAX) {
-        memcpy(value, cmd.data, cmd.len);
-        ret = 0;
-        *size = cmd.len;
-    }
-err:
-    close(fd);
-    return ret;
-}
-
-#endif
diff --git a/cmds/keystore/common.h b/cmds/keystore/common.h
deleted file mode 100644
index a18114e..0000000
--- a/cmds/keystore/common.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-**
-** Copyright 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 __COMMON_H__
-#define __COMMON_H__
-
-#define SOCKET_PATH             "keystore"
-#define KEYSTORE_DIR            "/data/misc/keystore/"
-
-#define READ_TIMEOUT            3
-#define MAX_KEY_NAME_LENGTH     64
-#define MAX_NAMESPACE_LENGTH    MAX_KEY_NAME_LENGTH
-#define MAX_KEY_VALUE_LENGTH    4096
-
-#define BUFFER_MAX              MAX_KEY_VALUE_LENGTH
-
-typedef enum {
-    BOOTUP,
-    UNINITIALIZED,
-    LOCKED,
-    UNLOCKED,
-} KEYSTORE_STATE;
-
-typedef enum {
-    LOCK,
-    UNLOCK,
-    PASSWD,
-    GETSTATE,
-    LISTKEYS,
-    GET,
-    PUT,
-    REMOVE,
-    RESET,
-    MAX_OPCODE
-} KEYSTORE_OPCODE;
-
-typedef struct {
-    uint32_t  len;
-    union {
-        uint32_t  opcode;
-        uint32_t  retcode;
-    };
-    unsigned char data[BUFFER_MAX + 1];
-} LPC_MARSHAL;
-
-#endif
diff --git a/cmds/keystore/keymgmt.c b/cmds/keystore/keymgmt.c
deleted file mode 100644
index b5ace86..0000000
--- a/cmds/keystore/keymgmt.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
-** Copyright 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.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <errno.h>
-#include <openssl/aes.h>
-#include <openssl/evp.h>
-#include <cutils/log.h>
-
-#include "common.h"
-#include "keymgmt.h"
-
-static int  retry_count = 0;
-static unsigned char iv[IV_LEN];
-static KEYSTORE_STATE state = BOOTUP;
-static AES_KEY encryptKey, decryptKey;
-
-inline void unlock_keystore(unsigned char *master_key)
-{
-    AES_set_encrypt_key(master_key, AES_KEY_LEN, &encryptKey);
-    AES_set_decrypt_key(master_key, AES_KEY_LEN, &decryptKey);
-    memset(master_key, 0, sizeof(master_key));
-    state = UNLOCKED;
-}
-
-inline void lock_keystore()
-{
-    memset(&encryptKey, 0 , sizeof(AES_KEY));
-    memset(&decryptKey, 0 , sizeof(AES_KEY));
-    state = LOCKED;
-}
-
-inline void get_encrypt_key(char *passwd, AES_KEY *key)
-{
-    unsigned char user_key[USER_KEY_LEN];
-    gen_key(passwd, user_key, USER_KEY_LEN);
-    AES_set_encrypt_key(user_key, AES_KEY_LEN, key);
-}
-
-inline void get_decrypt_key(char *passwd, AES_KEY *key)
-{
-    unsigned char user_key[USER_KEY_LEN];
-    gen_key(passwd, user_key, USER_KEY_LEN);
-    AES_set_decrypt_key(user_key, AES_KEY_LEN, key);
-}
-
-static int gen_random_blob(unsigned char *key, int size)
-{
-    int ret = 0;
-    int fd = open("/dev/urandom", O_RDONLY);
-    if (fd == -1) return -1;
-    if (read(fd, key, size) != size) ret = -1;
-    close(fd);
-    return ret;
-}
-
-static int encrypt_n_save(AES_KEY *enc_key, DATA_BLOB *blob,
-                          const char *keyfile)
-{
-    int size, fd, ret = -1;
-    unsigned char enc_blob[MAX_BLOB_LEN];
-    char tmpfile[KEYFILE_LEN];
-
-    if ((keyfile == NULL) || (strlen(keyfile) >= (KEYFILE_LEN - 4))) {
-        LOGE("keyfile name is too long or null");
-        return -1;
-    }
-    strcpy(tmpfile, keyfile);
-    strcat(tmpfile, ".tmp");
-
-    // prepare the blob
-    if (IV_LEN > USER_KEY_LEN) {
-        LOGE("iv length is too long.");
-        return -1;
-    }
-    memcpy(blob->iv, iv, IV_LEN);
-    blob->blob_size = get_blob_size(blob);
-    if (blob->blob_size > MAX_BLOB_LEN) {
-        LOGE("blob data size is too large.");
-        return -1;
-    }
-    memcpy(enc_blob, blob->blob, blob->blob_size);
-    AES_cbc_encrypt((unsigned char *)enc_blob, (unsigned char *)blob->blob,
-                    blob->blob_size, enc_key, iv, AES_ENCRYPT);
-    // write to keyfile
-    size = data_blob_size(blob);
-    if ((fd = open(tmpfile, O_CREAT|O_RDWR)) == -1) return -1;
-    if (write(fd, blob, size) == size) ret = 0;
-    close(fd);
-    if (!ret) {
-        unlink(keyfile);
-        rename(tmpfile, keyfile);
-        chmod(keyfile, 0440);
-    }
-    return ret;
-}
-
-static int load_n_decrypt(const char *keyname, const char *keyfile,
-                          AES_KEY *key, DATA_BLOB *blob)
-{
-    int fd, ret = -1;
-    if ((fd = open(keyfile, O_RDONLY)) == -1) return -1;
-    // get the encrypted blob and iv
-    if ((read(fd, blob->iv, sizeof(blob->iv)) != sizeof(blob->iv)) ||
-        (read(fd, &blob->blob_size, sizeof(uint32_t)) != sizeof(uint32_t)) ||
-        (blob->blob_size > MAX_BLOB_LEN)) {
-        goto err;
-    } else {
-        unsigned char enc_blob[MAX_BLOB_LEN];
-        if (read(fd, enc_blob, blob->blob_size) !=
-            (int) blob->blob_size) goto err;
-        // decrypt the blob
-        AES_cbc_encrypt((unsigned char *)enc_blob, (unsigned char*)blob->blob,
-                        blob->blob_size, key, blob->iv, AES_DECRYPT);
-        if (strcmp(keyname, (char*)blob->keyname) == 0) ret = 0;
-    }
-err:
-    close(fd);
-    return ret;
-}
-
-static int store_master_key(char *upasswd, unsigned char *master_key)
-{
-    AES_KEY key;
-    DATA_BLOB blob;
-
-    // prepare the blob
-    if (strlen(MASTER_KEY_TAG) >= USER_KEY_LEN) return -1;
-    strlcpy(blob.keyname, MASTER_KEY_TAG, USER_KEY_LEN);
-    blob.value_size = USER_KEY_LEN;
-    if (USER_KEY_LEN > MAX_KEY_VALUE_LENGTH) {
-        LOGE("master_key length is too long.");
-        return -1;
-    }
-    memcpy((void*)blob.value, (const void*)master_key, USER_KEY_LEN);
-
-    // generate the encryption key
-    get_encrypt_key(upasswd, &key);
-    return encrypt_n_save(&key, &blob, MASTER_KEY);
-}
-
-static int get_master_key(char *upasswd, unsigned char *master_key)
-{
-    AES_KEY key;
-    int size, ret = 0;
-    DATA_BLOB blob;
-
-    get_decrypt_key(upasswd, &key);
-    ret = load_n_decrypt(MASTER_KEY_TAG, MASTER_KEY, &key, &blob);
-    if (blob.value_size > USER_KEY_LEN) {
-        LOGE("the blob's value size is too large");
-        return -1;
-    }
-    if (!ret) memcpy(master_key, blob.value, blob.value_size);
-    return ret;
-}
-
-static int create_master_key(char *upasswd)
-{
-    int ret;
-    unsigned char mpasswd[AES_KEY_LEN];
-    unsigned char master_key[USER_KEY_LEN];
-
-    gen_random_blob(mpasswd, AES_KEY_LEN);
-    gen_key((char*)mpasswd, master_key, USER_KEY_LEN);
-    if ((ret = store_master_key(upasswd, master_key)) == 0) {
-        unlock_keystore(master_key);
-    }
-    memset(master_key, 0, USER_KEY_LEN);
-    memset(mpasswd, 0, AES_KEY_LEN);
-
-    return ret;
-}
-
-int change_passwd(char *old_pass, char *new_pass)
-{
-    unsigned char master_key[USER_KEY_LEN];
-    int ret;
-
-    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;
-    } else {
-        ret = MAX_RETRY_COUNT - ++retry_count;
-        if (ret == 0) {
-            retry_count = 0;
-            LOGE("passwd:reach max retry count, reset the keystore now.");
-            reset_keystore();
-            return -1;
-        }
-
-    }
-    return ret;
-}
-
-int remove_key(const char *namespace, const char *keyname)
-{
-    char keyfile[KEYFILE_LEN];
-
-    if (state != UNLOCKED) return -state;
-    if ((strlen(namespace) >= MAX_KEY_NAME_LENGTH) ||
-        (strlen(keyname) >= MAX_KEY_NAME_LENGTH)) {
-        LOGE("keyname is too long.");
-        return -1;
-    }
-    sprintf(keyfile, KEYFILE_NAME, namespace, keyname);
-    return unlink(keyfile);
-}
-
-int put_key(const char *namespace, const char *keyname,
-            unsigned char *data, int size)
-{
-    DATA_BLOB blob;
-    uint32_t  real_size;
-    char keyfile[KEYFILE_LEN];
-
-    if (state != UNLOCKED) {
-        LOGE("Can not store key with current state %d\n", state);
-        return -state;
-    }
-    if ((strlen(namespace) >= MAX_KEY_NAME_LENGTH) ||
-        (strlen(keyname) >= MAX_KEY_NAME_LENGTH)) {
-        LOGE("keyname is too long.");
-        return -1;
-    }
-    sprintf(keyfile, KEYFILE_NAME, namespace, keyname);
-    strcpy(blob.keyname, keyname);
-    blob.value_size = size;
-    if (size > MAX_KEY_VALUE_LENGTH) {
-        LOGE("the data size is too large.");
-        return -1;
-    }
-    memcpy(blob.value, data, size);
-    return encrypt_n_save(&encryptKey, &blob, keyfile);
-}
-
-int get_key(const char *namespace, const char *keyname,
-            unsigned char *data, int *size)
-{
-    int ret;
-    DATA_BLOB blob;
-    uint32_t  blob_size;
-    char keyfile[KEYFILE_LEN];
-
-    if (state != UNLOCKED) {
-        LOGE("Can not retrieve key value with current state %d\n", state);
-        return -state;
-    }
-    if ((strlen(namespace) >= MAX_KEY_NAME_LENGTH) ||
-        (strlen(keyname) >= MAX_KEY_NAME_LENGTH)) {
-        LOGE("keyname is too long.");
-        return -1;
-    }
-    sprintf(keyfile, KEYFILE_NAME, namespace, keyname);
-    ret = load_n_decrypt(keyname, keyfile, &decryptKey, &blob);
-    if (!ret) {
-        if ((blob.value_size > MAX_KEY_VALUE_LENGTH)) {
-            LOGE("blob value size is too large.");
-            ret = -1;
-        } else {
-            *size = blob.value_size;
-            memcpy(data, blob.value, *size);
-        }
-    }
-    return ret;
-}
-
-int list_keys(const char *namespace, char reply[BUFFER_MAX])
-{
-    DIR *d;
-    struct dirent *de;
-
-    if (state != UNLOCKED) {
-        LOGE("Can not list key with current state %d\n", state);
-        return -1;
-    }
-
-    if (!namespace || ((d = opendir("."))) == NULL) {
-        LOGE("cannot open keystore dir or namespace is null\n");
-        return -1;
-    }
-
-    if (strlen(namespace) >= MAX_KEY_NAME_LENGTH) {
-        LOGE("namespace is too long.");
-        return -1;
-    }
-
-    reply[0] = 0;
-    while ((de = readdir(d))) {
-        char *prefix, *name, *keyfile = de->d_name;
-        char *context = NULL;
-
-        if (de->d_type != DT_REG) continue;
-        if ((prefix = strtok_r(keyfile, NAME_DELIMITER, &context))
-            == NULL) continue;
-        if (strcmp(prefix, namespace)) continue;
-        if ((name = strtok_r(NULL, NAME_DELIMITER, &context)) == NULL) continue;
-        // append the key name into reply
-        if (reply[0] != 0) strlcat(reply, " ", BUFFER_MAX);
-        if (strlcat(reply, name, BUFFER_MAX) >= BUFFER_MAX) {
-            LOGE("too many files under keystore directory\n");
-            return -1;
-        }
-    }
-    closedir(d);
-    return 0;
-}
-
-int new_passwd(char *password)
-{
-    int passwdlen = strlen(password);
-
-    if ((state != UNINITIALIZED) || (passwdlen < MIN_PASSWD_LENGTH)) return -1;
-    return create_master_key(password);
-}
-
-int lock()
-{
-    switch(state) {
-        case UNLOCKED:
-            lock_keystore();
-        case LOCKED:
-            return 0;
-        default:
-            return -1;
-    }
-}
-
-int unlock(char *passwd)
-{
-    unsigned char master_key[USER_KEY_LEN];
-    int ret = get_master_key(passwd, master_key);
-    if (!ret) {
-        unlock_keystore(master_key);
-        retry_count = 0;
-    } else {
-        ret = MAX_RETRY_COUNT - ++retry_count;
-        if (ret == 0) {
-            retry_count = 0;
-            LOGE("unlock:reach max retry count, reset the keystore now.");
-            reset_keystore();
-            return -1;
-        }
-    }
-    return ret;
-}
-
-KEYSTORE_STATE get_state()
-{
-    return state;
-}
-
-int reset_keystore()
-{
-    int ret = 0;
-    DIR *d;
-    struct dirent *de;
-
-    if ((d = opendir(".")) == NULL) {
-        LOGE("cannot open keystore dir\n");
-        return -1;
-    }
-    while ((de = readdir(d))) {
-        char *dirname = de->d_name;
-        if (strcmp(".", dirname) == 0) continue;
-        if (strcmp("..", dirname) == 0) continue;
-        if (unlink(dirname) != 0) ret = -1;
-    }
-    closedir(d);
-    state = UNINITIALIZED;
-    if (ret == 0) {
-        LOGI("keystore is reset.");
-    } else {
-        LOGI("keystore can not be cleaned up entirely.");
-    }
-    return ret;
-}
-
-int init_keystore(const char *dir)
-{
-    int fd;
-
-    if (dir) mkdir(dir, 0770);
-    if (!dir || chdir(dir)) {
-        LOGE("Can not open/create the keystore directory %s\n",
-             dir ? dir : "(null)");
-        return -1;
-    }
-    gen_random_blob(iv, IV_LEN);
-    if ((fd = open(MASTER_KEY, O_RDONLY)) == -1) {
-        state = UNINITIALIZED;
-        return 0;
-    }
-    close(fd);
-    state = LOCKED;
-    return 0;
-}
diff --git a/cmds/keystore/keymgmt.h b/cmds/keystore/keymgmt.h
deleted file mode 100644
index 116d7a3..0000000
--- a/cmds/keystore/keymgmt.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-** Copyright 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 __KEYMGMT_H__
-#define __KEYMGMT_H__
-
-#define MASTER_KEY_TAG  "master_key"
-#define MASTER_KEY      ".keymaster"
-#define MAX_PATH_LEN    128
-#define SALT            "Android Keystore 0.1"
-#define NAME_DELIMITER  "_"
-#define KEYFILE_NAME    "%s"NAME_DELIMITER"%s"
-#define KEYGEN_ITER     1024
-#define AES_KEY_LEN     128
-#define USER_KEY_LEN    (AES_KEY_LEN/8)
-#define IV_LEN          USER_KEY_LEN
-#define MAX_RETRY_COUNT   6
-#define MIN_PASSWD_LENGTH 8
-
-#define gen_key(passwd, key, len) \
-                PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), \
-                                       (unsigned char*)SALT, \
-                                       strlen(SALT), KEYGEN_ITER, \
-                                       len, key)
-
-#define KEYFILE_LEN MAX_NAMESPACE_LENGTH + MAX_KEY_NAME_LENGTH + 6
-
-#define get_blob_size(blob) \
-        (((blob->value_size + sizeof(uint32_t) + MAX_KEY_NAME_LENGTH \
-        + USER_KEY_LEN - 1) / USER_KEY_LEN) * USER_KEY_LEN)
-
-#define MAX_BLOB_LEN    ((MAX_KEY_VALUE_LENGTH + MAX_KEY_NAME_LENGTH + \
-                         sizeof(uint32_t) + USER_KEY_LEN - 1) / USER_KEY_LEN)\
-                         * USER_KEY_LEN
-
-#define data_blob_size(blob) USER_KEY_LEN + sizeof(uint32_t) + blob->blob_size
-
-typedef struct {
-    unsigned char iv[USER_KEY_LEN];
-    uint32_t blob_size;
-    union {
-        unsigned char blob[1];
-        struct {
-            uint32_t value_size;
-            char keyname[MAX_KEY_NAME_LENGTH];
-            unsigned char value[MAX_KEY_VALUE_LENGTH];
-        } __attribute__((packed));
-    };
-} DATA_BLOB;
-
-typedef struct {
-    char tag[USER_KEY_LEN];
-    unsigned char master_key[USER_KEY_LEN];
-} MASTER_BLOB;
-
-int put_key(const char *namespace, const char *keyname,
-            unsigned char *data, int size);
-int get_key(const char *namespace, const char *keyname,
-            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 new_passwd(char *password);
-int change_passwd(char *old_pass, char *new_pass);
-int lock();
-int unlock(char *passwd);
-KEYSTORE_STATE get_state();
-int reset_keystore();
-int init_keystore(const char *dir);
-
-#endif
diff --git a/cmds/keystore/netkeystore.c b/cmds/keystore/netkeystore.c
deleted file mode 100644
index 87fdc80..0000000
--- a/cmds/keystore/netkeystore.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
-** Copyright 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.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <utime.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <private/android_filesystem_config.h>
-
-#include <cutils/sockets.h>
-#include <cutils/log.h>
-#include <cutils/properties.h>
-
-#include "netkeystore.h"
-#include "keymgmt.h"
-
-#define  DBG  1
-#define  CMD_PUT_WITH_FILE  "putfile"
-
-typedef void CMD_FUNC(LPC_MARSHAL *cmd, LPC_MARSHAL *reply);
-
-struct cmdinfo {
-    const char *name;
-    CMD_FUNC *func;
-};
-
-static CMD_FUNC do_lock;
-static CMD_FUNC do_unlock;
-static CMD_FUNC do_passwd;
-static CMD_FUNC do_get_state;;
-static CMD_FUNC do_listkeys;
-static CMD_FUNC do_get_key;
-static CMD_FUNC do_put_key;
-static CMD_FUNC do_remove_key;
-static CMD_FUNC do_reset_keystore;
-
-#define str(x)      #x
-
-struct cmdinfo cmds[] = {
-    { str(LOCK),           do_lock },
-    { str(UNLOCK),         do_unlock },
-    { str(PASSWD),         do_passwd },
-    { str(GETSTATE),       do_get_state },
-    { str(LISTKEYS),       do_listkeys },
-    { str(GET),            do_get_key },
-    { str(PUT),            do_put_key },
-    { str(REMOVE),         do_remove_key },
-    { str(RESET),          do_reset_keystore },
-};
-
-static  struct ucred cr;
-
-static int check_get_perm(int uid)
-{
-    if (uid == AID_WIFI || uid == AID_VPN) return 0;
-    return -1;
-}
-
-static int check_reset_perm(int uid)
-{
-    if (uid == AID_SYSTEM) return 0;
-    return -1;
-}
-
-/**
- * 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;
-    va_list args;
-    char *p = data, **q;
-
-    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;
-        }
-    }
-    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)
-{
-    char *s0 = s;
-    while (*s != 0) {
-        if (!isalnum(*s++)) {
-            LOGE("The string '%s' is not an alphanumeric string\n", s0);
-            return 0;
-        }
-    }
-    return 1;
-}
-
-// args of passwd():
-// firstPassword - for the first time
-// oldPassword newPassword - for changing the password
-static void do_passwd(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
-{
-    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():
-// no argument
-static void do_lock(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
-{
-    reply->retcode = lock();
-}
-
-// args of unlock():
-// password
-static void do_unlock(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
-{
-    reply->retcode = unlock((char*)cmd->data);
-}
-
-// args of get_state():
-// no argument
-static void do_get_state(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
-{
-    int s = get_state();
-    if (DBG) LOGD("keystore state = %d\n", s);
-    reply->retcode = s;
-}
-
-// args of listkeys():
-// namespace
-static void do_listkeys(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
-{
-    reply->retcode = list_keys((const char*)cmd->data, (char*)reply->data);
-    if (!reply->retcode) reply->len = strlen((char*)reply->data);
-}
-
-// args of get():
-// namespace keyname
-static void do_get_key(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
-{
-    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);
-        reply->retcode = -1;
-        return;
-    }
-
-    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,
-                                 (int*)&reply->len);
-    }
-}
-
-static int get_value_index(LPC_MARSHAL *cmd)
-{
-    uint32_t count = 0, i;
-    for (i = 0 ; i < cmd->len ; ++i) {
-        if (cmd->data[i] == ' ') {
-            if (++count == 2) return ++i;
-        }
-    }
-    return -1;
-}
-
-// args of put():
-// namespace keyname keyvalue
-static void do_put_key(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
-{
-    char *namespace = NULL, *keyname = NULL;
-    char *value = NULL;
-
-    if (parse_strings((char*)cmd->data, cmd->len, 3, &namespace, &keyname, &value) ||
-        !is_alnum_string(namespace) || !is_alnum_string(keyname)) {
-        reply->retcode = -1;
-        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 = 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;
-    }
-    reply->retcode = remove_key(namespace, keyname);
-}
-
-// args of reset_keystore():
-// no argument
-static void do_reset_keystore(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
-{
-    if (check_reset_perm(cr.uid)) {
-        LOGE("uid %d doesn't have the permission to reset the keystore\n",
-             cr.uid);
-        reply->retcode = -1;
-        return;
-    }
-    reply->retcode = reset_keystore();
-}
-
-void execute(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
-{
-    uint32_t cmd_max = sizeof(cmds)/sizeof(struct cmdinfo);
-
-    if (cmd->opcode >= cmd_max) {
-        LOGE("the opcode (%d) is not valid", cmd->opcode);
-        reply->retcode = -1;
-        return;
-    }
-    cmds[cmd->opcode].func(cmd, reply);
-}
-
-static int set_read_timeout(int socket)
-{
-    struct timeval tv;
-    tv.tv_sec = READ_TIMEOUT;
-    tv.tv_usec = 0;
-    if (setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,  sizeof tv))
-    {
-        LOGE("setsockopt failed");
-        return -1;
-    }
-    return 0;
-}
-
-static int append_input_from_file(const char *filename, LPC_MARSHAL *cmd)
-{
-    int fd, len, ret = 0;
-
-    // get opcode of the function put()
-    if ((fd = open(filename, O_RDONLY)) == -1) {
-        fprintf(stderr, "Can not open file %s\n", filename);
-        return -1;
-    }
-    len = read(fd, cmd->data + cmd->len, BUFFER_MAX - cmd->len);
-    if (len < 0 || (len == (int)(BUFFER_MAX - cmd->len))) {
-        ret = -1;
-    } else {
-        cmd->len += len;
-    }
-    close(fd);
-    return ret;
-}
-
-static int flatten_str_args(int argc, const char **argv, LPC_MARSHAL *cmd)
-{
-    int i, len = 0;
-    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) + 1);
-        } else {
-            len += (snprintf(buf + len, BUFFER_MAX - len, "%s", argv[i]) + 1);
-        }
-        if (len >= BUFFER_MAX) return -1;
-    }
-    if (len) cmd->len = len ;
-    return 0;
-}
-
-int parse_cmd(int argc, const char **argv, LPC_MARSHAL *cmd)
-{
-    uint32_t i, len = 0;
-    uint32_t cmd_max = sizeof(cmds)/sizeof(cmds[0]);
-
-    for (i = 0 ; i < cmd_max ; ++i) {
-        if (!strcasecmp(argv[0], cmds[i].name)) break;
-    }
-
-    if (i == cmd_max) {
-        // check if this is a command to put the key value with a file.
-        if (strcmp(argv[0], CMD_PUT_WITH_FILE) != 0) return -1;
-        cmd->opcode = PUT;
-        if (argc != 4) {
-            fprintf(stderr, "%s args\n\tnamespace keyname filename\n",
-                    argv[0]);
-            return -1;
-        }
-        if (flatten_str_args(argc - 2, argv + 1, cmd)) return -1;
-        return append_input_from_file(argv[3], cmd);
-    } else {
-        cmd->opcode = i;
-        return flatten_str_args(argc - 1, argv + 1, cmd);
-    }
-}
-
-int shell_command(const int argc, const char **argv)
-{
-    int fd, i;
-    LPC_MARSHAL  cmd;
-
-    if (parse_cmd(argc, argv, &cmd)) {
-        fprintf(stderr, "Incorrect command or command line is too long.\n");
-        return -1;
-    }
-    fd = socket_local_client(SOCKET_PATH,
-                             ANDROID_SOCKET_NAMESPACE_RESERVED,
-                             SOCK_STREAM);
-    if (fd == -1) {
-        fprintf(stderr, "Keystore service is not up and running.\n");
-        return -1;
-    }
-
-    if (write_marshal(fd, &cmd)) {
-        fprintf(stderr, "Incorrect command or command line is too long.\n");
-        return -1;
-    }
-    if (read_marshal(fd, &cmd)) {
-        fprintf(stderr, "Failed to read the result.\n");
-        return -1;
-    }
-    cmd.data[cmd.len] = 0;
-    fprintf(stdout, "%s\n", (cmd.retcode == 0) ? "Succeeded!" : "Failed!");
-    if (cmd.len) fprintf(stdout, "\t%s\n", (char*)cmd.data);
-    close(fd);
-    return 0;
-}
-
-int server_main(const int argc, const char *argv[])
-{
-    struct sockaddr addr;
-    socklen_t alen;
-    int lsocket, s;
-    LPC_MARSHAL  cmd, reply;
-
-    if (init_keystore(KEYSTORE_DIR)) {
-        LOGE("Can not initialize the keystore, the directory exist?\n");
-        return -1;
-    }
-
-    lsocket = android_get_control_socket(SOCKET_PATH);
-    if (lsocket < 0) {
-        LOGE("Failed to get socket from environment: %s\n", strerror(errno));
-        return -1;
-    }
-    if (listen(lsocket, 5)) {
-        LOGE("Listen on socket failed: %s\n", strerror(errno));
-        return -1;
-    }
-    fcntl(lsocket, F_SETFD, FD_CLOEXEC);
-    memset(&reply, 0, sizeof(LPC_MARSHAL));
-
-    for (;;) {
-        socklen_t cr_size = sizeof(cr);
-        alen = sizeof(addr);
-        s = accept(lsocket, &addr, &alen);
-
-        /* retrieve the caller info here */
-        if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cr_size) < 0) {
-            close(s);
-            LOGE("Unable to recieve socket options\n");
-            continue;
-        }
-
-        if (s < 0) {
-            LOGE("Accept failed: %s\n", strerror(errno));
-            continue;
-        }
-        fcntl(s, F_SETFD, FD_CLOEXEC);
-        if (set_read_timeout(s)) {
-            close(s);
-            continue;
-        }
-
-        // read the command, execute and send the result back.
-        if(read_marshal(s, &cmd)) goto err;
-        execute(&cmd, &reply);
-        write_marshal(s, &reply);
-err:
-        memset(&reply, 0, sizeof(LPC_MARSHAL));
-        close(s);
-    }
-
-    return 0;
-}
diff --git a/cmds/keystore/netkeystore.h b/cmds/keystore/netkeystore.h
deleted file mode 100644
index e2ffd8b..0000000
--- a/cmds/keystore/netkeystore.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
-**
-** Copyright 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 __NETKEYSTORE_H__
-#define __NETKEYSTORE_H__
-
-#include <stdio.h>
-#include <arpa/inet.h>
-#include <cutils/sockets.h>
-#include <cutils/log.h>
-
-#include "common.h"
-
-// for testing
-int parse_cmd(int argc, const char **argv, LPC_MARSHAL *cmd);
-void execute(LPC_MARSHAL *cmd, LPC_MARSHAL *reply);
-
-static inline int readx(int s, void *_buf, int count)
-{
-    char *buf = _buf;
-    int n = 0, r;
-    if (count < 0) return -1;
-    while (n < count) {
-        r = read(s, buf + n, count - n);
-        if (r < 0) {
-            if (errno == EINTR) continue;
-            LOGE("read error: %s\n", strerror(errno));
-            return -1;
-        }
-        if (r == 0) {
-            LOGE("eof\n");
-            return -1; /* EOF */
-        }
-        n += r;
-    }
-    return 0;
-}
-
-static inline int writex(int s, const void *_buf, int count)
-{
-    const char *buf = _buf;
-    int n = 0, r;
-    if (count < 0) return -1;
-    while (n < count) {
-        r = write(s, buf + n, count - n);
-        if (r < 0) {
-            if (errno == EINTR) continue;
-            LOGE("write error: %s\n", strerror(errno));
-            return -1;
-        }
-        n += r;
-    }
-    return 0;
-}
-
-static inline int read_marshal(int s, LPC_MARSHAL *cmd)
-{
-    if (readx(s, cmd, 2 * sizeof(uint32_t))) {
-        LOGE("failed to read header\n");
-        return -1;
-    }
-    cmd->len = ntohl(cmd->len);
-    cmd->opcode = ntohl(cmd->opcode);
-    if (cmd->len > BUFFER_MAX) {
-        LOGE("invalid size %d\n", cmd->len);
-        return -1;
-    }
-    if (readx(s, cmd->data, cmd->len)) {
-        LOGE("failed to read data\n");
-        return -1;
-    }
-    cmd->data[cmd->len] = 0;
-    return 0;
-}
-
-static inline int write_marshal(int s, LPC_MARSHAL *cmd)
-{
-    int len = cmd->len;
-    cmd->len = htonl(cmd->len);
-    cmd->opcode = htonl(cmd->opcode);
-    if (writex(s, cmd, 2 * sizeof(uint32_t))) {
-        LOGE("failed to write marshal header\n");
-        return -1;
-    }
-    if (writex(s, cmd->data, len)) {
-        LOGE("failed to write marshal data\n");
-        return -1;
-    }
-    return 0;
-}
-
-#endif
diff --git a/cmds/keystore/netkeystore_main.c b/cmds/keystore/netkeystore_main.c
deleted file mode 100644
index 606e67a..0000000
--- a/cmds/keystore/netkeystore_main.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-** Copyright 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_TAG "keystore"
-
-int shell_command(const int argc, const char **argv);
-int server_main(const int argc, const char *argv[]);
-
-int main(const int argc, const char *argv[])
-{
-    if (argc > 1) {
-        return shell_command(argc - 1, argv + 1);
-    } else {
-        return server_main(argc, argv);
-    }
-}
diff --git a/cmds/keystore/tests/Android.mk b/cmds/keystore/tests/Android.mk
deleted file mode 100644
index e0a776a..0000000
--- a/cmds/keystore/tests/Android.mk
+++ /dev/null
@@ -1,28 +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.
-#
-# define the KEYSTORE_TESTS environment variable to build the test programs
-ifdef KEYSTORE_TESTS
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= netkeystore_test.c ../keymgmt.c ../netkeystore.c
-LOCAL_SHARED_LIBRARIES := libcutils libssl
-LOCAL_MODULE:= netkeystore_test
-LOCAL_MODULE_TAGS := optional
-LOCAL_C_INCLUDES := external/openssl/include \
-								frameworks/base/cmds/keystore
-EXTRA_CFLAGS := -g -O0 -DGTEST_OS_LINUX -DGTEST_HAS_STD_STRING
-include $(BUILD_EXECUTABLE)
-
-endif  #KEYSTORE_TESTS
diff --git a/cmds/keystore/tests/netkeystore_test.c b/cmds/keystore/tests/netkeystore_test.c
deleted file mode 100644
index ce79503..0000000
--- a/cmds/keystore/tests/netkeystore_test.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <cutils/log.h>
-
-#include "common.h"
-#include "keymgmt.h"
-#include "netkeystore.h"
-
-#define LOG_TAG "keystore_test"
-
-typedef int FUNC_PTR();
-typedef struct {
-    const char *name;
-    FUNC_PTR *func;
-} TESTFUNC;
-
-#define FUNC_NAME(x) { #x, test_##x }
-#define FUNC_BODY(x) int test_##x()
-
-#define TEST_PASSWD        "12345678"
-#define TEST_NPASSWD    "hello world"
-#define TEST_DIR        "/data/local/tmp/keystore"
-#define READONLY_DIR    "/proc/keystore"
-#define TEST_NAMESPACE    "test"
-#define TEST_KEYNAME    "key"
-#define TEST_KEYNAME2    "key2"
-#define TEST_KEYVALUE    "ANDROID"
-
-void setup()
-{
-    if (init_keystore(TEST_DIR) != 0) {
-        fprintf(stderr, "Can not create the test directory %s\n", TEST_DIR);
-        exit(-1);
-    }
-}
-
-void teardown()
-{
-    if (reset_keystore() != 0) {
-        fprintf(stderr, "Can not reset the test directory %s\n", TEST_DIR);
-    }
-    rmdir(TEST_DIR);
-}
-
-FUNC_BODY(init_keystore)
-{
-    if (init_keystore(READONLY_DIR) == 0) return -1;
-
-    return EXIT_SUCCESS;
-}
-
-FUNC_BODY(reset_keystore)
-{
-    int ret = chdir("/proc");
-    if (reset_keystore() == 0) return -1;
-    chdir(TEST_DIR);
-    return EXIT_SUCCESS;
-}
-
-FUNC_BODY(get_state)
-{
-    if (get_state() != UNINITIALIZED) return -1;
-    new_passwd(TEST_PASSWD);
-    if (get_state() != UNLOCKED) return -1;
-    lock();
-    if (get_state() != LOCKED) return -1;
-
-    if (reset_keystore() != 0) return -1;
-    if (get_state() != UNINITIALIZED) return -1;
-    return EXIT_SUCCESS;
-}
-
-FUNC_BODY(passwd)
-{
-    char buf[512];
-
-    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
-    if (change_passwd("klfdjdsklfjg", "abcdefghi") == 0) return -1;
-
-    if (change_passwd(TEST_PASSWD, TEST_NPASSWD) != 0) return -1;
-    lock();
-
-    if (unlock(TEST_PASSWD) == 0) return -1;
-    if (unlock(TEST_NPASSWD) != 0) return -1;
-
-    return EXIT_SUCCESS;
-}
-
-FUNC_BODY(lock)
-{
-    if (lock() == 0) return -1;
-    new_passwd(TEST_PASSWD);
-    if (lock() != 0) return -1;
-    if (lock() != 0) return -1;
-    return EXIT_SUCCESS;
-}
-
-FUNC_BODY(unlock)
-{
-    int i = MAX_RETRY_COUNT;
-    new_passwd(TEST_PASSWD);
-    lock();
-    while (i > 1) {
-        if (unlock(TEST_NPASSWD) != --i) return -1;
-    }
-    if (unlock(TEST_NPASSWD) != -1) return -1;
-    return EXIT_SUCCESS;
-}
-
-FUNC_BODY(put_key)
-{
-    int i = 0;
-    char keyname[512];
-
-    if (put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
-                strlen(TEST_KEYVALUE)) == 0) return -1;
-    new_passwd(TEST_PASSWD);
-    if (put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
-                strlen(TEST_KEYVALUE)) != 0) return -1;
-
-    for(i = 0; i < 500; i++) keyname[i] = 'K';
-    keyname[i] = 0;
-    if (put_key(TEST_NAMESPACE, keyname, (unsigned char *)TEST_KEYVALUE,
-                strlen(TEST_KEYVALUE)) == 0) return -1;
-    if (put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
-                MAX_KEY_VALUE_LENGTH + 1) == 0) return -1;
-    return EXIT_SUCCESS;
-}
-
-FUNC_BODY(get_key)
-{
-    int size;
-    unsigned char data[MAX_KEY_VALUE_LENGTH];
-
-    if (get_key(TEST_NAMESPACE, TEST_KEYNAME, data, &size) == 0) return -1;
-
-    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;
-    if (memcmp(data, TEST_KEYVALUE, size) != 0) return -1;
-
-    return EXIT_SUCCESS;
-}
-
-FUNC_BODY(remove_key)
-{
-    if (remove_key(TEST_NAMESPACE, TEST_KEYNAME) == 0) return -1;
-
-    new_passwd(TEST_PASSWD);
-    if (remove_key(TEST_NAMESPACE, TEST_KEYNAME) == 0) return -1;
-
-    put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
-            strlen(TEST_KEYVALUE));
-    if (remove_key(TEST_NAMESPACE, TEST_KEYNAME) != 0) return -1;
-
-    return EXIT_SUCCESS;
-}
-
-FUNC_BODY(list_keys)
-{
-    int i;
-    char buf[128];
-    char reply[BUFFER_MAX];
-
-    for(i = 0; i < 100; i++) buf[i] = 'K';
-    buf[i] = 0;
-
-    if (list_keys(TEST_NAMESPACE, reply) == 0) return -1;
-
-    new_passwd(TEST_PASSWD);
-    if (list_keys(buf, reply) == 0) return -1;
-
-    if (list_keys(TEST_NAMESPACE, reply) != 0) return -1;
-    if (strcmp(reply, "") != 0) return -1;
-
-    put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
-            strlen(TEST_KEYVALUE));
-    if (list_keys(TEST_NAMESPACE, reply) != 0) return -1;
-    if (strcmp(reply, TEST_KEYNAME) != 0) return -1;
-
-    put_key(TEST_NAMESPACE, TEST_KEYNAME2, (unsigned char *)TEST_KEYVALUE,
-            strlen(TEST_KEYVALUE));
-
-    if (list_keys(TEST_NAMESPACE, reply) != 0) return -1;
-    sprintf(buf, "%s %s", TEST_KEYNAME2, TEST_KEYNAME);
-    if (strcmp(reply, buf) != 0) return -1;
-
-    return EXIT_SUCCESS;
-}
-
-static int execute_cmd(int argc, const char *argv[], LPC_MARSHAL *cmd,
-        LPC_MARSHAL *reply)
-{
-    memset(cmd, 0, sizeof(LPC_MARSHAL));
-    memset(reply, 0, sizeof(LPC_MARSHAL));
-    if (parse_cmd(argc, argv, cmd)) return -1;
-    execute(cmd, reply);
-    return (reply->retcode ? -1 : 0);
-}
-
-FUNC_BODY(client_passwd)
-{
-    LPC_MARSHAL cmd, reply;
-    const char *set_passwd_cmds[2] = {"passwd", TEST_PASSWD};
-    const char *change_passwd_cmds[3] = {"passwd", TEST_PASSWD, TEST_NPASSWD};
-
-    if (execute_cmd(2, set_passwd_cmds, &cmd, &reply)) return -1;
-
-    lock();
-    if (unlock("55555555") == 0) return -1;
-    if (unlock(TEST_PASSWD) != 0) return -1;
-
-    if (execute_cmd(3, change_passwd_cmds, &cmd, &reply)) return -1;
-
-    lock();
-    if (unlock(TEST_PASSWD) == 0) return -1;
-    if (unlock(TEST_NPASSWD) != 0) return -1;
-
-    return EXIT_SUCCESS;
-}
-
-TESTFUNC all_tests[] = {
-    FUNC_NAME(init_keystore),
-    FUNC_NAME(reset_keystore),
-    FUNC_NAME(get_state),
-    FUNC_NAME(passwd),
-    FUNC_NAME(lock),
-    FUNC_NAME(unlock),
-    FUNC_NAME(put_key),
-    FUNC_NAME(get_key),
-    FUNC_NAME(remove_key),
-    FUNC_NAME(list_keys),
-    FUNC_NAME(client_passwd),
-};
-
-int main(int argc, char **argv) {
-    int i, ret;
-    for (i = 0 ; i < (int)(sizeof(all_tests)/sizeof(TESTFUNC)) ; ++i) {
-        LOGD("run %s...\n", all_tests[i].name);
-        setup();
-        if ((ret = all_tests[i].func()) != EXIT_SUCCESS) {
-            fprintf(stderr, "ERROR in function %s\n", all_tests[i].name);
-            return ret;
-        } else {
-            fprintf(stderr, "function %s PASSED!\n", all_tests[i].name);
-        }
-        teardown();
-    }
-    return EXIT_SUCCESS;
-}
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 32a2997..2d2e75f 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -73,6 +73,10 @@
 public class AccountManagerService
         extends IAccountManager.Stub
         implements RegisteredServicesCacheListener {
+    private static final String GOOGLE_ACCOUNT_TYPE = "com.google.GAIA";
+
+    private static final String NO_BROADCAST_FLAG = "nobroadcast";
+
     private static final String TAG = "AccountManagerService";
 
     private static final int TIMEOUT_DELAY_MS = 1000 * 60;
@@ -357,6 +361,14 @@
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         db.beginTransaction();
         try {
+            boolean noBroadcast = false;
+            if (account.type.equals(GOOGLE_ACCOUNT_TYPE)) {
+                // Look for the 'nobroadcast' flag and remove it since we don't want it to persist
+                // in the db.
+                noBroadcast = extras.getBoolean(NO_BROADCAST_FLAG, false);
+                extras.remove(NO_BROADCAST_FLAG);
+            }
+
             long numMatches = DatabaseUtils.longForQuery(db,
                     "select count(*) from " + TABLE_ACCOUNTS
                             + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
@@ -381,7 +393,9 @@
                 }
             }
             db.setTransactionSuccessful();
-            sendAccountsChangedBroadcast();
+            if (!noBroadcast) {
+                sendAccountsChangedBroadcast();
+            }
             return true;
         } finally {
             db.endTransaction();
@@ -608,6 +622,10 @@
     public void setUserData(Account account, String key, String value) {
         checkAuthenticateAccountsPermission(account);
         long identityToken = clearCallingIdentity();
+        if (account.type.equals(GOOGLE_ACCOUNT_TYPE) && key.equals("broadcast")) {
+            sendAccountsChangedBroadcast();
+            return;
+        }
         try {
             writeUserdataIntoDatabase(account, key, value);
         } finally {
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index eff6f52..1c61324d 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -208,6 +208,15 @@
         }
     };
 
+    private BroadcastReceiver mBackgroundDataSettingChanged = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            if (getConnectivityManager().getBackgroundDataSetting()) {
+                scheduleSync(null /* account */, null /* authority */, new Bundle(), 0 /* delay */,
+                        false /* onlyThoseWithUnknownSyncableState */);
+            }
+        }
+    };
+
     public void onAccountsUpdated(Account[] accounts) {
         // remember if this was the first time this was called after an update
         final boolean justBootedUp = mAccounts == null;
@@ -351,6 +360,9 @@
         intentFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
         context.registerReceiver(mBootCompletedReceiver, intentFilter);
 
+        intentFilter = new IntentFilter(ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
+        context.registerReceiver(mBackgroundDataSettingChanged, intentFilter);
+
         intentFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
         intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
         context.registerReceiver(mStorageIntentReceiver, intentFilter);
@@ -687,8 +699,8 @@
                             if (isLoggable) {
                                 Log.d(TAG, "scheduleSync: sync of " + account + ", " + authority
                                         + " is not allowed, dropping request");
-                                continue;
                             }
+                            continue;
                         }
                     }
                     if (isLoggable) {
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 1ad13c5..87da55f 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -127,12 +127,20 @@
      */
     public static final int FLAG_NO_HISTORY = 0x0080;
     /**
+     * Bit in {@link #flags} indicating that, when a request to close system
+     * windows happens, this activity is finished.
+     * Set from the
+     * {@link android.R.attr#finishOnCloseSystemDialogs} attribute.
+     */
+    public static final int FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS = 0x0100;
+    /**
      * Options that have been set in the activity declaration in the
      * manifest: {@link #FLAG_MULTIPROCESS},
      * {@link #FLAG_FINISH_ON_TASK_LAUNCH}, {@link #FLAG_CLEAR_TASK_ON_LAUNCH},
      * {@link #FLAG_ALWAYS_RETAIN_TASK_STATE},
      * {@link #FLAG_STATE_NOT_NEEDED}, {@link #FLAG_EXCLUDE_FROM_RECENTS},
-     * {@link #FLAG_ALLOW_TASK_REPARENTING}, {@link #FLAG_NO_HISTORY}.
+     * {@link #FLAG_ALLOW_TASK_REPARENTING}, {@link #FLAG_NO_HISTORY},
+     * {@link #FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS}.
      */
     public int flags;
 
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index b4a6fee..27c65f0 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1658,6 +1658,12 @@
             a.info.flags |= ActivityInfo.FLAG_ALLOW_TASK_REPARENTING;
         }
 
+        if (sa.getBoolean(
+                com.android.internal.R.styleable.AndroidManifestActivity_finishOnCloseSystemDialogs,
+                false)) {
+            a.info.flags |= ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
+        }
+
         if (!receiver) {
             a.info.launchMode = sa.getInt(
                     com.android.internal.R.styleable.AndroidManifestActivity_launchMode,
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 5f1a3c5..e47ea84 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1093,17 +1093,18 @@
         }
 
         /**
-         * Sets the orientation of the device in degrees, which instructs the
-         * camera driver to rotate the picture and thumbnail, in order to match
-         * what the user sees from the viewfinder. For example, suppose the
-         * natural position of the device is landscape. If the user takes a
+         * Sets the orientation of the device in degrees. For example, suppose
+         * the natural position of the device is landscape. If the user takes a
          * picture in landscape mode in 2048x1536 resolution, the rotation
          * should be set to 0. If the user rotates the phone 90 degrees
          * clockwise, the rotation should be set to 90. Applications can use
          * {@link android.view.OrientationEventListener} to set this parameter.
          *
-         * Since the picture is rotated, the orientation in the EXIF header is
-         * missing or always 1 (row #0 is top and column #0 is left side).
+         * The camera driver may set orientation in the EXIF header without
+         * rotating the picture. Or the driver may rotate the picture and
+         * the EXIF thumbnail. If the Jpeg picture is rotated, the orientation
+         * in the EXIF header will be missing or 1 (row #0 is top and column #0
+         * is left side).
          *
          * @param rotation The orientation of the device in degrees. Rotation
          *                 can only be 0, 90, 180 or 270.
diff --git a/core/java/android/net/WebAddress.java b/core/java/android/net/WebAddress.java
index f6159de..f4ae66a 100644
--- a/core/java/android/net/WebAddress.java
+++ b/core/java/android/net/WebAddress.java
@@ -54,7 +54,7 @@
     static Pattern sAddressPattern = Pattern.compile(
             /* scheme    */ "(?:(http|HTTP|https|HTTPS|file|FILE)\\:\\/\\/)?" +
             /* authority */ "(?:([-A-Za-z0-9$_.+!*'(),;?&=]+(?:\\:[-A-Za-z0-9$_.+!*'(),;?&=]+)?)@)?" +
-            /* host      */ "([-A-Za-z0-9%_]+(?:\\.[-A-Za-z0-9%_]+)*)?" +
+            /* host      */ "([-A-Za-z0-9%_]+(?:\\.[-A-Za-z0-9%_]+)*|\\[[0-9a-fA-F:\\.]+\\])?" +
             /* port      */ "(?:\\:([0-9]+))?" +
             /* path      */ "(\\/?.*)?");
 
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 3df228d..6b2ab3f 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -21,6 +21,7 @@
 import android.content.ContentProviderOperation;
 import android.content.ContentResolver;
 import android.content.ContentUris;
+import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
@@ -38,10 +39,11 @@
 
 /**
  * The contract between the contacts provider and applications. Contains definitions
- * for the supported URIs and columns.
+ * for the supported URIs and columns. These APIs supersede {@link Contacts}.
  *
- * @hide pending API council approval
+ * @hide
  */
+@SuppressWarnings("unused")
 public final class ContactsContract {
     /** The authority for the contacts provider */
     public static final String AUTHORITY = "com.android.contacts";
@@ -57,10 +59,19 @@
      */
     public static final String CALLER_IS_SYNCADAPTER = "caller_is_syncadapter";
 
+    /**
+     * @hide should be removed when users are updated to refer to SyncState
+     * @deprecated use SyncState instead
+     */
     public interface SyncStateColumns extends SyncStateContract.Columns {
     }
 
-    public static final class SyncState {
+    /**
+     * A table provided for sync adapters to use for storing private sync state data.
+     *
+     * @see SyncStateContract
+     */
+    public static final class SyncState implements SyncStateContract.Columns {
         /**
          * This utility class cannot be instantiated
          */
@@ -130,7 +141,8 @@
      */
     private interface SyncColumns extends BaseSyncColumns {
         /**
-         * The name of the account instance to which this row belongs.
+         * The name of the account instance to which this row belongs, which when paired with
+         * {@link #ACCOUNT_TYPE} identifies a specific account.
          * <P>Type: TEXT</P>
          */
         public static final String ACCOUNT_NAME = "account_name";
@@ -163,15 +175,15 @@
         public static final String DIRTY = "dirty";
     }
 
-    public interface ContactOptionsColumns {
+    private interface ContactOptionsColumns {
         /**
-         * The number of times a person has been contacted
+         * The number of times a contact has been contacted
          * <P>Type: INTEGER</P>
          */
         public static final String TIMES_CONTACTED = "times_contacted";
 
         /**
-         * The last time a person was contacted.
+         * The last time a contact was contacted.
          * <P>Type: INTEGER</P>
          */
         public static final String LAST_TIME_CONTACTED = "last_time_contacted";
@@ -183,13 +195,13 @@
         public static final String STARRED = "starred";
 
         /**
-         * A custom ringtone associated with a person. Not always present.
+         * A custom ringtone associated with a contact. Not always present.
          * <P>Type: TEXT (URI to the ringtone)</P>
          */
         public static final String CUSTOM_RINGTONE = "custom_ringtone";
 
         /**
-         * Whether the person should always be sent to voicemail. Not always
+         * Whether the contact should always be sent to voicemail. Not always
          * present.
          * <P>Type: INTEGER (0 for false, 1 for true)</P>
          */
@@ -216,7 +228,7 @@
         public static final String IN_VISIBLE_GROUP = "in_visible_group";
 
         /**
-         * Contact presence status.  See {@link android.provider.Im.CommonPresenceColumns}
+         * Contact presence status.  See {@link PresenceColumns}
          * for individual status definitions.  This column is only returned if explicitly
          * requested in the query projection.
          * <p>Type: NUMBER</p>
@@ -246,7 +258,7 @@
 
     /**
      * Constants for the contacts table, which contains a record per group
-     * of raw contact representing the same person.
+     * of raw contacts representing the same person.
      */
     public static class Contacts implements BaseColumns, ContactsColumns,
             ContactOptionsColumns {
@@ -342,6 +354,20 @@
         }
 
         /**
+         * Mark a contact as having been contacted.
+         *
+         * @param resolver the ContentResolver to use
+         * @param contactId the person who was contacted
+         */
+        public static void markAsContacted(ContentResolver resolver, long contactId) {
+            Uri uri = ContentUris.withAppendedId(CONTENT_URI, contactId);
+            ContentValues values = new ContentValues();
+            // TIMES_CONTACTED will be incremented when LAST_TIME_CONTACTED is modified.
+            values.put(LAST_TIME_CONTACTED, System.currentTimeMillis());
+            resolver.update(uri, values, null, null);
+        }
+
+        /**
          * The content:// style URI used for "type-to-filter" functionality on the
          * {@link #CONTENT_URI} URI. The filter string will be used to match
          * various parts of the contact name. The filter argument should be passed
@@ -383,6 +409,29 @@
         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact";
 
         /**
+         * An optional query parameter added to {@link Groups#CONTENT_URI} or
+         * {@link Settings#CONTENT_URI} signaling that any update of
+         * {@link Contacts#STARRED} should not be triggered based on
+         * {@link Groups#GROUP_VISIBLE} or {@link Settings#UNGROUPED_VISIBLE}
+         * during the current update. Callers should follow-up with a separate
+         * update using {@link #FORCE_STARRED_UPDATE} to ensure that
+         * {@link Contacts#STARRED} remains consistent.
+         *
+         * @hide
+         */
+        public static final String DELAY_STARRED_UPDATE = "delay_update";
+
+        /**
+         * An optional query parameter added to {@link Groups#CONTENT_URI} or
+         * {@link Settings#CONTENT_URI} signaling that a full update of
+         * {@link Contacts#STARRED} should be triggered. This is usually only
+         * needed after using {@link #DELAY_STARRED_UPDATE}.
+         *
+         * @hide
+         */
+        public static final String FORCE_STARRED_UPDATE = "force_update";
+
+        /**
          * A sub-directory of a single contact that contains all of the constituent raw contact
          * {@link Data} rows.
          */
@@ -432,10 +481,11 @@
         }
 
         /**
-         * Opens an InputStream for the person's default photo and returns the
-         * photo as a Bitmap stream.
+         * Opens an InputStream for the contacts's default photo and returns the
+         * photo as a byte stream. If there is not photo null will be returned.
          *
          * @param contactUri the contact whose photo should be used
+         * @return an InputStream of the photo, or null if no photo is present
          */
         public static InputStream openContactPhotoInputStream(ContentResolver cr, Uri contactUri) {
             Uri photoUri = Uri.withAppendedPath(contactUri, Photo.CONTENT_DIRECTORY);
@@ -470,7 +520,7 @@
         public static final String CONTACT_ID = "contact_id";
 
         /**
-         * Flag indicating that this {@link RawContacts} entry and its children has
+         * Flag indicating that this {@link RawContacts} entry and its children have
          * been restricted to specific platform apps.
          * <P>Type: INTEGER (boolean)</P>
          *
@@ -498,7 +548,7 @@
     }
 
     /**
-     * Constants for the raw_contacts table, which contains the base contact
+     * Constants for the raw contacts table, which contains the base contact
      * information per sync source. Sync adapters and contact management apps
      * are the primary consumers of this API.
      */
@@ -600,6 +650,8 @@
          * The package name to use when creating {@link Resources} objects for
          * this data row. This value is only designed for use when building user
          * interfaces, and should not be used to infer the owner.
+         *
+         * @hide
          */
         public static final String RES_PACKAGE = "res_package";
 
@@ -790,12 +842,6 @@
     private interface PresenceColumns {
 
         /**
-         * The unique ID for a row.
-         * <P>Type: INTEGER (long)</P>
-         */
-        public static final String _ID = "presence_id";
-
-        /**
          * Reference to the {@link Data#_ID} entry that owns this presence.
          * <P>Type: INTEGER</P>
          */
@@ -834,8 +880,7 @@
         /**
          * This utility class cannot be instantiated
          */
-        private Presence() {
-        }
+        private Presence() {}
 
         /**
          * The content:// style URI for this table
@@ -843,6 +888,12 @@
         public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "presence");
 
         /**
+         * The unique ID for a presence row.
+         * <P>Type: INTEGER (long)</P>
+         */
+        public static final String _ID = "presence_id";
+
+        /**
          * Gets the resource ID for the proper presence icon.
          *
          * @param status the status to get the icon for
@@ -895,8 +946,15 @@
      */
     public static final class CommonDataKinds {
         /**
+         * This utility class cannot be instantiated
+         */
+        private CommonDataKinds() {}
+
+        /**
          * The {@link Data#RES_PACKAGE} value for common data that should be
          * shown using a default style.
+         *
+         * @hide RES_PACKAGE is hidden
          */
         public static final String PACKAGE_COMMON = "common";
 
@@ -937,6 +995,9 @@
          * Parts of the name.
          */
         public static final class StructuredName implements DataColumnsWithJoins {
+            /**
+             * This utility class cannot be instantiated
+             */
             private StructuredName() {}
 
             /** MIME type used when storing this in data table. */
@@ -1003,6 +1064,9 @@
          * A nickname.
          */
         public static final class Nickname implements DataColumnsWithJoins, CommonColumns {
+            /**
+             * This utility class cannot be instantiated
+             */
             private Nickname() {}
 
             /** MIME type used when storing this in data table. */
@@ -1024,6 +1088,9 @@
          * Common data definition for telephone numbers.
          */
         public static final class Phone implements DataColumnsWithJoins, CommonColumns {
+            /**
+             * This utility class cannot be instantiated
+             */
             private Phone() {}
 
             /** MIME type used when storing this in data table. */
@@ -1081,6 +1148,7 @@
 
             /**
              * @deprecated use {@link #getTypeLabel(Resources, int, CharSequence)} instead.
+             * @hide
              */
             @Deprecated
             public static final CharSequence getDisplayLabel(Context context, int type,
@@ -1090,6 +1158,7 @@
 
             /**
              * @deprecated use {@link #getTypeLabel(Resources, int, CharSequence)} instead.
+             * @hide
              */
             @Deprecated
             public static final CharSequence getDisplayLabel(Context context, int type,
@@ -1147,6 +1216,9 @@
          * Common data definition for email addresses.
          */
         public static final class Email implements DataColumnsWithJoins, CommonColumns {
+            /**
+             * This utility class cannot be instantiated
+             */
             private Email() {}
 
             /** MIME type used when storing this in data table. */
@@ -1227,6 +1299,9 @@
          * Common data definition for postal addresses.
          */
         public static final class StructuredPostal implements DataColumnsWithJoins, CommonColumns {
+            /**
+             * This utility class cannot be instantiated
+             */
             private StructuredPostal() {
             }
 
@@ -1349,6 +1424,9 @@
          * Common data definition for IM addresses.
          */
         public static final class Im implements DataColumnsWithJoins, CommonColumns {
+            /**
+             * This utility class cannot be instantiated
+             */
             private Im() {}
 
             /** MIME type used when storing this in data table. */
@@ -1449,6 +1527,9 @@
          * Common data definition for organizations.
          */
         public static final class Organization implements DataColumnsWithJoins, CommonColumns {
+            /**
+             * This utility class cannot be instantiated
+             */
             private Organization() {}
 
             /** MIME type used when storing this in data table. */
@@ -1525,6 +1606,9 @@
          * Common data definition for miscellaneous information.
          */
         public static final class Miscellaneous implements DataColumnsWithJoins {
+            /**
+             * This utility class cannot be instantiated
+             */
             private Miscellaneous() {}
 
             /** MIME type used when storing this in data table. */
@@ -1539,6 +1623,7 @@
             /**
              * The nickname as the user entered it.
              * <P>Type: TEXT</P>
+             *@hide
              */
             public static final String NICKNAME = DATA2;
         }
@@ -1547,6 +1632,9 @@
          * Common data definition for relations.
          */
         public static final class Relation implements DataColumnsWithJoins, CommonColumns {
+            /**
+             * This utility class cannot be instantiated
+             */
             private Relation() {}
 
             /** MIME type used when storing this in data table. */
@@ -1578,6 +1666,9 @@
          * Common data definition for events.
          */
         public static final class Event implements DataColumnsWithJoins, CommonColumns {
+            /**
+             * This utility class cannot be instantiated
+             */
             private Event() {}
 
             /** MIME type used when storing this in data table. */
@@ -1597,6 +1688,9 @@
          * Photo of the contact.
          */
         public static final class Photo implements DataColumnsWithJoins {
+            /**
+             * This utility class cannot be instantiated
+             */
             private Photo() {}
 
             /** MIME type used when storing this in data table. */
@@ -1615,6 +1709,9 @@
          * Notes about the contact.
          */
         public static final class Note implements DataColumnsWithJoins {
+            /**
+             * This utility class cannot be instantiated
+             */
             private Note() {}
 
             /** MIME type used when storing this in data table. */
@@ -1631,6 +1728,9 @@
          * Group Membership.
          */
         public static final class GroupMembership implements DataColumnsWithJoins {
+            /**
+             * This utility class cannot be instantiated
+             */
             private GroupMembership() {}
 
             /** MIME type used when storing this in data table. */
@@ -1656,6 +1756,9 @@
          * Website related to the contact.
          */
         public static final class Website implements DataColumnsWithJoins, CommonColumns {
+            /**
+             * This utility class cannot be instantiated
+             */
             private Website() {}
 
             /** MIME type used when storing this in data table. */
@@ -1677,8 +1780,7 @@
         }
     }
 
-    // TODO: make this private before unhiding
-    public interface GroupsColumns {
+    private interface GroupsColumns {
         /**
          * The display title of this group.
          * <p>
@@ -1690,6 +1792,8 @@
          * The package name to use when creating {@link Resources} objects for
          * this group. This value is only designed for use when building user
          * interfaces, and should not be used to infer the owner.
+         *
+         * @hide
          */
         public static final String RES_PACKAGE = "res_package";
 
@@ -1697,6 +1801,8 @@
          * The display title of this group to load as a resource from
          * {@link #RES_PACKAGE}, which may be localized.
          * <P>Type: TEXT</P>
+         *
+         * @hide
          */
         public static final String TITLE_RES = "title_res";
 
@@ -1946,6 +2052,8 @@
     /**
      * Helper methods to display FastTrack dialogs that allow users to pivot on
      * a specific {@link Contacts} entry.
+     *
+     * @hide
      */
     public static final class FastTrack {
         /**
@@ -2149,6 +2257,8 @@
          * Optional extra used with {@link #SHOW_OR_CREATE_CONTACT} to specify a
          * dialog location using screen coordinates. When not specified, the
          * dialog will be centered.
+         *
+         * @hide
          */
         @Deprecated
         public static final String EXTRA_TARGET_RECT = "target_rect";
@@ -2157,24 +2267,32 @@
          * Optional extra used with {@link #SHOW_OR_CREATE_CONTACT} to specify a
          * desired dialog style, usually a variation on size. One of
          * {@link #MODE_SMALL}, {@link #MODE_MEDIUM}, or {@link #MODE_LARGE}.
+         *
+         * @hide
          */
         @Deprecated
         public static final String EXTRA_MODE = "mode";
 
         /**
          * Value for {@link #EXTRA_MODE} to show a small-sized dialog.
+         *
+         * @hide
          */
         @Deprecated
         public static final int MODE_SMALL = 1;
 
         /**
          * Value for {@link #EXTRA_MODE} to show a medium-sized dialog.
+         *
+         * @hide
          */
         @Deprecated
         public static final int MODE_MEDIUM = 2;
 
         /**
          * Value for {@link #EXTRA_MODE} to show a large-sized dialog.
+         *
+         * @hide
          */
         @Deprecated
         public static final int MODE_LARGE = 3;
@@ -2183,12 +2301,16 @@
          * Optional extra used with {@link #SHOW_OR_CREATE_CONTACT} to indicate
          * a list of specific MIME-types to exclude and not display. Stored as a
          * {@link String} array.
+         *
+         * @hide
          */
         @Deprecated
         public static final String EXTRA_EXCLUDE_MIMES = "exclude_mimes";
 
         /**
          * Intents related to the Contacts app UI.
+         *
+         * @hide
          */
         public static final class UI {
             /**
@@ -2245,7 +2367,7 @@
              * title to a custom String value.
              */
             public static final String TITLE_EXTRA_KEY =
-                "com.android.contacts.extra.TITLE_EXTRA";
+                    "com.android.contacts.extra.TITLE_EXTRA";
 
             /**
              * Activity Action: Display a filtered list of contacts
@@ -2256,14 +2378,14 @@
              * Output: Nothing.
              */
             public static final String FILTER_CONTACTS_ACTION =
-                "com.android.contacts.action.FILTER_CONTACTS";
+                    "com.android.contacts.action.FILTER_CONTACTS";
 
             /**
              * Used as an int extra field in {@link #FILTER_CONTACTS_ACTION}
              * intents to supply the text on which to filter.
              */
             public static final String FILTER_TEXT_EXTRA_KEY =
-                "com.android.contacts.extra.FILTER_TEXT";
+                    "com.android.contacts.extra.FILTER_TEXT";
         }
 
         /**
@@ -2435,8 +2557,6 @@
 
             /**
              * The extra field for the IM protocol
-             * <P>Type: the result of {@link CommonDataKinds.Im#encodePredefinedImProtocol(int)}
-             * or {@link CommonDataKinds.Im#encodeCustomImProtocol(String)}.</P>
              */
             public static final String IM_PROTOCOL = "im_protocol";
 
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index b7953af..7977578 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -57,6 +57,8 @@
      */
     void windowFocusChanged(boolean hasFocus, boolean inTouchMode);
     
+    void closeSystemDialogs(String reason);
+    
     /**
      * Called for wallpaper windows when their offsets change.
      */
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 3e6cdc2..7d1872a 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -90,6 +90,8 @@
     void exitKeyguardSecurely(IOnKeyguardExitResult callback);
     boolean inKeyguardRestrictedInputMode();
 
+    void closeSystemDialogs(String reason);
+    
     // These can only be called with the SET_ANIMATON_SCALE permission.
     float getAnimationScale(int which);
     float[] getAnimationScales();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6ff0fc8..642f0fa 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8099,6 +8099,13 @@
     }
 
     /**
+     * This needs to be a better API (NOT ON VIEW) before it is exposed.  If
+     * it is ever exposed at all.
+     */
+    public void onCloseSystemDialogs(String reason) {
+    }
+    
+    /**
      * Given a Drawable whose bounds have been set to draw into this view,
      * update a Region being computed for {@link #gatherTransparentRegion} so
      * that any non-transparent parts of the Drawable are removed from the
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index c6937a3..398abf8 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -1610,6 +1610,7 @@
     public final static int DISPATCH_KEY_FROM_IME = 1011;
     public final static int FINISH_INPUT_CONNECTION = 1012;
     public final static int CHECK_FOCUS = 1013;
+    public final static int CLOSE_SYSTEM_DIALOGS = 1014;
 
     @Override
     public void handleMessage(Message msg) {
@@ -1867,6 +1868,11 @@
                 imm.checkFocus();
             }
         } break;
+        case CLOSE_SYSTEM_DIALOGS: {
+            if (mView != null) {
+                mView.onCloseSystemDialogs((String)msg.obj);
+            }
+        } break;
         }
     }
 
@@ -2630,6 +2636,13 @@
         sendMessage(msg);
     }
 
+    public void dispatchCloseSystemDialogs(String reason) {
+        Message msg = Message.obtain();
+        msg.what = CLOSE_SYSTEM_DIALOGS;
+        msg.obj = reason;
+        sendMessage(msg);
+    }
+    
     /**
      * The window is getting focus so if there is anything focused/selected
      * send an {@link AccessibilityEvent} to announce that.
@@ -2869,6 +2882,13 @@
             }
         }
         
+        public void closeSystemDialogs(String reason) {
+            final ViewRoot viewRoot = mViewRoot.get();
+            if (viewRoot != null) {
+                viewRoot.dispatchCloseSystemDialogs(reason);
+            }
+        }
+        
         public void dispatchWallpaperOffsets(float x, float y, boolean sync) {
             if (sync) {
                 try {
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index 2f5e601..c8396c4 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -175,6 +175,11 @@
      */
     private int mZAdjustment;
     
+    /**
+     * Don't animate the wallpaper.
+     */
+    private boolean mDetachWallpaper = false;
+
     private boolean mMore = true;
     private boolean mOneMoreTime = true;
 
@@ -218,6 +223,8 @@
 
         setZAdjustment(a.getInt(com.android.internal.R.styleable.Animation_zAdjustment, ZORDER_NORMAL));
         
+        setDetachWallpaper(a.getBoolean(com.android.internal.R.styleable.Animation_detachWallpaper, false));
+        
         ensureInterpolator();
 
         a.recycle();
@@ -515,6 +522,19 @@
     }
     
     /**
+     * If detachWallpaper is true, and this is a window animation of a window
+     * that has a wallpaper background, then the window will be detached from
+     * the wallpaper while it runs.  That is, the animation will only be applied
+     * to the window, and the wallpaper behind it will remain static.
+     *
+     * @param detachWallpaper true if the wallpaper should be detached from the animation
+     * @attr ref android.R.styleable#Animation_detachWallpaper
+     */
+    public void setDetachWallpaper(boolean detachWallpaper) {
+        mDetachWallpaper = detachWallpaper;
+    }
+
+    /**
      * Gets the acceleration curve type for this animation.
      *
      * @return the {@link Interpolator} associated to this animation
@@ -611,6 +631,14 @@
     }
 
     /**
+     * Return value of {@link #setDetachWallpaper(boolean)}.
+     * @attr ref android.R.styleable#Animation_detachWallpaper
+     */
+    public boolean getDetachWallpaper() {
+        return mDetachWallpaper;
+    }
+
+    /**
      * <p>Indicates whether or not this animation will affect the transformation
      * matrix. For instance, a fade animation will not affect the matrix whereas
      * a scale animation will.</p>
diff --git a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java
index 0bc70de..6d29038 100644
--- a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java
+++ b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java
@@ -19,6 +19,7 @@
 import android.app.WallpaperManager;
 import android.graphics.Canvas;
 import android.graphics.Rect;
+import android.graphics.Region.Op;
 import android.graphics.drawable.Drawable;
 import android.os.HandlerThread;
 import android.os.Process;
@@ -134,14 +135,18 @@
                     final int dh = frame.height();
                     final int bw = mBackground.getIntrinsicWidth();
                     final int bh = mBackground.getIntrinsicHeight();
-                    final int availw = bw-dw;
-                    final int availh = bh-dh;
-                    int xPixels = availw > 0
-                            ? -(int)(availw*mXOffset+.5f) : -(availw/2);
-                    int yPixels = availh > 0
-                            ? -(int)(availh*mYOffset+.5f) : -(availh/2);
+                    final int availw = dw-bw;
+                    final int availh = dh-bh;
+                    int xPixels = availw < 0 ? (int)(availw*mXOffset+.5f) : (availw/2);
+                    int yPixels = availh < 0 ? (int)(availh*mYOffset+.5f) : (availh/2);
+
                     c.translate(xPixels, yPixels);
-                    c.drawColor(0xff000000);
+                    if (availw<0 || availh<0) {
+                        c.save(Canvas.CLIP_SAVE_FLAG);
+                        c.clipRect(0, 0, bw, bh, Op.DIFFERENCE);
+                        c.drawColor(0xff000000);
+                        c.restore();
+                    }
                     background.draw(c);
                 }
                 sh.unlockCanvasAndPost(c);
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index b8d19ac..38ef0c2 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -90,6 +90,9 @@
     public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
     }
     
+    public void closeSystemDialogs(String reason) {
+    }
+    
     public void dispatchWallpaperOffsets(float x, float y, boolean sync) {
         if (sync) {
             try {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c4536be..3242ed2 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1134,6 +1134,7 @@
                  android:icon="@drawable/ic_launcher_android">
         <activity android:name="com.android.internal.app.ChooserActivity"
                 android:theme="@style/Theme.Dialog.Alert"
+                android:finishOnCloseSystemDialogs="true"
                 android:excludeFromRecents="true"
                 android:multiprocess="true">
             <intent-filter>
diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml
index 303cfd6..c42ad83 100644
--- a/core/res/res/anim/task_close_enter.xml
+++ b/core/res/res/anim/task_close_enter.xml
@@ -18,9 +18,14 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:interpolator="@anim/decelerate_interpolator">
+        android:interpolator="@anim/decelerate_interpolator"
+        android:zAdjustment="top">
+    <!-- For now stay like the normal activity transition.
     <scale android:fromXScale="2.0" android:toXScale="1.0"
            android:fromYScale="2.0" android:toYScale="1.0"
-           android:pivotX="50%p" android:pivotY="50%p"
-           android:duration="@android:integer/config_mediumAnimTime" />
+           android:pivotX="100%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_shortAnimTime" />
+    -->
+    <translate android:fromXDelta="-100%" android:toXDelta="0"
+        android:duration="@android:integer/config_shortAnimTime"/>
 </set>
diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml
index a28ac3b..66d3480 100644
--- a/core/res/res/anim/task_close_exit.xml
+++ b/core/res/res/anim/task_close_exit.xml
@@ -18,12 +18,7 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:interpolator="@anim/decelerate_interpolator"
-        android:zAdjustment="top">
-    <scale android:fromXScale="1.0" android:toXScale=".5"
-           android:fromYScale="1.0" android:toYScale=".5"
-           android:pivotX="50%p" android:pivotY="50%p"
-           android:duration="@android:integer/config_mediumAnimTime" />
-    <alpha android:fromAlpha="1.0" android:toAlpha="0"
-            android:duration="@android:integer/config_mediumAnimTime"/>
+        android:interpolator="@anim/decelerate_interpolator">
+    <translate android:fromXDelta="0%" android:toXDelta="33%"
+        android:duration="@android:integer/config_shortAnimTime"/>
 </set>
diff --git a/core/res/res/anim/task_open_enter.xml b/core/res/res/anim/task_open_enter.xml
index 234abb2..66adf9f 100644
--- a/core/res/res/anim/task_open_enter.xml
+++ b/core/res/res/anim/task_open_enter.xml
@@ -18,12 +18,7 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:interpolator="@anim/decelerate_interpolator"
-        android:zAdjustment="top">
-    <scale android:fromXScale=".5" android:toXScale="1.0"
-           android:fromYScale=".5" android:toYScale="1.0"
-           android:pivotX="50%p" android:pivotY="50%p"
-           android:duration="@android:integer/config_mediumAnimTime" />
-    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
-            android:duration="@android:integer/config_mediumAnimTime"/>
+        android:interpolator="@anim/decelerate_interpolator">
+    <translate android:fromXDelta="33%" android:toXDelta="0"
+        android:duration="@android:integer/config_shortAnimTime"/>
 </set>
diff --git a/core/res/res/anim/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml
index db331b1..4a2cef4 100644
--- a/core/res/res/anim/task_open_exit.xml
+++ b/core/res/res/anim/task_open_exit.xml
@@ -18,9 +18,14 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:interpolator="@anim/decelerate_interpolator">
+        android:interpolator="@anim/decelerate_interpolator"
+        android:zAdjustment="top">
+    <!-- For now stay like the normal activity transition.
     <scale android:fromXScale="1.0" android:toXScale="2.0"
            android:fromYScale="1.0" android:toYScale="2.0"
-           android:pivotX="50%p" android:pivotY="50%p"
-           android:duration="@android:integer/config_mediumAnimTime" />
+           android:pivotX="100%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_shortAnimTime" />
+    -->
+    <translate android:fromXDelta="0%" android:toXDelta="-100%"
+        android:duration="@android:integer/config_shortAnimTime"/>
 </set>
diff --git a/core/res/res/anim/wallpaper_close_enter.xml b/core/res/res/anim/wallpaper_close_enter.xml
index 0d13009..5bc299e 100644
--- a/core/res/res/anim/wallpaper_close_enter.xml
+++ b/core/res/res/anim/wallpaper_close_enter.xml
@@ -18,7 +18,21 @@
 -->
 
 <!-- This version zooms the new non-wallpaper down on top of the
+     wallpaper, without zooming the wallpaper itself. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator"
+        android:zAdjustment="top">
+    <scale android:fromXScale="2.0" android:toXScale="1.0"
+           android:fromYScale="2.0" android:toYScale="1.0"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+    <alpha android:fromAlpha="0" android:toAlpha="1.0"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
+
+<!-- This version zooms the new non-wallpaper down on top of the
      wallpaper. -->
+<!-- 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator">
     <scale android:fromXScale="2.0" android:toXScale="1.0"
@@ -26,6 +40,7 @@
            android:pivotX="50%p" android:pivotY="50%p"
            android:duration="@android:integer/config_mediumAnimTime" />
 </set>
+-->
 
 <!-- This version is a variation on the inter-activity slide that
     also scales the wallpaper. -->
diff --git a/core/res/res/anim/wallpaper_close_exit.xml b/core/res/res/anim/wallpaper_close_exit.xml
index 5d91e30..c3ae620 100644
--- a/core/res/res/anim/wallpaper_close_exit.xml
+++ b/core/res/res/anim/wallpaper_close_exit.xml
@@ -18,7 +18,19 @@
 -->
 
 <!-- This version zooms the new non-wallpaper down on top of the
+     wallpaper, without zooming the wallpaper itself. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator"
+        android:detachWallpaper="true">
+    <scale android:fromXScale="1.0" android:toXScale=".5"
+           android:fromYScale="1.0" android:toYScale=".5"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+</set>
+
+<!-- This version zooms the new non-wallpaper down on top of the
      wallpaper.  The wallpaper here just stays fixed behind. -->
+<!--
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator"
         android:zAdjustment="top">
@@ -29,6 +41,7 @@
     <alpha android:fromAlpha="1.0" android:toAlpha="0"
             android:duration="@android:integer/config_mediumAnimTime"/>
 </set>
+-->
 
 <!-- This version is a variation on the inter-activity slide that
     also scales the wallpaper. -->
diff --git a/core/res/res/anim/wallpaper_open_enter.xml b/core/res/res/anim/wallpaper_open_enter.xml
index cf27cf0..7fe7e1e 100644
--- a/core/res/res/anim/wallpaper_open_enter.xml
+++ b/core/res/res/anim/wallpaper_open_enter.xml
@@ -17,8 +17,20 @@
 */
 -->
 
+<!-- This version zooms the new non-wallpaper down on top of the
+     wallpaper, without zooming the wallpaper itself. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator"
+        android:detachWallpaper="true">
+    <scale android:fromXScale=".5" android:toXScale="1.0"
+           android:fromYScale=".5" android:toYScale="1.0"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+</set>
+
 <!-- This version zooms the new non-wallpaper up off the wallpaper the
      wallpaper.  The wallpaper here just stays fixed behind. -->
+<!--
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator"
         android:zAdjustment="top">
@@ -29,6 +41,7 @@
     <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
             android:duration="@android:integer/config_mediumAnimTime"/>
 </set>
+-->
 
 <!-- This version is a variation on the inter-activity slide that
     also scales the wallpaper. -->
diff --git a/core/res/res/anim/wallpaper_open_exit.xml b/core/res/res/anim/wallpaper_open_exit.xml
index b7a539c..9489c6d 100644
--- a/core/res/res/anim/wallpaper_open_exit.xml
+++ b/core/res/res/anim/wallpaper_open_exit.xml
@@ -18,7 +18,21 @@
 -->
 
 <!-- This version zooms the new non-wallpaper down on top of the
+     wallpaper, without zooming the wallpaper itself. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator"
+        android:zAdjustment="top">
+    <scale android:fromXScale="1.0" android:toXScale="2.0"
+           android:fromYScale="1.0" android:toYScale="2.0"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+    <alpha android:fromAlpha="1.0" android:toAlpha="0"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
+
+<!-- This version zooms the new non-wallpaper down on top of the
      wallpaper. -->
+<!--
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator">
     <scale android:fromXScale="1.0" android:toXScale="2.0"
@@ -26,6 +40,7 @@
            android:pivotX="50%p" android:pivotY="50%p"
            android:duration="@android:integer/config_mediumAnimTime" />
 </set>
+-->
 
 <!-- This version is a variation on the inter-activity slide that
     also scales the wallpaper. -->
diff --git a/core/res/res/drawable-hdpi/btn_zoom_up_disabled.9.png b/core/res/res/drawable-hdpi/btn_zoom_up_disabled.9.png
index 9813201..6a55903 100644
--- a/core/res/res/drawable-hdpi/btn_zoom_up_disabled.9.png
+++ b/core/res/res/drawable-hdpi/btn_zoom_up_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_zoom_up_disabled_focused.9.png b/core/res/res/drawable-hdpi/btn_zoom_up_disabled_focused.9.png
index 8710c72..7adbae1 100644
--- a/core/res/res/drawable-hdpi/btn_zoom_up_disabled_focused.9.png
+++ b/core/res/res/drawable-hdpi/btn_zoom_up_disabled_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_zoom_up_normal.9.png b/core/res/res/drawable-hdpi/btn_zoom_up_normal.9.png
index 763d271..4631a32 100644
--- a/core/res/res/drawable-hdpi/btn_zoom_up_normal.9.png
+++ b/core/res/res/drawable-hdpi/btn_zoom_up_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_zoom_up_pressed.9.png b/core/res/res/drawable-hdpi/btn_zoom_up_pressed.9.png
index b77936a..df75fec 100644
--- a/core/res/res/drawable-hdpi/btn_zoom_up_pressed.9.png
+++ b/core/res/res/drawable-hdpi/btn_zoom_up_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_zoom_up_selected.9.png b/core/res/res/drawable-hdpi/btn_zoom_up_selected.9.png
index a8e4af1..bae522c 100644
--- a/core/res/res/drawable-hdpi/btn_zoom_up_selected.9.png
+++ b/core/res/res/drawable-hdpi/btn_zoom_up_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_default.9.png b/core/res/res/drawable-hdpi/textfield_default.9.png
index a2f022a..4c20179 100644
--- a/core/res/res/drawable-hdpi/textfield_default.9.png
+++ b/core/res/res/drawable-hdpi/textfield_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_disabled.9.png b/core/res/res/drawable-hdpi/textfield_disabled.9.png
index 6a28cb4..81569d1 100644
--- a/core/res/res/drawable-hdpi/textfield_disabled.9.png
+++ b/core/res/res/drawable-hdpi/textfield_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_disabled_selected.9.png b/core/res/res/drawable-hdpi/textfield_disabled_selected.9.png
index 0de9cda..2591490 100644
--- a/core/res/res/drawable-hdpi/textfield_disabled_selected.9.png
+++ b/core/res/res/drawable-hdpi/textfield_disabled_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_pressed.9.png b/core/res/res/drawable-hdpi/textfield_pressed.9.png
index d5892c8..a42d87f 100644
--- a/core/res/res/drawable-hdpi/textfield_pressed.9.png
+++ b/core/res/res/drawable-hdpi/textfield_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_selected.9.png b/core/res/res/drawable-hdpi/textfield_selected.9.png
index 7a072dd..a36ed72 100644
--- a/core/res/res/drawable-hdpi/textfield_selected.9.png
+++ b/core/res/res/drawable-hdpi/textfield_selected.9.png
Binary files differ
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 193fdb2..df2a715 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2639,6 +2639,9 @@
                  content for the duration of the animation. -->
             <enum name="bottom" value="-1" />
         </attr>
+        <!-- Special option for window animations: if this window is on top
+             of a wallpaper, don't animate the wallpaper with it. -->
+        <attr name="detachWallpaper" format="boolean" />
     </declare-styleable>
 
     <declare-styleable name="RotateAnimation">
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 365363a..85f5ce3 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -288,6 +288,12 @@
          ignored and the activity simply finished. -->
     <attr name="finishOnTaskLaunch" format="boolean" />
     
+    <!-- Specify whether an activity should be finished when a "close system
+         windows" request has been made.  This happens, for example, when
+         the home key is pressed, when the device is locked, when a system
+         dialog like recent apps is displayed, etc. -->
+    <attr name="finishOnCloseSystemDialogs" format="boolean" />
+    
     <!-- Specify whether an activity's task should be cleared when it
          is re-launched from the home screen.  As a result, every time the
          user starts the task, they will be brought to its root activity,
@@ -1078,6 +1084,7 @@
         <attr name="taskAffinity" />
         <attr name="allowTaskReparenting" />
         <attr name="finishOnTaskLaunch" />
+        <attr name="finishOnCloseSystemDialogs" />
         <attr name="clearTaskOnLaunch" />
         <attr name="noHistory" />
         <attr name="alwaysRetainTaskState" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a32f519..b508372 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -30,7 +30,7 @@
     <integer name="config_shortAnimTime">150</integer>
     
     <!-- The duration (in milliseconds) of a medium-length animation. -->
-    <integer name="config_mediumAnimTime">250</integer>
+    <integer name="config_mediumAnimTime">200</integer>
     
     <!-- The duration (in milliseconds) of a long animation. -->
     <integer name="config_longAnimTime">400</integer>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 4d23ef4..257e0f2 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1170,6 +1170,8 @@
   <public type="attr" name="detailColumn" />
   <public type="attr" name="detailSocialSummary" />
   <public type="attr" name="thumbnail" />
+  <public type="attr" name="detachWallpaper" />
+  <public type="attr" name="finishOnCloseSystemDialogs" />
 
   <public type="style" name="Theme.Wallpaper" />
   <public type="style" name="Theme.Wallpaper.NoTitleBar" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 6426080..47c68ad 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -58,19 +58,6 @@
         <item name="activityOpenExitAnimation">@anim/activity_open_exit</item>
         <item name="activityCloseEnterAnimation">@anim/activity_close_enter</item>
         <item name="activityCloseExitAnimation">@anim/activity_close_exit</item>
-        <item name="taskOpenEnterAnimation">@anim/activity_open_enter</item>
-        <item name="taskOpenExitAnimation">@anim/activity_open_exit</item>
-        <item name="taskCloseEnterAnimation">@anim/activity_close_enter</item>
-        <item name="taskCloseExitAnimation">@anim/activity_close_exit</item>
-        <item name="taskToFrontEnterAnimation">@anim/activity_open_enter</item>
-        <item name="taskToFrontExitAnimation">@anim/activity_open_exit</item>
-        <item name="taskToBackEnterAnimation">@anim/activity_close_enter</item>
-        <item name="taskToBackExitAnimation">@anim/activity_close_exit</item>
-        <!-- There is a good argument to be made that the user shouldn't
-             be aware of task transitions, so we are going to use the same
-             animation for them as we do for regular activity transitions. -->
-        <!-- These provide an alternative animation for task transitions. -->
-        <!--
         <item name="taskOpenEnterAnimation">@anim/task_open_enter</item>
         <item name="taskOpenExitAnimation">@anim/task_open_exit</item>
         <item name="taskCloseEnterAnimation">@anim/task_close_enter</item>
@@ -79,7 +66,6 @@
         <item name="taskToFrontExitAnimation">@anim/task_open_exit</item>
         <item name="taskToBackEnterAnimation">@anim/task_close_enter</item>
         <item name="taskToBackExitAnimation">@anim/task_close_exit</item>
-        -->
         <item name="wallpaperOpenEnterAnimation">@anim/wallpaper_open_enter</item>
         <item name="wallpaperOpenExitAnimation">@anim/wallpaper_open_exit</item>
         <item name="wallpaperCloseEnterAnimation">@anim/wallpaper_close_enter</item>
diff --git a/include/ui/SurfaceComposerClient.h b/include/ui/SurfaceComposerClient.h
index 269959c..8701928 100644
--- a/include/ui/SurfaceComposerClient.h
+++ b/include/ui/SurfaceComposerClient.h
@@ -20,6 +20,8 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <binder/IBinder.h>
+
 #include <utils/SortedVector.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
@@ -106,6 +108,8 @@
     static ssize_t getDisplayHeight(DisplayID dpy);
     static ssize_t getDisplayOrientation(DisplayID dpy);
 
+    status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
+            void* cookie = NULL, uint32_t flags = 0);
 
 private:
     friend class Surface;
diff --git a/keystore/java/android/security/CertTool.java b/keystore/java/android/security/CertTool.java
deleted file mode 100644
index 88d6e3d..0000000
--- a/keystore/java/android/security/CertTool.java
+++ /dev/null
@@ -1,357 +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 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;
-import java.security.cert.CertificateException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.util.ArrayList;
-
-/**
- * The CertTool class provides the functions to list the certs/keys,
- * generate the certificate request(csr) and store certificates into
- * keystore.
- *
- * {@hide}
- */
-public class CertTool {
-    static {
-        System.loadLibrary("certtool_jni");
-    }
-
-    /** Keystore namespace for CA certificates. */
-    public static final String CA_CERTIFICATE = "CACERT";
-
-    /** Keystore namespace for user certificates. */
-    public static final String USER_CERTIFICATE = "USRCERT";
-
-    /** 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";
-
-    /** 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";
-
-    /** 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:";
-    private static final String DISTINCT_NAME = "Distinct Name:";
-
-    private static final String KEYNAME_DELIMITER = "_";
-    private static final Keystore sKeystore = Keystore.getInstance();
-
-    private native int getPkcs12Handle(byte[] data, String password);
-    private native String getPkcs12Certificate(int handle);
-    private native String getPkcs12PrivateKey(int handle);
-    private native String popPkcs12CertificateStack(int handle);
-    private native void freePkcs12Handle(int handle);
-    private native String generateCertificateRequest(int bits, String challenge);
-    private native boolean isPkcs12Keystore(byte[] data);
-    private native int generateX509Certificate(byte[] data);
-    private native boolean isCaCertificate(int handle);
-    private native String getIssuerDN(int handle);
-    private native String getCertificateDN(int handle);
-    private native String getPrivateKeyPEM(int handle);
-    private native void freeX509Certificate(int handle);
-
-    private static CertTool sSingleton = null;
-
-    private CertTool() { }
-
-    public static final CertTool getInstance() {
-        if (sSingleton == null) {
-            sSingleton = new CertTool();
-        }
-        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);
-    }
-
-    public String[] getSupportedKeyStrenghs() {
-        return new String[] {"High Grade", "Medium Grade"};
-    }
-
-    private int getKeyLength(int index) {
-        if (index == 0) return 2048;
-        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 int extractAndStoreKeysFromPkcs12(int handle, String keyname) {
-        int ret, i = 0;
-        String pemData;
-
-        if ((pemData = getPkcs12Certificate(handle)) != null) {
-            if ((ret = sKeystore.put(USER_CERTIFICATE, keyname, pemData)) != 0) {
-                return ret;
-            }
-        }
-        if ((pemData = getPkcs12PrivateKey(handle)) != null) {
-            if ((ret = sKeystore.put(USER_KEY, keyname, pemData)) != 0) {
-                return ret;
-            }
-        }
-        if ((pemData = this.popPkcs12CertificateStack(handle)) != null) {
-            if ((ret = sKeystore.put(CA_CERTIFICATE, keyname, pemData)) != 0) {
-                return ret;
-            }
-        }
-        return 0;
-    }
-
-    /** Adds a PKCS12 keystore to the keystore. */
-    public int addPkcs12Keystore(byte[] p12Data, String password,
-            String keyname) {
-        int handle, ret;
-        Log.i("CertTool", "addPkcs12Keystore()");
-
-        if ((handle = getPkcs12Handle(p12Data, password)) == 0) {
-            return INCORRECT_PKCS12_PASSPHRASE;
-        }
-        ret = extractAndStoreKeysFromPkcs12(handle, keyname);
-        freePkcs12Handle(handle);
-        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, 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, issuer, distinctName)
-                        .addCredential(CA_CERTIFICATE, data).build();
-            } else {
-                AddCredentialIntentBuilder builder =
-                        prepareIntent(TITLE_USER_CERT, issuer, distinctName)
-                        .addCredential(USER_CERTIFICATE, data);
-                if (!TextUtils.isEmpty(privateKeyPEM)) {
-                    builder.addCredential(USER_KEY, privateKeyPEM.getBytes());
-                }
-                intent = builder.build();
-            }
-            freeX509Certificate(handle);
-        }
-        if (intent != null) {
-            context.startActivity(intent);
-        } else {
-            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 a47534b..0a2fe4c 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -172,8 +172,10 @@
             socket.shutdownOutput();
 
             InputStream in = socket.getInputStream();
-            code = in.read();
-            if (code == -1) {
+            if ((code = in.read()) != NO_ERROR) {
+                if (code != -1) {
+                    mError = code;
+                }
                 return null;
             }
 
@@ -194,7 +196,7 @@
                 }
                 results.add(result);
             }
-            mError = code;
+            mError = NO_ERROR;
             return results.toArray(new byte[results.size()][]);
         } catch (IOException e) {
             // ignore
diff --git a/keystore/java/android/security/Keystore.java b/keystore/java/android/security/Keystore.java
deleted file mode 100644
index b47ae12..0000000
--- a/keystore/java/android/security/Keystore.java
+++ /dev/null
@@ -1,133 +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 android.security;
-
-/**
- * The Keystore class provides the functions to list the certs/keys in keystore.
- * {@hide}
- */
-
-public abstract class Keystore {
-    /** 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;
-    public static final int UNINITIALIZED = 1;
-    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();
-    }
-
-    public abstract int lock();
-    public abstract int unlock(String password);
-    public abstract int getState();
-    public abstract int changePassword(String oldPassword, String newPassword);
-    public abstract int setPassword(String firstPassword);
-    public abstract String[] listKeys(String namespace);
-    public abstract int put(String namespace, String keyname, String value);
-    public abstract String get(String namespace, String keyname);
-    public abstract int remove(String namespace, String keyname);
-    public abstract int reset();
-
-    private static class FileKeystore extends Keystore {
-        private static final String SERVICE_NAME = "keystore";
-        private static final String CA_CERTIFICATE = "CaCertificate";
-        private static final String USER_CERTIFICATE = "UserCertificate";
-        private static final String USER_KEY = "UserPrivateKey";
-        private static final ServiceCommand mServiceCommand =
-                new ServiceCommand(SERVICE_NAME);
-
-        @Override
-        public int lock() {
-            Reply result = mServiceCommand.execute(ServiceCommand.LOCK);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public int unlock(String password) {
-            Reply result = mServiceCommand.execute(ServiceCommand.UNLOCK,
-                    password);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public int getState() {
-            Reply result = mServiceCommand.execute(ServiceCommand.GET_STATE);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public int changePassword(String oldPassword, String newPassword) {
-            Reply result = mServiceCommand.execute(ServiceCommand.PASSWD,
-                    oldPassword, newPassword);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public int setPassword(String firstPassword) {
-            Reply result = mServiceCommand.execute(ServiceCommand.PASSWD,
-                    firstPassword);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public String[] listKeys(String namespace) {
-            Reply result = mServiceCommand.execute(ServiceCommand.LIST_KEYS,
-                    namespace);
-            if ((result == null) || (result.returnCode != 0) ||
-                    (result.len == 0)) {
-                return NOTFOUND;
-            }
-            return new String(result.data, 0, result.len).split("\\s+");
-        }
-
-        @Override
-        public int put(String namespace, String keyname, String value) {
-            Reply result = mServiceCommand.execute(ServiceCommand.PUT_KEY,
-                    namespace, keyname, value);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public String get(String namespace, String keyname) {
-            Reply result = mServiceCommand.execute(ServiceCommand.GET_KEY,
-                    namespace, keyname);
-            return (result != null) ? ((result.returnCode != 0) ? null :
-                    new String(result.data, 0, result.len)) : null;
-        }
-
-        @Override
-        public int remove(String namespace, String keyname) {
-            Reply result = mServiceCommand.execute(ServiceCommand.REMOVE_KEY,
-                    namespace, keyname);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public int reset() {
-            Reply result = mServiceCommand.execute(ServiceCommand.RESET);
-            return (result != null) ? result.returnCode : -1;
-        }
-    }
-}
diff --git a/keystore/java/android/security/Reply.java b/keystore/java/android/security/Reply.java
deleted file mode 100644
index 15a0dde..0000000
--- a/keystore/java/android/security/Reply.java
+++ /dev/null
@@ -1,26 +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 android.security;
-
-/*
- * {@hide}
- */
-public class Reply {
-    public int len;
-    public int returnCode;
-    public byte[] data = new byte[ServiceCommand.BUFFER_LENGTH];
-}
diff --git a/keystore/java/android/security/ServiceCommand.java b/keystore/java/android/security/ServiceCommand.java
deleted file mode 100644
index 9923011..0000000
--- a/keystore/java/android/security/ServiceCommand.java
+++ /dev/null
@@ -1,203 +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 android.security;
-
-import android.net.LocalSocketAddress;
-import android.net.LocalSocket;
-import android.util.Config;
-import android.util.Log;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-
-/*
- * ServiceCommand is used to connect to a service throught the local socket,
- * and send out the command, return the result to the caller.
- * {@hide}
- */
-public class ServiceCommand {
-    public static final String SUCCESS = "0";
-    public static final String FAILED = "-1";
-
-    // Opcodes for keystore commands.
-    public static final int LOCK = 0;
-    public static final int UNLOCK = 1;
-    public static final int PASSWD = 2;
-    public static final int GET_STATE = 3;
-    public static final int LIST_KEYS = 4;
-    public static final int GET_KEY = 5;
-    public static final int PUT_KEY = 6;
-    public static final int REMOVE_KEY = 7;
-    public static final int RESET = 8;
-    public static final int MAX_CMD_INDEX = 9;
-
-    public static final int BUFFER_LENGTH = 4096;
-
-    private String mServiceName;
-    private String mTag;
-    private InputStream mIn;
-    private OutputStream mOut;
-    private LocalSocket mSocket;
-
-    private boolean connect() {
-        if (mSocket != null) {
-            return true;
-        }
-        try {
-            mSocket = new LocalSocket();
-
-            LocalSocketAddress address = new LocalSocketAddress(
-                    mServiceName, LocalSocketAddress.Namespace.RESERVED);
-
-            mSocket.connect(address);
-
-            mIn = mSocket.getInputStream();
-            mOut = mSocket.getOutputStream();
-        } catch (IOException ex) {
-            disconnect();
-            return false;
-        }
-        return true;
-    }
-
-    private void disconnect() {
-        try {
-            if (mSocket != null) mSocket.close();
-        } catch (IOException ex) { }
-        try {
-            if (mIn != null) mIn.close();
-        } catch (IOException ex) { }
-        try {
-            if (mOut != null) mOut.close();
-        } catch (IOException ex) { }
-        mSocket = null;
-        mIn = null;
-        mOut = null;
-    }
-
-    private boolean readBytes(byte buffer[], int len) {
-        int off = 0, count;
-        if (len < 0) return false;
-        while (off != len) {
-            try {
-                count = mIn.read(buffer, off, len - off);
-                if (count <= 0) {
-                    Log.e(mTag, "read error " + count);
-                    break;
-                }
-                off += count;
-            } catch (IOException ex) {
-                Log.e(mTag,"read exception", ex);
-                break;
-            }
-        }
-        if (off == len) return true;
-        disconnect();
-        return false;
-    }
-
-    private Reply readReply() {
-        byte buf[] = new byte[4];
-        Reply reply = new Reply();
-
-        if (!readBytes(buf, 4)) return null;
-        reply.len = ((((int) buf[0]) & 0xff) << 24) |
-                ((((int) buf[1]) & 0xff) << 16) |
-                ((((int) buf[2]) & 0xff) << 8) |
-                (((int) buf[3]) & 0xff);
-
-        if (!readBytes(buf, 4)) return null;
-        reply.returnCode = ((((int) buf[0]) & 0xff) << 24) |
-                ((((int) buf[1]) & 0xff) << 16) |
-                ((((int) buf[2]) & 0xff) << 8) |
-                (((int) buf[3]) & 0xff);
-
-        if (reply.len > BUFFER_LENGTH) {
-            Log.e(mTag,"invalid reply length (" + reply.len + ")");
-            disconnect();
-            return null;
-        }
-        if (!readBytes(reply.data, reply.len)) return null;
-        return reply;
-    }
-
-    private byte[] convert(String... data) {
-        StringBuilder sb = new StringBuilder();
-        if (data.length >=1) sb.append(data[0]).append("\0");
-        if (data.length >=2) sb.append(data[1]).append("\0");
-        if (data.length >=3) sb.append(data[2]);
-        return sb.toString().getBytes();
-    }
-
-    private boolean writeCommand(int cmd, String... data) {
-        byte buf[] = new byte[8];
-        byte[] dataBytes = convert(data);
-        int len = dataBytes.length;
-        // the length of data
-        buf[0] = (byte) ((len >> 24) & 0xff);
-        buf[1] = (byte) ((len >> 16) & 0xff);
-        buf[2] = (byte) ((len >> 8) & 0xff);
-        buf[3] = (byte) (len & 0xff);
-        // the opcode of the command
-        buf[4] = (byte) ((cmd >> 24) & 0xff);
-        buf[5] = (byte) ((cmd >> 16) & 0xff);
-        buf[6] = (byte) ((cmd >> 8) & 0xff);
-        buf[7] = (byte) (cmd & 0xff);
-        try {
-            mOut.write(buf, 0, 8);
-            mOut.write(dataBytes, 0, len);
-        } catch (IOException ex) {
-            Log.e(mTag,"write error", ex);
-            disconnect();
-            return false;
-        }
-        return true;
-    }
-
-    private Reply executeCommand(int cmd, String... data) {
-        if (!writeCommand(cmd, data)) {
-            /* If service died and restarted in the background
-             * (unlikely but possible) we'll fail on the next
-             * write (this one).  Try to reconnect and write
-             * the command one more time before giving up.
-             */
-            Log.e(mTag, "write command failed? reconnect!");
-            if (!connect() || !writeCommand(cmd, data)) {
-                return null;
-            }
-        }
-        return readReply();
-    }
-
-    public synchronized Reply execute(int cmd, String... data) {
-      Reply result;
-      if (!connect()) {
-          Log.e(mTag, "connection failed");
-          return null;
-      }
-      result = executeCommand(cmd, data);
-      disconnect();
-      return result;
-    }
-
-    public ServiceCommand(String service) {
-        mServiceName = service;
-        mTag = service;
-    }
-}
diff --git a/keystore/jni/Android.mk b/keystore/jni/Android.mk
deleted file mode 100644
index 92c2d6d..0000000
--- a/keystore/jni/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    cert.c certtool.c
-
-LOCAL_C_INCLUDES += \
-  $(JNI_H_INCLUDE) \
-  external/openssl/include
-
-LOCAL_SHARED_LIBRARIES := \
-  libcutils \
-  libnativehelper \
-  libutils \
-  libcrypto
-
-ifeq ($(TARGET_SIMULATOR),true)
-ifeq ($(TARGET_OS),linux)
-ifeq ($(TARGET_ARCH),x86)
-LOCAL_LDLIBS += -lpthread -ldl -lrt -lssl
-endif
-endif
-endif
-
-ifeq ($(WITH_MALLOC_LEAK_CHECK),true)
-  LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK
-endif
-
-LOCAL_MODULE:= libcerttool_jni
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/keystore/jni/cert.c b/keystore/jni/cert.c
deleted file mode 100644
index 90f872e..0000000
--- a/keystore/jni/cert.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
-**
-** Copyright 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_TAG "CertTool"
-
-#include <stdio.h>
-#include <openssl/pem.h>
-#include <openssl/pkcs12.h>
-#include <openssl/rsa.h>
-#include <openssl/x509v3.h>
-#include <cutils/log.h>
-
-#include "cert.h"
-
-static PKEY_STORE pkey_store[KEYGEN_STORE_SIZE];
-static int store_index = 0;
-
-static char emsg[][30] = {
-    "",
-    STR(ERR_INVALID_KEY_LENGTH),
-    STR(ERR_CONSTRUCT_NEW_DATA),
-    STR(ERR_RSA_KEYGEN),
-    STR(ERR_X509_PROCESS),
-    STR(ERR_SPKAC_TOO_LONG),
-    STR(ERR_INVALID_ARGS),
-};
-
-static void save_in_store(EVP_PKEY *pkey)
-{
-    EVP_PKEY *newpkey = EVP_PKEY_new();
-    RSA *rsa = EVP_PKEY_get1_RSA(pkey);
-    EVP_PKEY_set1_RSA(newpkey, rsa);
-    PKEY_STORE_free(pkey_store[store_index]);
-    pkey_store[store_index].key_len = i2d_RSA_PUBKEY(rsa, &pkey_store[store_index].public_key);
-    pkey_store[store_index++].pkey = newpkey;
-    store_index %= KEYGEN_STORE_SIZE;
-    RSA_free(rsa);
-}
-
-static EVP_PKEY *get_pkey_from_store(X509 *cert)
-{
-    int i, key_len;
-    unsigned char *buf = NULL;
-    if ((key_len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &buf)) == 0) {
-        return NULL;
-    }
-    for (i = 0 ; i < KEYGEN_STORE_SIZE ; ++i) {
-        if ((key_len == pkey_store[i].key_len) &&
-            memcmp(buf, pkey_store[i].public_key, key_len) == 0) {
-            break;
-        }
-    }
-    free(buf);
-    return (i == KEYGEN_STORE_SIZE) ? NULL : pkey_store[i].pkey;
-}
-
-int gen_csr(int bits, const char *challenge, char reply[REPLY_MAX])
-{
-    int len, ret_code = 0;
-    BIGNUM *bn = NULL;
-    char *spkstr = NULL;
-    EVP_PKEY *pkey = NULL;
-    RSA *rsa = NULL;
-    NETSCAPE_SPKI *req = NULL;
-
-    if (challenge == NULL) {
-        ret_code = ERR_INVALID_ARGS;
-        goto err;
-    }
-
-    if ((bits != KEYLENGTH_MEDIUM) && (bits != KEYLENGTH_MAXIMUM)) {
-        ret_code = ERR_INVALID_KEY_LENGTH;
-        goto err;
-    }
-
-    if (((pkey = EVP_PKEY_new()) == NULL) ||
-        ((req = NETSCAPE_SPKI_new()) == NULL) ||
-        ((rsa = RSA_new()) == NULL) || ((bn = BN_new()) == NULL)) {
-        ret_code = ERR_CONSTRUCT_NEW_DATA;
-        goto err;
-    }
-
-    if (!BN_set_word(bn, RSA_F4) ||
-        !RSA_generate_key_ex(rsa, bits, bn, NULL) ||
-        !EVP_PKEY_assign_RSA(pkey, rsa)) {
-        ret_code = ERR_RSA_KEYGEN;
-        goto err;
-    }
-
-    rsa = NULL;
-    ASN1_STRING_set(req->spkac->challenge, challenge, (int)strlen(challenge));
-    NETSCAPE_SPKI_set_pubkey(req, pkey);
-    NETSCAPE_SPKI_sign(req, pkey, EVP_md5());
-    spkstr = NETSCAPE_SPKI_b64_encode(req);
-
-    if ((strlcpy(reply, spkstr, REPLY_MAX)) < REPLY_MAX) {
-        save_in_store(pkey);
-    } else {
-        ret_code = ERR_SPKAC_TOO_LONG;
-    }
-
-err:
-    if (rsa) RSA_free(rsa);
-    if (bn) BN_free(bn);
-    if (req) NETSCAPE_SPKI_free(req);
-    if (pkey) EVP_PKEY_free(pkey);
-    if (spkstr) OPENSSL_free(spkstr);
-    if ((ret_code > 0) && (ret_code < ERR_MAXIMUM)) LOGE(emsg[ret_code]);
-    return -ret_code;
-}
-
-PKCS12 *get_p12_handle(const char *buf, int bufLen)
-{
-    BIO *bp = NULL;
-    PKCS12  *p12 = NULL;
-
-    if (!buf || (bufLen < 1) || (buf[0] != 48)) goto err;
-
-    bp = BIO_new(BIO_s_mem());
-    if (!bp) goto err;
-
-    if (!BIO_write(bp, buf, bufLen)) goto err;
-
-    p12 = d2i_PKCS12_bio(bp, NULL);
-
-err:
-    if (bp) BIO_free(bp);
-    return p12;
-}
-
-PKCS12_KEYSTORE *get_pkcs12_keystore_handle(const char *buf, int bufLen,
-                                            const char *passwd)
-{
-    PKCS12_KEYSTORE *p12store = NULL;
-    EVP_PKEY *pkey = NULL;
-    X509 *cert = NULL;
-    STACK_OF(X509) *certs = NULL;
-    PKCS12  *p12 = get_p12_handle(buf, bufLen);
-
-    if (p12 == NULL) return NULL;
-    if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) {
-        LOGE("Can not parse PKCS12 content");
-        PKCS12_free(p12);
-        return NULL;
-    }
-    if ((p12store = malloc(sizeof(PKCS12_KEYSTORE))) == NULL) {
-        if (cert) X509_free(cert);
-        if (pkey) EVP_PKEY_free(pkey);
-        if (certs) sk_X509_free(certs);
-    }
-    p12store->p12 = p12;
-    p12store->pkey = pkey;
-    p12store->cert = cert;
-    p12store->certs = certs;
-    return p12store;
-}
-
-void free_pkcs12_keystore(PKCS12_KEYSTORE *p12store)
-{
-    if (p12store != NULL) {
-        if (p12store->cert) X509_free(p12store->cert);
-        if (p12store->pkey) EVP_PKEY_free(p12store->pkey);
-        if (p12store->certs) sk_X509_free(p12store->certs);
-        free(p12store);
-    }
-}
-
-int is_pkcs12(const char *buf, int bufLen)
-{
-    int ret = 0;
-    PKCS12  *p12 = get_p12_handle(buf, bufLen);
-    if (p12 != NULL) ret = 1;
-    PKCS12_free(p12);
-    return ret;
-}
-
-static int convert_to_pem(void *data, int is_cert, char *buf, int size)
-{
-    int len = 0;
-    BIO *bio = NULL;
-
-    if (data == NULL) return -1;
-
-    if ((bio = BIO_new(BIO_s_mem())) == NULL) goto err;
-    if (is_cert) {
-        if ((len = PEM_write_bio_X509(bio, (X509*)data)) == 0) {
-            goto err;
-        }
-    } else {
-        if ((len = PEM_write_bio_PrivateKey(bio, (EVP_PKEY *)data, NULL,
-                                            NULL, 0, NULL, NULL)) == 0) {
-            goto err;
-        }
-    }
-    if (len < size && (len = BIO_read(bio, buf, size - 1)) > 0) {
-        buf[len] = 0;
-    }
-err:
-    if (bio) BIO_free(bio);
-    return len;
-}
-
-int get_pkcs12_certificate(PKCS12_KEYSTORE *p12store, char *buf, int size)
-{
-    if ((p12store != NULL) && (p12store->cert != NULL)) {
-        int len = convert_to_pem((void*)p12store->cert, 1, buf, size);
-        return (len == 0) ? -1 : 0;
-    }
-    return -1;
-}
-
-int get_pkcs12_private_key(PKCS12_KEYSTORE *p12store, char *buf, int size)
-{
-    if ((p12store != NULL) && (p12store->pkey != NULL)) {
-        int len = convert_to_pem((void*)p12store->pkey, 0, buf, size);
-        return (len == 0) ? -1 : 0;
-    }
-    return -1;
-}
-
-int pop_pkcs12_certs_stack(PKCS12_KEYSTORE *p12store, char *buf, int size)
-{
-    X509 *cert = NULL;
-    int len = 0;
-
-    if ((p12store != NULL) && (p12store->certs != NULL)) {
-        while (((cert = sk_X509_pop(p12store->certs)) != NULL) && (len < size)) {
-            int s = convert_to_pem((void*)cert, 1, buf + len, size - len);
-            if (s == 0) {
-                LOGE("buffer size is too small. len=%d size=%d\n", len, size);
-                return -1;
-            }
-            len += s;
-            X509_free(cert);
-        }
-        return (len == 0) ? -1 : 0;
-    }
-    return -1;
-}
-
-X509* parse_cert(const char *buf, int bufLen)
-{
-    X509 *cert = NULL;
-    BIO *bp = NULL;
-
-    if(!buf || bufLen < 1)
-        return NULL;
-
-    bp = BIO_new(BIO_s_mem());
-    if (!bp) goto err;
-
-    if (!BIO_write(bp, buf, bufLen)) goto err;
-
-    cert = PEM_read_bio_X509(bp, NULL, NULL, NULL);
-    if (!cert) {
-        BIO_free(bp);
-        if((bp = BIO_new(BIO_s_mem())) == NULL) goto err;
-
-        if(!BIO_write(bp, (char *) buf, bufLen)) goto err;
-        cert = d2i_X509_bio(bp, NULL);
-   }
-
-err:
-    if (bp) BIO_free(bp);
-    return cert;
-}
-
-static int get_distinct_name(X509_NAME *dname, char *buf, int size)
-{
-   int i, len;
-   char *p, *name;
-
-   if (X509_NAME_oneline(dname, buf, size) == NULL) {
-      return -1;
-   }
-   name = strstr(buf, "/CN=");
-   p = name = name ? (name + 4) : buf;
-   while (*p != 0) {
-       if (*p == ' ') *p = '_';
-       if (*p == '/') {
-          *p = 0;
-          break;
-       }
-       ++p;
-   }
-   return 0;
-}
-
-int get_cert_name(X509 *cert, char *buf, int size)
-{
-   if (!cert) return -1;
-   return get_distinct_name(X509_get_subject_name(cert), buf, size);
-}
-
-int get_issuer_name(X509 *cert, char *buf, int size)
-{
-   if (!cert) return -1;
-   return get_distinct_name(X509_get_issuer_name(cert), buf, size);
-}
-
-int is_ca_cert(X509 *cert)
-{
-    int ret = 0;
-    BASIC_CONSTRAINTS *bs = (BASIC_CONSTRAINTS *)
-            X509_get_ext_d2i(cert, NID_basic_constraints, NULL, NULL);
-    if (bs != NULL) ret = bs->ca;
-    if (bs) BASIC_CONSTRAINTS_free(bs);
-    return ret;
-}
-
-int get_private_key_pem(X509 *cert, char *buf, int size)
-{
-    int len = 0;
-    BIO *bio = NULL;
-    EVP_PKEY *pkey = get_pkey_from_store(cert);
-
-    if (pkey == NULL) return -1;
-
-    bio = BIO_new(BIO_s_mem());
-    if ((bio = BIO_new(BIO_s_mem())) == NULL) goto err;
-    if (!PEM_write_bio_PrivateKey(bio, pkey, NULL,NULL,0,NULL, NULL)) {
-        goto err;
-    }
-    if ((len = BIO_read(bio, buf, size - 1)) > 0) {
-        buf[len] = 0;
-    }
-err:
-    if (bio) BIO_free(bio);
-    return (len == 0) ? -1 : 0;
-}
diff --git a/keystore/jni/cert.h b/keystore/jni/cert.h
deleted file mode 100644
index a9e1a9e..0000000
--- a/keystore/jni/cert.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-**
-** Copyright 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 __CERT_H__
-#define __CERT_H__
-
-#define ANDROID_KEYSTORE "Android Keystore"
-#define KEYGEN_STORE_SIZE     5
-#define KEYLENGTH_MEDIUM      1024
-#define KEYLENGTH_MAXIMUM     2048
-#define MAX_CERT_NAME_LEN     128
-#define MAX_PEM_LENGTH        4096
-#define REPLY_MAX             MAX_PEM_LENGTH
-
-
-#define STR(token) #token
-#define ERR_INVALID_KEY_LENGTH  1
-#define ERR_CONSTRUCT_NEW_DATA  2
-#define ERR_RSA_KEYGEN          3
-#define ERR_X509_PROCESS        4
-#define ERR_SPKAC_TOO_LONG      5
-#define ERR_INVALID_ARGS        6
-#define ERR_MAXIMUM             7
-
-typedef struct {
-    EVP_PKEY *pkey;
-    unsigned char *public_key;
-    int key_len;
-} PKEY_STORE;
-
-typedef struct {
-    PKCS12  *p12;
-    EVP_PKEY *pkey;
-    X509 *cert;
-    STACK_OF(X509) *certs;
-} PKCS12_KEYSTORE;
-
-#define PKEY_STORE_free(x) { \
-    if(x.pkey) EVP_PKEY_free(x.pkey); \
-    if(x.public_key) free(x.public_key); \
-}
-
-#define nelem(x) (sizeof (x) / sizeof *(x))
-
-int gen_csr(int bits, const char *organizations, char reply[REPLY_MAX]);
-PKCS12_KEYSTORE *get_pkcs12_keystore_handle(const char *buf, int bufLen,
-                                            const char *passwd);
-int get_pkcs12_certificate(PKCS12_KEYSTORE *p12store, char *buf, int size);
-int get_pkcs12_private_key(PKCS12_KEYSTORE *p12store, char *buf, int size);
-int pop_pkcs12_certs_stack(PKCS12_KEYSTORE *p12store, char *buf, int size);
-void free_pkcs12_keystore(PKCS12_KEYSTORE *p12store);
-int is_pkcs12(const char *buf, int bufLen);
-X509 *parse_cert(const char *buf, int bufLen);
-int get_cert_name(X509 *cert, char *buf, int size);
-int get_issuer_name(X509 *cert, char *buf, int size);
-int is_ca_cert(X509 *cert);
-int get_private_key_pem(X509 *cert, char *buf, int size);
-
-#endif
diff --git a/keystore/jni/certtool.c b/keystore/jni/certtool.c
deleted file mode 100644
index b36b34a..0000000
--- a/keystore/jni/certtool.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
-**
-** Copyright 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_TAG "CertTool"
-
-#include <string.h>
-#include <jni.h>
-#include <cutils/log.h>
-#include <openssl/pkcs12.h>
-#include <openssl/x509v3.h>
-
-#include "cert.h"
-
-typedef int PKCS12_KEYSTORE_FUNC(PKCS12_KEYSTORE *store, char *buf, int size);
-
-jstring
-android_security_CertTool_generateCertificateRequest(JNIEnv* env,
-                                                     jobject thiz,
-                                                     jint bits,
-                                                     jstring jChallenge)
-
-{
-    int ret = -1;
-    jboolean bIsCopy;
-    char csr[REPLY_MAX];
-    const char* challenge = (*env)->GetStringUTFChars(env, jChallenge, &bIsCopy);
-
-    ret = gen_csr(bits, challenge , csr);
-    (*env)->ReleaseStringUTFChars(env, jChallenge, challenge);
-    if (ret == 0) return (*env)->NewStringUTF(env, csr);
-    return NULL;
-}
-
-jboolean
-android_security_CertTool_isPkcs12Keystore(JNIEnv* env,
-                                           jobject thiz,
-                                           jbyteArray data)
-{
-    int len = (*env)->GetArrayLength(env, data);
-
-    if (len > 0) {
-        PKCS12 *handle = NULL;
-        char buf[len];
-
-        (*env)->GetByteArrayRegion(env, data, 0, len, (jbyte*)buf);
-        return (jboolean)is_pkcs12(buf, len);
-    } else {
-        return 0;
-    }
-}
-
-jint
-android_security_CertTool_getPkcs12Handle(JNIEnv* env,
-                                          jobject thiz,
-                                          jbyteArray data,
-                                          jstring jPassword)
-{
-    jboolean bIsCopy;
-    int len = (*env)->GetArrayLength(env, data);
-    const char* passwd = (*env)->GetStringUTFChars(env, jPassword , &bIsCopy);
-
-    if (len > 0) {
-        PKCS12_KEYSTORE *handle = NULL;
-        char buf[len];
-
-        (*env)->GetByteArrayRegion(env, data, 0, len, (jbyte*)buf);
-        handle = get_pkcs12_keystore_handle(buf, len, passwd);
-        (*env)->ReleaseStringUTFChars(env, jPassword, passwd);
-        return (jint)handle;
-    } else {
-        return 0;
-    }
-}
-
-jstring call_pkcs12_ks_func(PKCS12_KEYSTORE_FUNC *func,
-                            JNIEnv* env,
-                            jobject thiz,
-                            jint phandle)
-{
-    char buf[REPLY_MAX];
-
-    if (phandle == 0) return NULL;
-    if (func((PKCS12_KEYSTORE*)phandle, buf, sizeof(buf)) == 0) {
-        return (*env)->NewStringUTF(env, buf);
-    }
-    return NULL;
-}
-
-jstring
-android_security_CertTool_getPkcs12Certificate(JNIEnv* env,
-                                               jobject thiz,
-                                               jint phandle)
-{
-    return call_pkcs12_ks_func((PKCS12_KEYSTORE_FUNC *)get_pkcs12_certificate,
-                               env, thiz, phandle);
-}
-
-jstring
-android_security_CertTool_getPkcs12PrivateKey(JNIEnv* env,
-                                              jobject thiz,
-                                              jint phandle)
-{
-    return call_pkcs12_ks_func((PKCS12_KEYSTORE_FUNC *)get_pkcs12_private_key,
-                               env, thiz, phandle);
-}
-
-jstring
-android_security_CertTool_popPkcs12CertificateStack(JNIEnv* env,
-                                                    jobject thiz,
-                                                    jint phandle)
-{
-    return call_pkcs12_ks_func((PKCS12_KEYSTORE_FUNC *)pop_pkcs12_certs_stack,
-                               env, thiz, phandle);
-}
-
-void android_security_CertTool_freePkcs12Handle(JNIEnv* env,
-                                                jobject thiz,
-                                                jint handle)
-{
-    if (handle != 0) free_pkcs12_keystore((PKCS12_KEYSTORE*)handle);
-}
-
-jint
-android_security_CertTool_generateX509Certificate(JNIEnv* env,
-                                                  jobject thiz,
-                                                  jbyteArray data)
-{
-    char buf[REPLY_MAX];
-    int len = (*env)->GetArrayLength(env, data);
-
-    if (len > REPLY_MAX) return 0;
-    (*env)->GetByteArrayRegion(env, data, 0, len, (jbyte*)buf);
-    return (jint) parse_cert(buf, len);
-}
-
-jboolean android_security_CertTool_isCaCertificate(JNIEnv* env,
-                                                   jobject thiz,
-                                                   jint handle)
-{
-    return (handle == 0) ? (jboolean)0 : (jboolean) is_ca_cert((X509*)handle);
-}
-
-jstring android_security_CertTool_getIssuerDN(JNIEnv* env,
-                                              jobject thiz,
-                                              jint handle)
-{
-    char issuer[MAX_CERT_NAME_LEN];
-
-    if (handle == 0) return NULL;
-    if (get_issuer_name((X509*)handle, issuer, MAX_CERT_NAME_LEN)) return NULL;
-    return (*env)->NewStringUTF(env, issuer);
-}
-
-jstring android_security_CertTool_getCertificateDN(JNIEnv* env,
-                                                   jobject thiz,
-                                                   jint handle)
-{
-    char name[MAX_CERT_NAME_LEN];
-    if (handle == 0) return NULL;
-    if (get_cert_name((X509*)handle, name, MAX_CERT_NAME_LEN)) return NULL;
-    return (*env)->NewStringUTF(env, name);
-}
-
-jstring android_security_CertTool_getPrivateKeyPEM(JNIEnv* env,
-                                                   jobject thiz,
-                                                   jint handle)
-{
-    char pem[MAX_PEM_LENGTH];
-    if (handle == 0) return NULL;
-    if (get_private_key_pem((X509*)handle, pem, MAX_PEM_LENGTH)) return NULL;
-    return (*env)->NewStringUTF(env, pem);
-}
-
-void android_security_CertTool_freeX509Certificate(JNIEnv* env,
-                                                   jobject thiz,
-                                                   jint handle)
-{
-    if (handle != 0) X509_free((X509*)handle);
-}
-
-/*
- * Table of methods associated with the CertTool class.
- */
-static JNINativeMethod gCertToolMethods[] = {
-    /* name, signature, funcPtr */
-    {"generateCertificateRequest", "(ILjava/lang/String;)Ljava/lang/String;",
-        (void*)android_security_CertTool_generateCertificateRequest},
-    {"isPkcs12Keystore", "([B)Z",
-        (void*)android_security_CertTool_isPkcs12Keystore},
-    {"getPkcs12Handle", "([BLjava/lang/String;)I",
-        (void*)android_security_CertTool_getPkcs12Handle},
-    {"getPkcs12Certificate", "(I)Ljava/lang/String;",
-        (void*)android_security_CertTool_getPkcs12Certificate},
-    {"getPkcs12PrivateKey", "(I)Ljava/lang/String;",
-        (void*)android_security_CertTool_getPkcs12PrivateKey},
-    {"popPkcs12CertificateStack", "(I)Ljava/lang/String;",
-        (void*)android_security_CertTool_popPkcs12CertificateStack},
-    {"freePkcs12Handle", "(I)V",
-        (void*)android_security_CertTool_freePkcs12Handle},
-    {"generateX509Certificate", "([B)I",
-        (void*)android_security_CertTool_generateX509Certificate},
-    {"isCaCertificate", "(I)Z",
-        (void*)android_security_CertTool_isCaCertificate},
-    {"getIssuerDN", "(I)Ljava/lang/String;",
-        (void*)android_security_CertTool_getIssuerDN},
-    {"getCertificateDN", "(I)Ljava/lang/String;",
-        (void*)android_security_CertTool_getCertificateDN},
-    {"getPrivateKeyPEM", "(I)Ljava/lang/String;",
-        (void*)android_security_CertTool_getPrivateKeyPEM},
-    {"freeX509Certificate", "(I)V",
-        (void*)android_security_CertTool_freeX509Certificate},
-};
-
-/*
- * Register several native methods for one class.
- */
-static int registerNatives(JNIEnv* env, const char* className,
-                           JNINativeMethod* gMethods, int numMethods)
-{
-    jclass clazz;
-
-    clazz = (*env)->FindClass(env, className);
-    if (clazz == NULL) {
-        LOGE("Can not find class %s\n", className);
-        return JNI_FALSE;
-    }
-
-    if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {
-        LOGE("Can not RegisterNatives\n");
-        return JNI_FALSE;
-    }
-
-    return JNI_TRUE;
-}
-
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
-{
-    JNIEnv* env = NULL;
-    jint result = -1;
-
-
-    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
-        goto bail;
-    }
-
-    if (!registerNatives(env, "android/security/CertTool",
-                         gCertToolMethods, nelem(gCertToolMethods))) {
-        goto bail;
-    }
-
-    /* success -- return valid version number */
-    result = JNI_VERSION_1_4;
-
-bail:
-    return result;
-}
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index ab8d0653..cc11ab2 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -20,12 +20,16 @@
 #include <ui/FramebufferNativeWindow.h>
 #include <ui/EGLUtils.h>
 
+#include <cutils/properties.h>
+
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
 using namespace android;
 using namespace android::renderscript;
 
+bool g_logTimes = -1;
+
 pthread_key_t Context::gThreadTLSKey = 0;
 
 void Context::initEGL()
@@ -113,9 +117,9 @@
 
 bool Context::runRootScript()
 {
-#if RS_LOG_TIMES
-    timerSet(RS_TIMER_CLEAR_SWAP);
-#endif
+    if (this->logTimes) {
+        timerSet(RS_TIMER_CLEAR_SWAP);
+    }
     rsAssert(mRootScript->mEnviroment.mIsRoot);
 
     eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
@@ -136,9 +140,9 @@
         glClear(GL_COLOR_BUFFER_BIT);
     }
 
-#if RS_LOG_TIMES
-    timerSet(RS_TIMER_SCRIPT);
-#endif
+    if (this->logTimes) {
+        timerSet(RS_TIMER_SCRIPT);
+    }
     bool ret = runScript(mRootScript.get(), 0);
     return ret;
 }
@@ -204,11 +208,19 @@
     mVertex->setupGL(this, &mStateVertex);
 }
 
+static bool get_log_times()
+{
+    char buf[PROPERTY_VALUE_MAX];
+    property_get("debug.rs.profile", buf, "0");
+    return 0 != strcmp(buf, "0");
+}
 
 void * Context::threadProc(void *vrsc)
 {
      Context *rsc = static_cast<Context *>(vrsc);
 
+     rsc->logTimes = get_log_times();
+
      rsc->initEGL();
 
      ScriptTLSStruct *tlsStruct = new ScriptTLSStruct;
@@ -240,16 +252,16 @@
 
          if (mDraw) {
              mDraw = rsc->runRootScript();
-#if RS_LOG_TIMES
-             rsc->timerSet(RS_TIMER_CLEAR_SWAP);
-#endif
+             if (rsc->logTimes) {
+                 rsc->timerSet(RS_TIMER_CLEAR_SWAP);
+             }
              eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
-#if RS_LOG_TIMES
-             rsc->timerFrame();
-             rsc->timerSet(RS_TIMER_INTERNAL);
-             rsc->timerPrint();
-             rsc->timerReset();
-#endif
+             if (rsc->logTimes) {
+                 rsc->timerFrame();
+                 rsc->timerSet(RS_TIMER_INTERNAL);
+                 rsc->timerPrint();
+                 rsc->timerReset();
+             }
          }
          if (rsc->mObjDestroy.mNeedToEmpty) {
              rsc->objDestroyOOBRun();
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 3e07f3e..1fb697a 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -143,6 +143,8 @@
     bool checkVersion1_1() const {return (mGL.mMajorVersion > 1) || (mGL.mMinorVersion >= 1); }
     bool checkVersion2_0() const {return mGL.mMajorVersion >= 2; }
 
+    bool logTimes;
+
 protected:
     Device *mDev;
 
@@ -215,7 +217,6 @@
     uint64_t mTimeLastFrame;
 };
 
-
 }
 }
 #endif
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index db4bb81..4072f06 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -42,13 +42,13 @@
         uint32_t cmdID = 0;
         uint32_t cmdSize = 0;
         ret = true;
-#if RS_LOG_TIMES
-        con->timerSet(Context::RS_TIMER_IDLE);
-#endif
+        if (con->logTimes) {
+            con->timerSet(Context::RS_TIMER_IDLE);
+        }
         const void * data = mToCore.get(&cmdID, &cmdSize);
-#if RS_LOG_TIMES
-        con->timerSet(Context::RS_TIMER_INTERNAL);
-#endif
+        if (con->logTimes) {
+            con->timerSet(Context::RS_TIMER_INTERNAL);
+        }
         waitForCommand = false;
         //LOGV("playCoreCommands 3 %i %i", cmdID, cmdSize);
 
diff --git a/libs/rs/rsUtils.h b/libs/rs/rsUtils.h
index ec928db..63d73a1 100644
--- a/libs/rs/rsUtils.h
+++ b/libs/rs/rsUtils.h
@@ -41,8 +41,6 @@
 #define rsAssert(v) while(0)
 #endif
 
-#define RS_LOG_TIMES 0
-
 template<typename T>
 T rsMin(T in1, T in2)
 {
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 5ff9284..67ddcf9 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -51,7 +51,8 @@
         const sp<Client>& c, int32_t i)
     :   LayerBaseClient(flinger, display, c, i),
         mSecure(false),
-        mNeedsBlending(true)
+        mNeedsBlending(true),
+        mNeedsDithering(false)
 {
     // no OpenGL operation is possible here, since we might not be
     // in the OpenGL thread.
@@ -88,6 +89,7 @@
         mBuffers[i].clear();
         mWidth = mHeight = 0;
     }
+    mSurface.clear();
 }
 
 sp<LayerBaseClient::Surface> Layer::createSurface() const
@@ -98,18 +100,23 @@
 status_t Layer::ditch()
 {
     // the layer is not on screen anymore. free as much resources as possible
-    //destroy();
-    mSurface.clear();
+    destroy();
     return NO_ERROR;
 }
 
 status_t Layer::setBuffers( uint32_t w, uint32_t h,
                             PixelFormat format, uint32_t flags)
 {
+    // this surfaces pixel format
     PixelFormatInfo info;
     status_t err = getPixelFormatInfo(format, &info);
     if (err) return err;
 
+    // the display's pixel format
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    PixelFormatInfo displayInfo;
+    getPixelFormatInfo(hw.getFormat(), &displayInfo);
+
     uint32_t bufferFlags = 0;
     if (flags & ISurfaceComposer::eSecure)
         bufferFlags |= Buffer::SECURE;
@@ -119,6 +126,12 @@
     mHeight = h;
     mSecure = (bufferFlags & Buffer::SECURE) ? true : false;
     mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
+
+    // we use the red index
+    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
+    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
+    mNeedsDithering = layerRedsize > displayRedSize;
+
     mBufferFlags = bufferFlags;
     for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
         mBuffers[i] = new Buffer();
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
index 2e8173d..6c7b27b 100644
--- a/libs/surfaceflinger/Layer.h
+++ b/libs/surfaceflinger/Layer.h
@@ -68,6 +68,7 @@
     virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
     virtual void finishPageFlip();
     virtual bool needsBlending() const      { return mNeedsBlending; }
+    virtual bool needsDithering() const     { return mNeedsDithering; }
     virtual bool isSecure() const           { return mSecure; }
     virtual sp<Surface> createSurface() const;
     virtual status_t ditch();
@@ -109,6 +110,7 @@
             bool            mSecure;
             int32_t         mFrontBufferIndex;
             bool            mNeedsBlending;
+            bool            mNeedsDithering;
             Region          mPostedDirtyRegion;
             sp<FreezeLock>  mFreezeLock;
             PixelFormat     mFormat;
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index e08861d..5a93b2d 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -56,6 +56,7 @@
     : dpy(display), contentDirty(false),
       mFlinger(flinger),
       mTransformed(false),
+      mUseLinearFiltering(false),
       mOrientation(0),
       mTransactionFlags(0),
       mPremultipliedAlpha(true),
@@ -208,7 +209,19 @@
         flags |= eVisibleRegion;
         this->contentDirty = true;
     }
-    
+
+    if (temp.sequence != front.sequence) {
+        const bool linearFiltering = mUseLinearFiltering;
+        mUseLinearFiltering = false;
+        if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
+            // we may use linear filtering, if the matrix scales us
+            const uint8_t type = temp.transform.getType();
+            if (!temp.transform.preserveRects() || (type >= Transform::SCALE)) {
+                mUseLinearFiltering = true;
+            }
+        }
+    }
+
     // Commit the transaction
     commitTransaction(flags & eRestartTransaction);
     return flags;
@@ -332,13 +345,8 @@
     glBindTexture(GL_TEXTURE_2D, textureName);
     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    if (mFlags & DisplayHardware::SLOW_CONFIG) {
-        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    } else {
-        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    }
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     return textureName;
 }
 
@@ -385,14 +393,6 @@
     
     glEnable(GL_TEXTURE_2D);
 
-    // Dithering...
-    bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG);
-    if (fast || s.flags & ISurfaceComposer::eLayerDither) {
-        glEnable(GL_DITHER);
-    } else {
-        glDisable(GL_DITHER);
-    }
-
     if (UNLIKELY(s.alpha < 0xFF)) {
         // We have an alpha-modulation. We need to modulate all
         // texture components by alpha because we're always using 
@@ -434,12 +434,6 @@
         Region::const_iterator it = clip.begin();
         Region::const_iterator const end = clip.end();
         if (it != end) {
-            // always use high-quality filtering with fast configurations
-            bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG);
-            if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
-                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-            }            
             const GLfixed texCoords[4][2] = {
                     { 0,        0 },
                     { 0,        0x10000 },
@@ -481,11 +475,6 @@
                 glScissor(r.left, sy, r.width(), r.height());
                 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
             }
-
-            if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
-                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-            }
             glDisableClientState(GL_TEXTURE_COORD_ARRAY);
         }
     } else {
@@ -512,6 +501,19 @@
     glBindTexture(GL_TEXTURE_2D, textureName);
     // TODO: reload the texture if needed
     // this is currently done in loadTexture() below
+    if (mUseLinearFiltering) {
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    } else {
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    }
+
+    if (needsDithering()) {
+        glEnable(GL_DITHER);
+    } else {
+        glDisable(GL_DITHER);
+    }
 }
 
 void LayerBase::loadTexture(Texture* texture, GLint textureName, 
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index 3a52240..233737d 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -188,6 +188,11 @@
     virtual bool needsBlending() const  { return false; }
 
     /**
+     * needsDithering - true if this surface needs dithering
+     */
+    virtual bool needsDithering() const { return false; }
+
+    /**
      * transformed -- true is this surface needs a to be transformed
      */
     virtual bool transformed() const    { return mTransformed; }
@@ -254,6 +259,7 @@
 
                 // cached during validateVisibility()
                 bool            mTransformed;
+                bool            mUseLinearFiltering;
                 int32_t         mOrientation;
                 GLfixed         mVertices[4][2];
                 Rect            mTransformedBounds;
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 831c446..a0b48d4 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -1084,12 +1084,9 @@
 
 status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
 {
-    // First add the layer to the purgatory list, which makes sure it won't 
-    // go away, then remove it from the main list (through a transaction).
+    // remove the layer from the main list (through a transaction).
     ssize_t err = removeLayer_l(layerBase);
-    if (err >= 0) {
-        mLayerPurgatory.add(layerBase);
-    }
+
     // it's possible that we don't find a layer, because it might
     // have been destroyed already -- this is not technically an error
     // from the user because there is a race between BClient::destroySurface(),
@@ -1362,18 +1359,8 @@
              * to use the purgatory.
              */
             status_t err = flinger->removeLayer_l(l);
-            if (err == NAME_NOT_FOUND) {
-                // The surface wasn't in the current list, which means it was
-                // removed already, which means it is in the purgatory, 
-                // and need to be removed from there.
-                // This needs to happen from the main thread since its dtor
-                // must run from there (b/c of OpenGL ES). Additionally, we
-                // can't really acquire our internal lock from 
-                // destroySurface() -- see postMessage() below.
-                ssize_t idx = flinger->mLayerPurgatory.remove(l);
-                LOGE_IF(idx < 0,
-                        "layer=%p is not in the purgatory list", l.get());
-            }
+            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
+                    "error removing layer=%p (%s)", l.get(), strerror(-err));
             return true;
         }
     };
@@ -1510,11 +1497,12 @@
                     "+ %s %p\n"
                     "      "
                     "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
-                    "needsBlending=%1d, invalidate=%1d, "
+                    "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, "
                     "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
                     layer->getTypeID(), layer.get(),
                     s.z, layer->tx(), layer->ty(), s.w, s.h,
-                    layer->needsBlending(), layer->contentDirty,
+                    layer->needsBlending(), layer->needsDithering(),
+                    layer->contentDirty,
                     s.alpha, s.flags,
                     s.transform[0], s.transform[1],
                     s.transform[2], s.transform[3]);
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index 493e777..e446070 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -314,7 +314,6 @@
     volatile    int32_t                 mTransactionCount;
                 Condition               mTransactionCV;
                 bool                    mResizeTransationPending;
-                SortedVector< sp<LayerBase> > mLayerPurgatory;
                 
                 // protected by mStateLock (but we could use another lock)
                 Tokenizer                               mTokens;
diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h
index 4c4528e..78f5c19 100644
--- a/libs/surfaceflinger/Transform.h
+++ b/libs/surfaceflinger/Transform.h
@@ -50,6 +50,14 @@
                 ROT_INVALID = 0x80000000
             };
 
+            enum type_mask {
+                IDENTITY            = 0,
+                TRANSLATE           = 0x1,
+                SCALE               = 0x2,
+                AFFINE              = 0x4,
+                PERSPECTIVE         = 0x8
+            };
+
             bool    transformed() const;
             int32_t getOrientation() const;
             bool    preserveRects() const;
diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp
index 8401cb6..3baa281 100644
--- a/libs/ui/SurfaceComposerClient.cpp
+++ b/libs/ui/SurfaceComposerClient.cpp
@@ -62,34 +62,42 @@
 static sp<IMemoryHeap>                                      gServerCblkMemory;
 static volatile surface_flinger_cblk_t*                     gServerCblk;
 
-const sp<ISurfaceComposer>& _get_surface_manager()
+static sp<ISurfaceComposer> getComposerService()
 {
-    if (gSurfaceManager != 0) {
-        return gSurfaceManager;
-    }
-
-    sp<IBinder> binder;
-    sp<IServiceManager> sm = defaultServiceManager();
-    do {
-        binder = sm->getService(String16("SurfaceFlinger"));
-        if (binder == 0) {
-            LOGW("SurfaceFlinger not published, waiting...");
-            usleep(500000); // 0.5 s
-        }
-    } while(binder == 0);
-    sp<ISurfaceComposer> sc(interface_cast<ISurfaceComposer>(binder));
-
+    sp<ISurfaceComposer> sc;
     Mutex::Autolock _l(gLock);
-    if (gSurfaceManager == 0) {
-        gSurfaceManager = sc;
+    if (gSurfaceManager != 0) {
+        sc = gSurfaceManager;
+    } else {
+        // release the lock while we're waiting...
+        gLock.unlock();
+
+        sp<IBinder> binder;
+        sp<IServiceManager> sm = defaultServiceManager();
+        do {
+            binder = sm->getService(String16("SurfaceFlinger"));
+            if (binder == 0) {
+                LOGW("SurfaceFlinger not published, waiting...");
+                usleep(500000); // 0.5 s
+            }
+        } while(binder == 0);
+
+        // grab the lock again for updating gSurfaceManager
+        gLock.lock();
+        if (gSurfaceManager == 0) {
+            sc = interface_cast<ISurfaceComposer>(binder);
+            gSurfaceManager = sc;
+        } else {
+            sc = gSurfaceManager;
+        }
     }
-    return gSurfaceManager;
+    return sc;
 }
 
 static volatile surface_flinger_cblk_t const * get_cblk()
 {
     if (gServerCblk == 0) {
-        const sp<ISurfaceComposer>& sm(_get_surface_manager());
+        sp<ISurfaceComposer> sm(getComposerService());
         Mutex::Autolock _l(gLock);
         if (gServerCblk == 0) {
             gServerCblkMemory = sm->getCblk();
@@ -112,7 +120,7 @@
 
 SurfaceComposerClient::SurfaceComposerClient()
 {
-    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    sp<ISurfaceComposer> sm(getComposerService());
     if (sm == 0) {
         _init(0, 0);
         return;
@@ -133,6 +141,15 @@
     _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
 }
 
+
+status_t SurfaceComposerClient::linkToComposerDeath(
+        const sp<IBinder::DeathRecipient>& recipient,
+        void* cookie, uint32_t flags)
+{
+    sp<ISurfaceComposer> sm(getComposerService());
+    return sm->asBinder()->linkToDeath(recipient, cookie, flags);    
+}
+
 void SurfaceComposerClient::_init(
         const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
 {
@@ -183,7 +200,7 @@
 
     if (client == 0) {
         // Need to make a new client.
-        const sp<ISurfaceComposer>& sm(_get_surface_manager());
+        sp<ISurfaceComposer> sm(getComposerService());
         client = new SurfaceComposerClient(sm, conn);
         if (client != 0 && client->initCheck() == NO_ERROR) {
             Mutex::Autolock _l(gLock);
@@ -377,7 +394,7 @@
     const size_t N = clients.size();
     VERBOSE("closeGlobalTransaction (%ld clients)", N);
 
-    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    sp<ISurfaceComposer> sm(getComposerService());
     sm->openGlobalTransaction();
     for (size_t i=0; i<N; i++) {
         clients[i]->closeTransaction();
@@ -389,20 +406,20 @@
 
 status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
 {
-    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    sp<ISurfaceComposer> sm(getComposerService());
     return sm->freezeDisplay(dpy, flags);
 }
 
 status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
 {
-    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    sp<ISurfaceComposer> sm(getComposerService());
     return sm->unfreezeDisplay(dpy, flags);
 }
 
 int SurfaceComposerClient::setOrientation(DisplayID dpy, 
         int orientation, uint32_t flags)
 {
-    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    sp<ISurfaceComposer> sm(getComposerService());
     return sm->setOrientation(dpy, orientation, flags);
 }
 
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 5439f8b..3c46954 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -473,8 +473,10 @@
     public void stopListening(int hostId) {
         synchronized (mAppWidgetIds) {
             Host host = lookupHostLocked(getCallingUid(), hostId);
-            host.callbacks = null;
-            pruneHostLocked(host);
+            if (host != null) {
+                host.callbacks = null;
+                pruneHostLocked(host);
+            }
         }
     }
 
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 38d2304..2c39c2a 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -3913,6 +3913,20 @@
         return mPolicy.inKeyguardRestrictedKeyInputMode();
     }
 
+    public void closeSystemDialogs(String reason) {
+        synchronized(mWindowMap) {
+            for (int i=mWindows.size()-1; i>=0; i--) {
+                WindowState w = (WindowState)mWindows.get(i);
+                if (w.mSurface != null) {
+                    try {
+                        w.mClient.closeSystemDialogs(reason);
+                    } catch (RemoteException e) {
+                    }
+                }
+            }
+        }
+    }
+    
     static float fixScale(float scale) {
         if (scale < 0) scale = 0;
         else if (scale > 20) scale = 20;
@@ -7320,18 +7334,22 @@
             // are currently targeting.
             if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
                     && mWallpaperTarget != null) {
-                if (mWallpaperTarget.mHasLocalTransformation) {
+                if (mWallpaperTarget.mHasLocalTransformation &&
+                        mWallpaperTarget.mAnimation != null &&
+                        !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
                     attachedTransformation = mWallpaperTarget.mTransformation;
+                    if (DEBUG_WALLPAPER && attachedTransformation != null) {
+                        Log.v(TAG, "WP target attached xform: " + attachedTransformation);
+                    }
                 }
                 if (mWallpaperTarget.mAppToken != null &&
-                        mWallpaperTarget.mAppToken.hasTransformation) {
+                        mWallpaperTarget.mAppToken.hasTransformation &&
+                        mWallpaperTarget.mAppToken.animation != null &&
+                        !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
                     appTransformation = mWallpaperTarget.mAppToken.transformation;
-                }
-                if (DEBUG_WALLPAPER && attachedTransformation != null) {
-                    Log.v(TAG, "WP target attached xform: " + attachedTransformation);
-                }
-                if (DEBUG_WALLPAPER && appTransformation != null) {
-                    Log.v(TAG, "WP target app xform: " + appTransformation);
+                    if (DEBUG_WALLPAPER && appTransformation != null) {
+                        Log.v(TAG, "WP target app xform: " + appTransformation);
+                    }
                 }
             }
             
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 8ea2221..750c44e 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -4957,6 +4957,16 @@
             }
             mWatchers.finishBroadcast();
             
+            mWindowManager.closeSystemDialogs(reason);
+            
+            for (i=mHistory.size()-1; i>=0; i--) {
+                HistoryRecord r = (HistoryRecord)mHistory.get(i);
+                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
+                    finishActivityLocked(r, i,
+                            Activity.RESULT_CANCELED, null, "close-sys");
+                }
+            }
+            
             broadcastIntentLocked(null, null, intent, null,
                     null, 0, null, null, null, false, false, -1, uid);
         }
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
index 7d600f0..f763d3f 100644
--- a/telephony/java/android/telephony/CellLocation.java
+++ b/telephony/java/android/telephony/CellLocation.java
@@ -26,11 +26,10 @@
 import android.telephony.cdma.CdmaCellLocation;
 import android.telephony.gsm.GsmCellLocation;
 import com.android.internal.telephony.ITelephony;
-import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.Phone;
 
 /**
- * Abstract class that represents the location of the device.  Currently the only
- * subclass is {@link android.telephony.gsm.GsmCellLocation}.  {@more}
+ * Abstract class that represents the location of the device.  {@more}
  */
 public abstract class CellLocation {
 
@@ -64,11 +63,13 @@
     public static CellLocation newFromBundle(Bundle bundle) {
         // TelephonyManager.getDefault().getPhoneType() handles the case when
         // ITelephony interface is not up yet.
-        int type = TelephonyManager.getDefault().getPhoneType();
-        if (type == RILConstants.CDMA_PHONE) {
+        switch(TelephonyManager.getDefault().getPhoneType()) {
+        case Phone.PHONE_TYPE_CDMA:
             return new CdmaCellLocation(bundle);
-        } else {
+        case Phone.PHONE_TYPE_GSM:
             return new GsmCellLocation(bundle);
+        default:
+            return null;
         }
     }
 
@@ -78,17 +79,20 @@
     public abstract void fillInNotifierBundle(Bundle bundle);
 
     /**
-     * Return a new CellLocation object representing an unknown location.
+     * Return a new CellLocation object representing an unknown
+     * location, or null for unknown/none phone radio types.
      *
      */
     public static CellLocation getEmpty() {
         // TelephonyManager.getDefault().getPhoneType() handles the case when
         // ITelephony interface is not up yet.
-        int type = TelephonyManager.getDefault().getPhoneType();
-        if (type == RILConstants.CDMA_PHONE) {
+        switch(TelephonyManager.getDefault().getPhoneType()) {
+        case Phone.PHONE_TYPE_CDMA:
             return new CdmaCellLocation();
-        } else {
+        case Phone.PHONE_TYPE_GSM:
             return new GsmCellLocation();
+        default:
+            return null;
         }
     }
 }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 8914aceac..6664b08 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -263,22 +263,12 @@
        }
     }
 
-    /**
-     * No phone module
-     *
-     */
-    public static final int PHONE_TYPE_NONE = RILConstants.NO_PHONE;
-
-    /**
-     * GSM phone
-     */
-    public static final int PHONE_TYPE_GSM = RILConstants.GSM_PHONE;
-
-    /**
-     * CDMA phone
-     * @hide
-     */
-    public static final int PHONE_TYPE_CDMA = RILConstants.CDMA_PHONE;
+    /** No phone radio. */
+    public static final int PHONE_TYPE_NONE = Phone.PHONE_TYPE_NONE;
+    /** Phone radio is GSM. */
+    public static final int PHONE_TYPE_GSM = Phone.PHONE_TYPE_GSM;
+    /** Phone radio is CDMA. */
+    public static final int PHONE_TYPE_CDMA = Phone.PHONE_TYPE_CDMA;
 
     /**
      * Returns a constant indicating the device phone type.
@@ -291,11 +281,7 @@
         try{
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                if(telephony.getActivePhoneType() == RILConstants.CDMA_PHONE) {
-                    return PHONE_TYPE_CDMA;
-                } else {
-                    return PHONE_TYPE_GSM;
-                }
+                return telephony.getActivePhoneType();
             } else {
                 // This can happen when the ITelephony interface is not up yet.
                 return getPhoneTypeFromProperty();
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index 52f25f6..7586ba2 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -676,7 +676,7 @@
                 mRadioTechnologyChangedRegistrants.notifyRegistrants();
             }
 
-            if (mState.isGsm() && !oldState.isOn() && (mPhoneType == RILConstants.CDMA_PHONE)) {
+            if (mState.isGsm() && !oldState.isOn() && (mPhoneType == Phone.PHONE_TYPE_CDMA)) {
                 Log.d(LOG_TAG,"Notifying: radio technology change CDMA OFF to GSM");
                 mRadioTechnologyChangedRegistrants.notifyRegistrants();
             }
@@ -686,7 +686,7 @@
                 mRadioTechnologyChangedRegistrants.notifyRegistrants();
             }
 
-            if (mState.isCdma() && !oldState.isOn() && (mPhoneType == RILConstants.GSM_PHONE)) {
+            if (mState.isCdma() && !oldState.isOn() && (mPhoneType == Phone.PHONE_TYPE_GSM)) {
                 Log.d(LOG_TAG,"Notifying: radio technology change GSM OFF to CDMA");
                 mRadioTechnologyChangedRegistrants.notifyRegistrants();
             }
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 9d83556..5777cad 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -1256,6 +1256,7 @@
 
     /** Set the Phone type created */
     void setPhoneType(int phoneType);
+
     /**
      *  Query the CDMA roaming preference setting
      *
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index fffd128..c113581 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -173,6 +173,11 @@
     static final int BM_AUS2_BAND   = 5; // GSM-900 / DCS-1800 / WCDMA-850
     static final int BM_BOUNDARY    = 6; // upper band boundary
 
+    // Radio Type
+    static final int PHONE_TYPE_NONE = RILConstants.NO_PHONE;
+    static final int PHONE_TYPE_GSM = RILConstants.GSM_PHONE;
+    static final int PHONE_TYPE_CDMA = RILConstants.CDMA_PHONE;
+
     // Used for preferred network type
     // Note NT_* substitute RILConstants.NETWORK_MODE_* above the Phone
     int NT_MODE_WCDMA_PREF   = RILConstants.NETWORK_MODE_WCDMA_PREF;
@@ -288,6 +293,12 @@
     String getPhoneName();
 
     /**
+     * Return a numerical identifier for the phone radio interface.
+     * @return PHONE_TYPE_XXX as defined above.
+     */
+    int getPhoneType();
+
+    /**
      * Returns an array of string identifiers for the APN types serviced by the
      * currently active or last connected APN.
      *  @return The string array.
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 1c62a82..1c03c5a 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -740,6 +740,8 @@
 
     public abstract String getPhoneName();
 
+    public abstract int getPhoneType();
+
     /** @hide */
     public int getVoiceMessageCount(){
         return 0;
diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java
index a84f74e..cd72752 100644
--- a/telephony/java/com/android/internal/telephony/PhoneFactory.java
+++ b/telephony/java/com/android/internal/telephony/PhoneFactory.java
@@ -108,11 +108,11 @@
                 sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
 
                 int phoneType = getPhoneType(networkMode);
-                if (phoneType == RILConstants.GSM_PHONE) {
+                if (phoneType == Phone.PHONE_TYPE_GSM) {
                     sProxyPhone = new PhoneProxy(new GSMPhone(context,
                             sCommandsInterface, sPhoneNotifier));
                     Log.i(LOG_TAG, "Creating GSMPhone");
-                } else if (phoneType == RILConstants.CDMA_PHONE) {
+                } else if (phoneType == Phone.PHONE_TYPE_CDMA) {
                     sProxyPhone = new PhoneProxy(new CDMAPhone(context,
                             sCommandsInterface, sPhoneNotifier));
                     Log.i(LOG_TAG, "Creating CDMAPhone");
@@ -135,18 +135,18 @@
         case RILConstants.NETWORK_MODE_CDMA:
         case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
         case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
-            return RILConstants.CDMA_PHONE;
+            return Phone.PHONE_TYPE_CDMA;
 
         case RILConstants.NETWORK_MODE_WCDMA_PREF:
         case RILConstants.NETWORK_MODE_GSM_ONLY:
         case RILConstants.NETWORK_MODE_WCDMA_ONLY:
         case RILConstants.NETWORK_MODE_GSM_UMTS:
-            return RILConstants.GSM_PHONE;
+            return Phone.PHONE_TYPE_GSM;
 
         case RILConstants.NETWORK_MODE_GLOBAL:
-            return RILConstants.CDMA_PHONE;
+            return Phone.PHONE_TYPE_CDMA;
         default:
-            return RILConstants.GSM_PHONE;
+            return Phone.PHONE_TYPE_GSM;
         }
     }
 
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index c4f663a..b1eaa93 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -191,6 +191,10 @@
         return mActivePhone.getPhoneName();
     }
 
+    public int getPhoneType() {
+        return mActivePhone.getPhoneType();
+    }
+
     public String[] getActiveApnTypes() {
         return mActivePhone.getActiveApnTypes();
     }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index dfc4889..6dcfcd9 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -60,7 +60,6 @@
 import com.android.internal.telephony.PhoneNotifier;
 import com.android.internal.telephony.PhoneProxy;
 import com.android.internal.telephony.PhoneSubInfo;
-import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyProperties;
 
@@ -143,7 +142,7 @@
             boolean unitTestMode) {
         super(notifier, context, ci, unitTestMode);
 
-        mCM.setPhoneType(RILConstants.CDMA_PHONE);
+        mCM.setPhoneType(Phone.PHONE_TYPE_CDMA);
         mCT = new CdmaCallTracker(this);
         mSST = new CdmaServiceStateTracker (this);
         mSMS = new CdmaSMSDispatcher(this);
@@ -171,7 +170,7 @@
 
         //Change the system setting
         SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE,
-                new Integer(RILConstants.CDMA_PHONE).toString());
+                new Integer(Phone.PHONE_TYPE_CDMA).toString());
 
         // This is needed to handle phone process crashes
         String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
@@ -261,23 +260,24 @@
         return mSST.ss;
     }
 
-    public Phone.State
-    getState() {
+    public Phone.State getState() {
         return mCT.state;
     }
 
-    public String
-    getPhoneName() {
+    public String getPhoneName() {
         return "CDMA";
     }
 
+    public int getPhoneType() {
+        return Phone.PHONE_TYPE_CDMA;
+    }
+
     public boolean canTransfer() {
         Log.e(LOG_TAG, "canTransfer: not possible in CDMA");
         return false;
     }
 
-    public CdmaCall
-    getRingingCall() {
+    public CdmaCall getRingingCall() {
         return mCT.ringingCall;
     }
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index 2fc2e13..5614c12 100755
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -66,7 +66,6 @@
 import com.android.internal.telephony.PhoneNotifier;
 import com.android.internal.telephony.PhoneProxy;
 import com.android.internal.telephony.PhoneSubInfo;
-import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.gsm.stk.StkService;
 import com.android.internal.telephony.test.SimulatedRadioControl;
@@ -141,7 +140,7 @@
             mSimulatedRadioControl = (SimulatedRadioControl) ci;
         }
 
-        mCM.setPhoneType(RILConstants.GSM_PHONE);
+        mCM.setPhoneType(Phone.PHONE_TYPE_GSM);
         mCT = new GsmCallTracker(this);
         mSST = new GsmServiceStateTracker (this);
         mSMS = new GsmSMSDispatcher(this);
@@ -201,7 +200,7 @@
 
         //Change the system property
         SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE,
-                new Integer(RILConstants.GSM_PHONE).toString());
+                new Integer(Phone.PHONE_TYPE_GSM).toString());
     }
 
     public void dispose() {
@@ -262,27 +261,27 @@
         return mSST.cellLoc;
     }
 
-    public Phone.State
-    getState() {
+    public Phone.State getState() {
         return mCT.state;
     }
 
-    public String
-    getPhoneName() {
+    public String getPhoneName() {
         return "GSM";
     }
 
+    public int getPhoneType() {
+        return Phone.PHONE_TYPE_GSM;
+    }
+
     public SignalStrength getSignalStrength() {
         return mSST.mSignalStrength;
     }
 
-    public boolean
-    getMessageWaitingIndicator() {
+    public boolean getMessageWaitingIndicator() {
         return mSIMRecords.getVoiceMessageWaiting();
     }
 
-    public boolean
-    getCallForwardingIndicator() {
+    public boolean getCallForwardingIndicator() {
         return mSIMRecords.getVoiceCallForwardingFlag();
     }
 
diff --git a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
index 98d4c25..4a77e19 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
@@ -16,6 +16,8 @@
 
 package com.android.unit_tests;
 
+import android.telephony.TelephonyManager;
+
 import com.android.internal.telephony.GsmAlphabet;
 import com.android.internal.telephony.SmsHeader;
 import com.android.internal.telephony.cdma.SmsMessage;
@@ -820,6 +822,8 @@
 
     @SmallTest
     public void testFragmentText() throws Exception {
+        boolean isCdmaPhone = (TelephonyManager.getDefault().getPhoneType() ==
+                TelephonyManager.PHONE_TYPE_CDMA);
         // Valid 160 character ASCII text.
         String text1 = "123456789012345678901234567890123456789012345678901234567890" +
                 "1234567890123456789012345678901234567890123456789012345678901234567890" +
@@ -828,8 +832,10 @@
         assertEquals(ted.msgCount, 1);
         assertEquals(ted.codeUnitCount, 160);
         assertEquals(ted.codeUnitSize, 1);
-        ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text1);
-        assertEquals(fragments.size(), 1);
+        if (isCdmaPhone) {
+            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text1);
+            assertEquals(fragments.size(), 1);
+        }
         // Valid 160 character GSM text -- the last character is
         // non-ASCII, and so this will currently generate a singleton
         // EMS message, which is not necessarily supported by Verizon.
@@ -840,7 +846,9 @@
         assertEquals(ted.msgCount, 1);
         assertEquals(ted.codeUnitCount, 160);
         assertEquals(ted.codeUnitSize, 1);
-        fragments = android.telephony.SmsMessage.fragmentText(text2);
-        assertEquals(fragments.size(), 1);
+        if (isCdmaPhone) {
+            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text2);
+            assertEquals(fragments.size(), 1);
+        }
     }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 0888fd8..d28a151 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -359,6 +359,7 @@
         try {
             // setup the display Metrics.
             DisplayMetrics metrics = new DisplayMetrics();
+            metrics.densityDpi = density;
             metrics.density = density / (float) DisplayMetrics.DENSITY_DEFAULT;
             metrics.scaledDensity = metrics.density;
             metrics.widthPixels = screenWidth;
@@ -406,7 +407,7 @@
 
             // get the background drawable
             if (windowBackground != null) {
-                Drawable d = ResourceHelper.getDrawable(windowBackground.getValue(),
+                Drawable d = ResourceHelper.getDrawable(windowBackground,
                         context, true /* isFramework */);
                 root.setBackgroundDrawable(d);
             }
@@ -1067,6 +1068,11 @@
             // pass for now.
         }
         
+        @SuppressWarnings("unused")
+        public void closeSystemDialogs(String reason) {
+            // pass for now.
+        }
+        
         public IBinder asBinder() {
             // pass for now.
             return null;
@@ -1125,6 +1131,11 @@
             // pass for now.
         }
 
+        @SuppressWarnings("unused")
+        public void closeSystemDialogs(String reason) {
+            // pass for now.
+        }
+        
         public IBinder asBinder() {
             // pass for now.
             return null;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java
index 2b0100b..1fafef4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java
@@ -124,7 +124,7 @@
         IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
-            return ResourceHelper.getDrawable(value.getValue(), mContext, value.isFramework());
+            return ResourceHelper.getDrawable(value, mContext, value.isFramework());
         }
 
         // id was not found or not resolved. Throw a NotFoundException.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
index 10421de..daba8cfd 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
@@ -659,8 +659,9 @@
             return null;
         }
 
-        String value = mData[index].getValue();
-        if (value == null || BridgeConstants.REFERENCE_NULL.equals(value)) {
+        IResourceValue value = mData[index];
+        String stringValue = value.getValue();
+        if (stringValue == null || BridgeConstants.REFERENCE_NULL.equals(stringValue)) {
             return null;
         }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java
index fbdf8dc..3d0dd73 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java
@@ -16,6 +16,9 @@
 
 package com.android.layoutlib.bridge;
 
+import com.android.layoutlib.api.IDensityBasedResourceValue;
+import com.android.layoutlib.api.IResourceValue;
+import com.android.layoutlib.api.IDensityBasedResourceValue.Density;
 import com.android.ninepatch.NinePatch;
 
 import org.kxml2.io.KXmlParser;
@@ -40,7 +43,7 @@
  * Helper class to provide various convertion method used in handling android resources.
  */
 public final class ResourceHelper {
-    
+
     private final static Pattern sFloatPattern = Pattern.compile("(-?[0-9]+(?:\\.[0-9]+)?)(.*)");
     private final static float[] sFloatOut = new float[1];
 
@@ -59,12 +62,12 @@
             }
 
             value = value.substring(1);
-            
+
             // make sure it's not longer than 32bit
             if (value.length() > 8) {
                 throw new NumberFormatException();
             }
-            
+
             if (value.length() == 3) { // RGB format
                 char[] color = new char[8];
                 color[0] = color[1] = 'F';
@@ -84,7 +87,7 @@
             }
 
             // this is a RRGGBB or AARRGGBB value
-            
+
             // Integer.parseInt will fail to parse strings like "ff191919", so we use
             // a Long, but cast the result back into an int, since we know that we're only
             // dealing with 32 bit values.
@@ -96,28 +99,30 @@
 
     /**
      * Returns a drawable from the given value.
-     * @param value The value. A path to a 9 patch, a bitmap or a xml based drawable,
+     * @param value The value that contains a path to a 9 patch, a bitmap or a xml based drawable,
      * or an hexadecimal color
-     * @param context 
+     * @param context
      * @param isFramework indicates whether the resource is a framework resources.
      * Framework resources are cached, and loaded only once.
      */
-    public static Drawable getDrawable(String value, BridgeContext context, boolean isFramework) {
+    public static Drawable getDrawable(IResourceValue value, BridgeContext context, boolean isFramework) {
         Drawable d = null;
-        
-        String lowerCaseValue = value.toLowerCase();
+
+        String stringValue = value.getValue();
+
+        String lowerCaseValue = stringValue.toLowerCase();
 
         if (lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) {
-            File f = new File(value);
-            if (f.isFile()) {
-                NinePatch ninePatch = Bridge.getCached9Patch(value,
+            File file = new File(stringValue);
+            if (file.isFile()) {
+                NinePatch ninePatch = Bridge.getCached9Patch(stringValue,
                         isFramework ? null : context.getProjectKey());
-                
+
                 if (ninePatch == null) {
                     try {
-                        ninePatch = NinePatch.load(new File(value).toURL(), false /* convert */);
-                        
-                        Bridge.setCached9Patch(value, ninePatch,
+                        ninePatch = NinePatch.load(file.toURL(), false /* convert */);
+
+                        Bridge.setCached9Patch(stringValue, ninePatch,
                                 isFramework ? null : context.getProjectKey());
                     } catch (MalformedURLException e) {
                         // URL is wrong, we'll return null below
@@ -125,23 +130,23 @@
                         // failed to read the file, we'll return null below.
                     }
                 }
-                
+
                 if (ninePatch != null) {
                     return new NinePatchDrawable(ninePatch);
                 }
             }
-            
+
             return null;
         } else if (lowerCaseValue.endsWith(".xml")) {
             // create a blockparser for the file
-            File f = new File(value);
+            File f = new File(stringValue);
             if (f.isFile()) {
                 try {
                     // let the framework inflate the Drawable from the XML file.
                     KXmlParser parser = new KXmlParser();
                     parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
                     parser.setInput(new FileReader(f));
-                    
+
                     d = Drawable.createFromXml(context.getResources(),
                             // FIXME: we need to know if this resource is platform or not
                             new BridgeXmlBlockParser(parser, context, false));
@@ -157,19 +162,43 @@
 
             return null;
         } else {
-            File bmpFile = new File(value);
+            File bmpFile = new File(stringValue);
             if (bmpFile.isFile()) {
                 try {
-                    Bitmap bitmap = Bridge.getCachedBitmap(value,
+                    Bitmap bitmap = Bridge.getCachedBitmap(stringValue,
                             isFramework ? null : context.getProjectKey());
-                    
+
                     if (bitmap == null) {
                         bitmap = new Bitmap(bmpFile);
-                        Bridge.setCachedBitmap(value, bitmap,
+                        try {
+                            bitmap.setDensity(Density.MEDIUM.getValue());
+                        } catch (NoClassDefFoundError error) {
+                            // look like we're running in an older version of ADT that doesn't
+                            // include the new layoutlib_api. Let's just ignore this, the drawing
+                            // will just be wrong.
+                        }
+                        Bridge.setCachedBitmap(stringValue, bitmap,
                                 isFramework ? null : context.getProjectKey());
                     }
-                    
-                    return new BitmapDrawable(bitmap);
+
+                    try {
+                        if (value instanceof IDensityBasedResourceValue) {
+                            Density density = ((IDensityBasedResourceValue)value).getDensity();
+                            if (density != Density.MEDIUM) {
+                                // create a copy of the bitmap
+                                bitmap = Bitmap.createBitmap(bitmap);
+
+                                // apply the density
+                                bitmap.setDensity(density.getValue());
+                            }
+                        }
+                    } catch (NoClassDefFoundError error) {
+                        // look like we're running in an older version of ADT that doesn't include
+                        // the new layoutlib_api. Let's just ignore this, the drawing will just be
+                        // wrong.
+                    }
+
+                    return new BitmapDrawable(context.getResources(), bitmap);
                 } catch (IOException e) {
                     // we'll return null below
                     // TODO: log the error.
@@ -177,7 +206,7 @@
             } else {
                 // attempt to get a color from the value
                 try {
-                    int color = getColor(value);
+                    int color = getColor(stringValue);
                     return new ColorDrawable(color);
                 } catch (NumberFormatException e) {
                     // we'll return null below.
@@ -185,20 +214,20 @@
                 }
             }
         }
-        
+
         return null;
     }
 
-    
+
     // ------- TypedValue stuff
     // This is taken from //device/libs/utils/ResourceTypes.cpp
-    
+
     private static final class UnitEntry {
         String name;
         int type;
         int unit;
         float scale;
-        
+
         UnitEntry(String name, int type, int unit, float scale) {
             this.name = name;
             this.type = type;
@@ -218,7 +247,7 @@
         new UnitEntry("%", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION, 1.0f/100),
         new UnitEntry("%p", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100),
     };
-    
+
     /**
      * Returns the raw value from the given string.
      * This object is only valid until the next call on to {@link ResourceHelper}.
@@ -227,10 +256,10 @@
         if (stringToFloat(s, mValue)) {
             return mValue;
         }
-        
+
         return null;
     }
-    
+
     /**
      * Convert the string into a {@link TypedValue}.
      * @param s
@@ -258,7 +287,7 @@
         if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') {
             return false;
         }
-        
+
         // now look for the string that is after the float...
         Matcher m = sFloatPattern.matcher(s);
         if (m.matches()) {
@@ -272,11 +301,11 @@
                 // this shouldn't happen with the regexp above.
                 return false;
             }
-            
+
             if (end.length() > 0 && end.charAt(0) != ' ') {
                 // Might be a unit...
                 if (parseUnit(end, outValue, sFloatOut)) {
-                     
+
                     f *= sFloatOut[0];
                     boolean neg = f < 0;
                     if (neg) {
@@ -312,17 +341,17 @@
                     if (neg) {
                         mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK;
                     }
-                    outValue.data |= 
+                    outValue.data |=
                         (radix<<TypedValue.COMPLEX_RADIX_SHIFT)
                         | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT);
                     return true;
                 }
                 return false;
             }
-            
+
             // make sure it's only spaces at the end.
             end = end.trim();
-    
+
             if (end.length() == 0) {
                 if (outValue != null) {
                     outValue.type = TypedValue.TYPE_FLOAT;
@@ -334,7 +363,7 @@
 
         return false;
     }
-    
+
     private static boolean parseUnit(String str, TypedValue outValue, float[] outScale) {
         str = str.trim();
 
@@ -343,7 +372,7 @@
                 outValue.type = unit.type;
                 outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT;
                 outScale[0] = unit.scale;
-                
+
                 return true;
             }
         }