Merge change 26819 into eclair

* changes:
  Fixes http://b/2143180 (mdpi sdcard notification icons).
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/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 8dfc2cf..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.
@@ -106,10 +107,16 @@
 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 e87b563..a0b48d4 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -1497,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/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;