Merge change 26720 into eclair

* changes:
  Allow us to set the contact uri without setting the fast track's uri
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/include/ui/CameraParameters.h b/include/ui/CameraParameters.h
index 9ca1806..9c3d4f0 100644
--- a/include/ui/CameraParameters.h
+++ b/include/ui/CameraParameters.h
@@ -69,11 +69,203 @@
     void dump() const;
     status_t dump(int fd, const Vector<String16>& args) const;
 
+    // Parameter keys to communicate between camera application and driver.
+    // The access (read/write, read only, or write only) is viewed from the
+    // perspective of applications, not driver.
+
+    // Preview frame size in pixels (width x height).
+    // Example value: "480x320". Read/Write.
+    static const char KEY_PREVIEW_SIZE[];
+    // Supported preview frame sizes in pixels.
+    // Example value: "800x600,480x320". Read only.
+    static const char KEY_SUPPORTED_PREVIEW_SIZES[];
+    // The image format for preview frames.
+    // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read/write.
+    static const char KEY_PREVIEW_FORMAT[];
+    // Supported image formats for preview frames.
+    // Example value: "yuv420sp,yuv422i-yuyv". Read only.
+    static const char KEY_SUPPORTED_PREVIEW_FORMATS[];
+    // Number of preview frames per second.
+    // Example value: "15". Read/write.
+    static const char KEY_PREVIEW_FRAME_RATE[];
+    // Supported number of preview frames per second.
+    // Example value: "24,15,10". Read.
+    static const char KEY_SUPPORTED_PREVIEW_FRAME_RATES[];
+    // The dimensions for captured pictures in pixels (width x height).
+    // Example value: "1024x768". Read/write.
+    static const char KEY_PICTURE_SIZE[];
+    // Supported dimensions for captured pictures in pixels.
+    // Example value: "2048x1536,1024x768". Read only.
+    static const char KEY_SUPPORTED_PICTURE_SIZES[];
+    // The image format for captured pictures.
+    // Example value: "jpeg" or PIXEL_FORMAT_XXX constants. Read/write.
+    static const char KEY_PICTURE_FORMAT[];
+    // Supported image formats for captured pictures.
+    // Example value: "jpeg,rgb565". Read only.
+    static const char KEY_SUPPORTED_PICTURE_FORMATS[];
+    // The width (in pixels) of EXIF thumbnail in Jpeg picture.
+    // Example value: "512". Read/write.
+    static const char KEY_JPEG_THUMBNAIL_WIDTH[];
+    // The height (in pixels) of EXIF thumbnail in Jpeg picture.
+    // Example value: "384". Read/write.
+    static const char KEY_JPEG_THUMBNAIL_HEIGHT[];
+    // Supported EXIF thumbnail sizes (width x height).
+    // Example value: "512x384,320x240". Read only.
+    static const char KEY_SUPPORTED_THUMBNAIL_SIZES[];
+    // The quality of the EXIF thumbnail in Jpeg picture. The range is 1 to 100,
+    // with 100 being the best.
+    // Example value: "90". Read/write.
+    static const char KEY_JPEG_THUMBNAIL_QUALITY[];
+    // Jpeg quality of captured picture. The range is 1 to 100, with 100 being
+    // the best.
+    // Example value: "90". Read/write.
+    static const char KEY_JPEG_QUALITY[];
+    // 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 will be set to
+    // "0". If the user rotates the phone 90 degrees clockwise, the rotation
+    // should be set to "90".
+    // The camera driver can set orientation in the EXIF header without rotating
+    // the picture. Or the driver can rotate the picture and the EXIF thumbnail.
+    // If the Jpeg picture is rotated, the orientation in the EXIF header should
+    // be missing or 1 (row #0 is top and column #0 is left side). The driver
+    // should not set default value for this parameter.
+    // Example value: "0" or "90" or "180" or "270". Write only.
+    static const char KEY_ROTATION[];
+    // GPS latitude coordinate. This will be stored in JPEG EXIF header.
+    // Example value: "25.032146". Write only.
+    static const char KEY_GPS_LATITUDE[];
+    // GPS longitude coordinate. This will be stored in JPEG EXIF header.
+    // Example value: "121.564448". Write only.
+    static const char KEY_GPS_LONGITUDE[];
+    // GPS altitude. This will be stored in JPEG EXIF header.
+    // Example value: "21.0". Write only.
+    static const char KEY_GPS_ALTITUDE[];
+    // GPS timestamp (UTC in seconds since January 1, 1970). This should be
+    // stored in JPEG EXIF header.
+    // Example value: "1251192757". Write only.
+    static const char KEY_GPS_TIMESTAMP[];
+    // Current white balance setting.
+    // Example value: "auto" or WHITE_BALANCE_XXX constants. Read/write.
+    static const char KEY_WHITE_BALANCE[];
+    // Supported white balance settings.
+    // Example value: "auto,incandescent,daylight". Read only.
+    static const char KEY_SUPPORTED_WHITE_BALANCE[];
+    // Current color effect setting.
+    // Example value: "none" or EFFECT_XXX constants. Read/write.
+    static const char KEY_EFFECT[];
+    // Supported color effect settings.
+    // Example value: "none,mono,sepia". Read only.
+    static const char KEY_SUPPORTED_EFFECTS[];
+    // Current antibanding setting.
+    // Example value: "auto" or ANTIBANDING_XXX constants. Read/write.
+    static const char KEY_ANTIBANDING[];
+    // Supported antibanding settings.
+    // Example value: "auto,50hz,60hz,off". Read only.
+    static const char KEY_SUPPORTED_ANTIBANDING[];
+    // Current scene mode.
+    // Example value: "auto" or SCENE_MODE_XXX constants. Read/write.
+    static const char KEY_SCENE_MODE[];
+    // Supported scene mode settings.
+    // Example value: "auto,night,fireworks". Read only.
+    static const char KEY_SUPPORTED_SCENE_MODES[];
+    // Current flash mode.
+    // Example value: "auto" or FLASH_MODE_XXX constants. Read/write.
+    static const char KEY_FLASH_MODE[];
+    // Supported flash modes.
+    // Example value: "auto,on,off". Read only.
+    static const char KEY_SUPPORTED_FLASH_MODES[];
+    // Current focus mode. If the camera does not support auto-focus, the value
+    // should be FOCUS_MODE_FIXED. If the focus mode is not FOCUS_MODE_FIXED or
+    // or FOCUS_MODE_INFINITY, applications should call
+    // CameraHardwareInterface.autoFocus to start the focus.
+    // Example value: "auto" or FOCUS_MODE_XXX constants. Read/write.
+    static const char KEY_FOCUS_MODE[];
+    // Supported focus modes.
+    // Example value: "auto,macro,fixed". Read only.
+    static const char KEY_SUPPORTED_FOCUS_MODES[];
+
+        // Values for white balance settings.
+    static const char WHITE_BALANCE_AUTO[];
+    static const char WHITE_BALANCE_INCANDESCENT[];
+    static const char WHITE_BALANCE_FLUORESCENT[];
+    static const char WHITE_BALANCE_WARM_FLUORESCENT[];
+    static const char WHITE_BALANCE_DAYLIGHT[];
+    static const char WHITE_BALANCE_CLOUDY_DAYLIGHT[];
+    static const char WHITE_BALANCE_TWILIGHT[];
+    static const char WHITE_BALANCE_SHADE[];
+
+    // Values for effect settings.
+    static const char EFFECT_NONE[];
+    static const char EFFECT_MONO[];
+    static const char EFFECT_NEGATIVE[];
+    static const char EFFECT_SOLARIZE[];
+    static const char EFFECT_SEPIA[];
+    static const char EFFECT_POSTERIZE[];
+    static const char EFFECT_WHITEBOARD[];
+    static const char EFFECT_BLACKBOARD[];
+    static const char EFFECT_AQUA[];
+
+    // Values for antibanding settings.
+    static const char ANTIBANDING_AUTO[];
+    static const char ANTIBANDING_50HZ[];
+    static const char ANTIBANDING_60HZ[];
+    static const char ANTIBANDING_OFF[];
+
+    // Values for flash mode settings.
+    // Flash will not be fired.
+    static const char FLASH_MODE_OFF[];
+    // Flash will be fired automatically when required. The timing is decided by
+    // camera driver.
+    static const char FLASH_MODE_AUTO[];
+    // Flash will always be fired. The timing is decided by camera driver.
+    static const char FLASH_MODE_ON[];
+    // Flash will be fired in red-eye reduction mode.
+    static const char FLASH_MODE_RED_EYE[];
+    // Constant emission of light. This can be used for video recording.
+    static const char FLASH_MODE_VIDEO_LIGHT[];
+
+    // Values for scene mode settings.
+    static const char SCENE_MODE_AUTO[];
+    static const char SCENE_MODE_ACTION[];
+    static const char SCENE_MODE_PORTRAIT[];
+    static const char SCENE_MODE_LANDSCAPE[];
+    static const char SCENE_MODE_NIGHT[];
+    static const char SCENE_MODE_NIGHT_PORTRAIT[];
+    static const char SCENE_MODE_THEATRE[];
+    static const char SCENE_MODE_BEACH[];
+    static const char SCENE_MODE_SNOW[];
+    static const char SCENE_MODE_SUNSET[];
+    static const char SCENE_MODE_STEADYPHOTO[];
+    static const char SCENE_MODE_FIREWORKS[];
+    static const char SCENE_MODE_SPORTS[];
+    static const char SCENE_MODE_PARTY[];
+    static const char SCENE_MODE_CANDLELIGHT[];
+
+    // Formats for setPreviewFormat and setPictureFormat.
+    static const char PIXEL_FORMAT_YUV422SP[];
+    static const char PIXEL_FORMAT_YUV420SP[]; // NV21
+    static const char PIXEL_FORMAT_YUV422I[]; // YUY2
+    static const char PIXEL_FORMAT_RGB565[];
+    static const char PIXEL_FORMAT_JPEG[];
+
+    // Values for focus mode settings.
+    // Auto-focus mode.
+    static const char FOCUS_MODE_AUTO[];
+    // Focus is set at infinity. Applications should not call
+    // CameraHardwareInterface.autoFocus in this mode.
+    static const char FOCUS_MODE_INFINITY[];
+    static const char FOCUS_MODE_MACRO[];
+    // Focus is fixed. The camera is always in this mode if the focus is not
+    // adjustable. If the camera has auto-focus, this mode can fix the
+    // focus, which is usually at hyperfocal distance. Applications should
+    // not call CameraHardwareInterface.autoFocus in this mode.
+    static const char FOCUS_MODE_FIXED[];
+
 private:
     DefaultKeyedVector<String8,String8>    mMap;
 };
 
-
 }; // namespace android
 
 #endif
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 7bdf885..8a7abec 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -160,7 +160,7 @@
     
 
     if (mNativeWindow->isUpdateOnDemand()) {
-        mFlags |= UPDATE_ON_DEMAND;
+        mFlags |= PARTIAL_UPDATES;
     }
     
     if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
@@ -174,9 +174,9 @@
 
     surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
 
-    if (mFlags & UPDATE_ON_DEMAND) {
-        // if we have update on demand, we definitely don't need to
-        // preserve the backbuffer, which is usually costly.
+    if (mFlags & PARTIAL_UPDATES) {
+        // if we have partial updates, we definitely don't need to
+        // preserve the backbuffer, which may be costly.
         eglSurfaceAttrib(display, surface,
                 EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
     }
@@ -199,9 +199,9 @@
             mFlags |= SWAP_RECTANGLE;
         }
     }
-    // when we have the choice between UPDATE_ON_DEMAND and SWAP_RECTANGLE
-    // choose UPDATE_ON_DEMAND, which is more efficient
-    if (mFlags & UPDATE_ON_DEMAND)
+    // when we have the choice between PARTIAL_UPDATES and SWAP_RECTANGLE
+    // choose PARTIAL_UPDATES, which should be more efficient
+    if (mFlags & PARTIAL_UPDATES)
         mFlags &= ~SWAP_RECTANGLE;
 #endif
     
@@ -317,7 +317,7 @@
     } 
 #endif
     
-    if (mFlags & UPDATE_ON_DEMAND) {
+    if (mFlags & PARTIAL_UPDATES) {
         mNativeWindow->setUpdateRectangle(dirty.getBounds());
     }
     
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
index b7f1cdb..cb688b7 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -48,7 +48,7 @@
         NPOT_EXTENSION          = 0x00000100,
         DRAW_TEXTURE_EXTENSION  = 0x00000200,
         BUFFER_PRESERVED        = 0x00010000,
-        UPDATE_ON_DEMAND        = 0x00020000,   // video driver feature
+        PARTIAL_UPDATES         = 0x00020000,   // video driver feature
         SLOW_CONFIG             = 0x00040000,   // software
         SWAP_RECTANGLE          = 0x00080000,
     };
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 5ff9284..2894bf0 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();
@@ -210,14 +223,12 @@
             mFrontBufferIndex : 0;
     GLuint textureName = mTextures[index].name;
     if (UNLIKELY(textureName == -1LU)) {
-        //LOGW("Layer %p doesn't have a texture", this);
         // the texture has not been created yet, this Layer has
         // in fact never been drawn into. this happens frequently with
         // SurfaceView.
         clearWithOpenGL(clip);
         return;
     }
-
     drawWithOpenGL(clip, mTextures[index]);
 }
 
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..a351253 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;
 }
 
@@ -355,15 +363,13 @@
 
     Region::const_iterator it = clip.begin();
     Region::const_iterator const end = clip.end();
-    if (it != end) {
-        glEnable(GL_SCISSOR_TEST);
-        glVertexPointer(2, GL_FIXED, 0, mVertices);
-        while (it != end) {
-            const Rect& r = *it++;
-            const GLint sy = fbHeight - (r.top + r.height());
-            glScissor(r.left, sy, r.width(), r.height());
-            glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
-        }
+    glEnable(GL_SCISSOR_TEST);
+    glVertexPointer(2, GL_FIXED, 0, mVertices);
+    while (it != end) {
+        const Rect& r = *it++;
+        const GLint sy = fbHeight - (r.top + r.height());
+        glScissor(r.left, sy, r.width(), r.height());
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
     }
 }
 
@@ -385,14 +391,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 
@@ -427,82 +425,63 @@
         }
     }
 
+    Region::const_iterator it = clip.begin();
+    Region::const_iterator const end = clip.end();
     if (UNLIKELY(transformed()
             || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) 
     {
         //StopWatch watch("GL transformed");
-        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 },
-                    { 0x10000,  0x10000 },
-                    { 0x10000,  0 }
-            };
+        const GLfixed texCoords[4][2] = {
+                { 0,        0 },
+                { 0,        0x10000 },
+                { 0x10000,  0x10000 },
+                { 0x10000,  0 }
+        };
 
-            glMatrixMode(GL_TEXTURE);
-            glLoadIdentity();
-            
-            // the texture's source is rotated
-            if (texture.transform == HAL_TRANSFORM_ROT_90) {
-                // TODO: handle the other orientations
-                glTranslatef(0, 1, 0);
-                glRotatef(-90, 0, 0, 1);
-            }
+        glMatrixMode(GL_TEXTURE);
+        glLoadIdentity();
 
-            if (!(mFlags & (DisplayHardware::NPOT_EXTENSION |
-                            DisplayHardware::DIRECT_TEXTURE))) {
-                // find the smallest power-of-two that will accommodate our surface
-                GLuint tw = 1 << (31 - clz(width));
-                GLuint th = 1 << (31 - clz(height));
-                if (tw < width)  tw <<= 1;
-                if (th < height) th <<= 1;
-                // this divide should be relatively fast because it's
-                // a power-of-two (optimized path in libgcc)
-                GLfloat ws = GLfloat(width) /tw;
-                GLfloat hs = GLfloat(height)/th;
-                glScalef(ws, hs, 1.0f);
-            }
-
-            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-            glVertexPointer(2, GL_FIXED, 0, mVertices);
-            glTexCoordPointer(2, GL_FIXED, 0, texCoords);
-
-            while (it != end) {
-                const Rect& r = *it++;
-                const GLint sy = fbHeight - (r.top + r.height());
-                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);
+        // the texture's source is rotated
+        if (texture.transform == HAL_TRANSFORM_ROT_90) {
+            // TODO: handle the other orientations
+            glTranslatef(0, 1, 0);
+            glRotatef(-90, 0, 0, 1);
         }
+
+        if (!(mFlags & (DisplayHardware::NPOT_EXTENSION |
+                DisplayHardware::DIRECT_TEXTURE))) {
+            // find the smallest power-of-two that will accommodate our surface
+            GLuint tw = 1 << (31 - clz(width));
+            GLuint th = 1 << (31 - clz(height));
+            if (tw < width)  tw <<= 1;
+            if (th < height) th <<= 1;
+            GLfloat ws = GLfloat(width) /tw;
+            GLfloat hs = GLfloat(height)/th;
+            glScalef(ws, hs, 1.0f);
+        }
+
+        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+        glVertexPointer(2, GL_FIXED, 0, mVertices);
+        glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+
+        while (it != end) {
+            const Rect& r = *it++;
+            const GLint sy = fbHeight - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+        }
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     } else {
-        Region::const_iterator it = clip.begin();
-        Region::const_iterator const end = clip.end();
-        if (it != end) {
-            GLint crop[4] = { 0, height, width, -height };
-            glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
-            int x = tx();
-            int y = ty();
-            y = fbHeight - (y + height);
-            while (it != end) {
-                const Rect& r = *it++;
-                const GLint sy = fbHeight - (r.top + r.height());
-                glScissor(r.left, sy, r.width(), r.height());
-                glDrawTexiOES(x, y, 0, width, height);
-            }
+        GLint crop[4] = { 0, height, width, -height };
+        glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
+        int x = tx();
+        int y = ty();
+        y = fbHeight - (y + height);
+        while (it != end) {
+            const Rect& r = *it++;
+            const GLint sy = fbHeight - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glDrawTexiOES(x, y, 0, width, height);
         }
     }
 }
@@ -512,6 +491,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..065425d 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -859,10 +859,10 @@
             // is costly and usually involves copying the whole update back.
         }
     } else {
-        if (flags & DisplayHardware::UPDATE_ON_DEMAND) {
+        if (flags & DisplayHardware::PARTIAL_UPDATES) {
             // We need to redraw the rectangle that will be updated
             // (pushed to the framebuffer).
-            // This is needed because UPDATE_ON_DEMAND only takes one
+            // This is needed because PARTIAL_UPDATES only takes one
             // rectangle instead of a region (see DisplayHardware::flip())
             mDirtyRegion.set(mInvalidRegion.bounds());
         } else {
@@ -920,7 +920,7 @@
 
      if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
              (flags & DisplayHardware::BUFFER_PRESERVED))) {
-         const Region repaint((flags & DisplayHardware::UPDATE_ON_DEMAND) ?
+         const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
                  mDirtyRegion.bounds() : hw.bounds());
          composeSurfaces(repaint);
      }
@@ -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/CameraParameters.cpp b/libs/ui/CameraParameters.cpp
index 6c25836..9200a97 100644
--- a/libs/ui/CameraParameters.cpp
+++ b/libs/ui/CameraParameters.cpp
@@ -2,16 +2,16 @@
 **
 ** Copyright 2008, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** 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 
+**     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 
+** 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.
 */
 
@@ -23,6 +23,103 @@
 #include <ui/CameraParameters.h>
 
 namespace android {
+// Parameter keys to communicate between camera application and driver.
+const char CameraParameters::KEY_PREVIEW_SIZE[] = "preview-size";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES[] = "preview-size-values";
+const char CameraParameters::KEY_PREVIEW_FORMAT[] = "preview-format";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS[] = "preview-format-values";
+const char CameraParameters::KEY_PREVIEW_FRAME_RATE[] = "preview-frame-rate";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES[] = "preview-frame-rate-values";
+const char CameraParameters::KEY_PICTURE_SIZE[] = "picture-size";
+const char CameraParameters::KEY_SUPPORTED_PICTURE_SIZES[] = "picture-size-values";
+const char CameraParameters::KEY_PICTURE_FORMAT[] = "picture-format";
+const char CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS[] = "picture-format-values";
+const char CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH[] = "jpeg-thumbnail-width";
+const char CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT[] = "jpeg-thumbnail-height";
+const char CameraParameters::KEY_SUPPORTED_THUMBNAIL_SIZES[] = "jpeg-thumbnail-size-values";
+const char CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY[] = "jpeg-thumbnail-quality";
+const char CameraParameters::KEY_JPEG_QUALITY[] = "jpeg-quality";
+const char CameraParameters::KEY_ROTATION[] = "rotation";
+const char CameraParameters::KEY_GPS_LATITUDE[] = "gps-latitude";
+const char CameraParameters::KEY_GPS_LONGITUDE[] = "gps-longitude";
+const char CameraParameters::KEY_GPS_ALTITUDE[] = "gps-altitude";
+const char CameraParameters::KEY_GPS_TIMESTAMP[] = "gps-timestamp";
+const char CameraParameters::KEY_WHITE_BALANCE[] = "whitebalance";
+const char CameraParameters::KEY_SUPPORTED_WHITE_BALANCE[] = "whitebalance-values";
+const char CameraParameters::KEY_EFFECT[] = "effect";
+const char CameraParameters::KEY_SUPPORTED_EFFECTS[] = "effect-values";
+const char CameraParameters::KEY_ANTIBANDING[] = "antibanding";
+const char CameraParameters::KEY_SUPPORTED_ANTIBANDING[] = "antibanding-values";
+const char CameraParameters::KEY_SCENE_MODE[] = "scene-mode";
+const char CameraParameters::KEY_SUPPORTED_SCENE_MODES[] = "scene-mode-values";
+const char CameraParameters::KEY_FLASH_MODE[] = "flash-mode";
+const char CameraParameters::KEY_SUPPORTED_FLASH_MODES[] = "flash-mode-values";
+const char CameraParameters::KEY_FOCUS_MODE[] = "focus-mode";
+const char CameraParameters::KEY_SUPPORTED_FOCUS_MODES[] = "focus-mode-values";
+
+// Values for white balance settings.
+const char CameraParameters::WHITE_BALANCE_AUTO[] = "auto";
+const char CameraParameters::WHITE_BALANCE_INCANDESCENT[] = "incandescent";
+const char CameraParameters::WHITE_BALANCE_FLUORESCENT[] = "fluorescent";
+const char CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT[] = "warm-fluorescent";
+const char CameraParameters::WHITE_BALANCE_DAYLIGHT[] = "daylight";
+const char CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT[] = "cloudy-daylight";
+const char CameraParameters::WHITE_BALANCE_TWILIGHT[] = "twilight";
+const char CameraParameters::WHITE_BALANCE_SHADE[] = "shade";
+
+// Values for effect settings.
+const char CameraParameters::EFFECT_NONE[] = "none";
+const char CameraParameters::EFFECT_MONO[] = "mono";
+const char CameraParameters::EFFECT_NEGATIVE[] = "negative";
+const char CameraParameters::EFFECT_SOLARIZE[] = "solarize";
+const char CameraParameters::EFFECT_SEPIA[] = "sepia";
+const char CameraParameters::EFFECT_POSTERIZE[] = "posterize";
+const char CameraParameters::EFFECT_WHITEBOARD[] = "whiteboard";
+const char CameraParameters::EFFECT_BLACKBOARD[] = "blackboard";
+const char CameraParameters::EFFECT_AQUA[] = "aqua";
+
+// Values for antibanding settings.
+const char CameraParameters::ANTIBANDING_AUTO[] = "auto";
+const char CameraParameters::ANTIBANDING_50HZ[] = "50hz";
+const char CameraParameters::ANTIBANDING_60HZ[] = "60hz";
+const char CameraParameters::ANTIBANDING_OFF[] = "off";
+
+// Values for flash mode settings.
+const char CameraParameters::FLASH_MODE_OFF[] = "off";
+const char CameraParameters::FLASH_MODE_AUTO[] = "auto";
+const char CameraParameters::FLASH_MODE_ON[] = "on";
+const char CameraParameters::FLASH_MODE_RED_EYE[] = "red-eye";
+const char CameraParameters::FLASH_MODE_VIDEO_LIGHT[] = "video-light";
+
+// Values for scene mode settings.
+const char CameraParameters::SCENE_MODE_AUTO[] = "auto";
+const char CameraParameters::SCENE_MODE_ACTION[] = "action";
+const char CameraParameters::SCENE_MODE_PORTRAIT[] = "portrait";
+const char CameraParameters::SCENE_MODE_LANDSCAPE[] = "landscape";
+const char CameraParameters::SCENE_MODE_NIGHT[] = "night";
+const char CameraParameters::SCENE_MODE_NIGHT_PORTRAIT[] = "night-portrait";
+const char CameraParameters::SCENE_MODE_THEATRE[] = "theatre";
+const char CameraParameters::SCENE_MODE_BEACH[] = "beach";
+const char CameraParameters::SCENE_MODE_SNOW[] = "snow";
+const char CameraParameters::SCENE_MODE_SUNSET[] = "sunset";
+const char CameraParameters::SCENE_MODE_STEADYPHOTO[] = "steadyphoto";
+const char CameraParameters::SCENE_MODE_FIREWORKS[] = "fireworks";
+const char CameraParameters::SCENE_MODE_SPORTS[] = "sports";
+const char CameraParameters::SCENE_MODE_PARTY[] = "party";
+const char CameraParameters::SCENE_MODE_CANDLELIGHT[] = "candlelight";
+
+// Formats for setPreviewFormat and setPictureFormat.
+const char CameraParameters::PIXEL_FORMAT_YUV422SP[] = "yuv422sp";
+const char CameraParameters::PIXEL_FORMAT_YUV420SP[] = "yuv420sp";
+const char CameraParameters::PIXEL_FORMAT_YUV422I[] = "yuv422i-yuyv";
+const char CameraParameters::PIXEL_FORMAT_RGB565[] = "rgb565";
+const char CameraParameters::PIXEL_FORMAT_JPEG[] = "jpeg";
+
+// Values for focus mode settings.
+const char CameraParameters::FOCUS_MODE_AUTO[] = "auto";
+const char CameraParameters::FOCUS_MODE_INFINITY[] = "infinity";
+const char CameraParameters::FOCUS_MODE_MACRO[] = "macro";
+const char CameraParameters::FOCUS_MODE_FIXED[] = "fixed";
 
 static const char* portrait = "portrait";
 static const char* landscape = "landscape";
@@ -91,7 +188,7 @@
 
 void CameraParameters::set(const char *key, const char *value)
 {
-    // XXX i think i can do this with strspn() 
+    // XXX i think i can do this with strspn()
     if (strchr(key, '=') || strchr(key, ';')) {
         //XXX LOGE("Key \"%s\"contains invalid character (= or ;)", key);
         return;
@@ -150,7 +247,7 @@
 {
     char str[32];
     sprintf(str, "%dx%d", width, height);
-    set("preview-size", str);
+    set(KEY_PREVIEW_SIZE, str);
 }
 
 void CameraParameters::getPreviewSize(int *width, int *height) const
@@ -159,7 +256,7 @@
     *height = -1;
 
     // Get the current string, if it doesn't exist, leave the -1x-1
-    const char *p = get("preview-size");
+    const char *p = get(KEY_PREVIEW_SIZE);
     if (p == 0)
         return;
 
@@ -172,17 +269,17 @@
 
 void CameraParameters::setPreviewFrameRate(int fps)
 {
-    set("preview-frame-rate", fps);
+    set(KEY_PREVIEW_FRAME_RATE, fps);
 }
 
 int CameraParameters::getPreviewFrameRate() const
 {
-    return getInt("preview-frame-rate");
+    return getInt(KEY_PREVIEW_FRAME_RATE);
 }
 
 void CameraParameters::setPreviewFormat(const char *format)
 {
-    set("preview-format", format);
+    set(KEY_PREVIEW_FORMAT, format);
 }
 
 int CameraParameters::getOrientation() const
@@ -196,22 +293,22 @@
 void CameraParameters::setOrientation(int orientation)
 {
     if (orientation == CAMERA_ORIENTATION_PORTRAIT) {
-        set("preview-format", portrait);
+        set("orientation", portrait);
     } else {
-        set("preview-format", landscape);
+        set("orientation", landscape);
     }
 }
 
 const char *CameraParameters::getPreviewFormat() const
 {
-    return get("preview-format");
+    return get(KEY_PREVIEW_FORMAT);
 }
 
 void CameraParameters::setPictureSize(int width, int height)
 {
     char str[32];
     sprintf(str, "%dx%d", width, height);
-    set("picture-size", str);
+    set(KEY_PICTURE_SIZE, str);
 }
 
 void CameraParameters::getPictureSize(int *width, int *height) const
@@ -220,7 +317,7 @@
     *height = -1;
 
     // Get the current string, if it doesn't exist, leave the -1x-1
-    const char *p = get("picture-size");
+    const char *p = get(KEY_PICTURE_SIZE);
     if (p == 0)
         return;
 
@@ -233,12 +330,12 @@
 
 void CameraParameters::setPictureFormat(const char *format)
 {
-    set("picture-format", format);
+    set(KEY_PICTURE_FORMAT, format);
 }
 
 const char *CameraParameters::getPictureFormat() const
 {
-    return get("picture-format");
+    return get(KEY_PICTURE_FORMAT);
 }
 
 void CameraParameters::dump() const
diff --git a/libs/utils/BackupData.cpp b/libs/utils/BackupData.cpp
index 0cef35a..2535094 100644
--- a/libs/utils/BackupData.cpp
+++ b/libs/utils/BackupData.cpp
@@ -196,8 +196,9 @@
                 m_done = true; \
             } else { \
                 m_status = errno; \
+                LOGD("CHECK_SIZE(a=%ld e=%ld) failed at line %d m_status='%s'", \
+                    long(actual), long(expected), __LINE__, strerror(m_status)); \
             } \
-            LOGD("CHECK_SIZE failed with at line %d m_status='%s'", __LINE__, strerror(m_status)); \
             return m_status; \
         } \
     } while(0)
diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp
index f414ee5..4878722 100644
--- a/opengl/libagl/array.cpp
+++ b/opengl/libagl/array.cpp
@@ -1266,9 +1266,7 @@
     GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
 {
     ogles_context_t* c = ogles_context_t::get();
-    // in theory ogles doesn't allow color arrays of size 3
-    // but it is very useful to 'visualize' the normal array.
-    if (size<3 || size>4 || stride<0) {
+    if (size!=4 || stride<0) {
         ogles_error(c, GL_INVALID_VALUE);
         return;
     }
diff --git a/opengl/tests/tritex/Android.mk b/opengl/tests/tritex/Android.mk
index 76fd8dd..6db3f49 100644
--- a/opengl/tests/tritex/Android.mk
+++ b/opengl/tests/tritex/Android.mk
@@ -2,7 +2,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-	tritex.c
+	tritex.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
diff --git a/opengl/tests/tritex/tritex.c b/opengl/tests/tritex/tritex.cpp
similarity index 89%
rename from opengl/tests/tritex/tritex.c
rename to opengl/tests/tritex/tritex.cpp
index 60a7feb..629b53c 100644
--- a/opengl/tests/tritex/tritex.c
+++ b/opengl/tests/tritex/tritex.cpp
@@ -6,10 +6,16 @@
 
 #include <EGL/egl.h>

 #include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/EGLUtils.h>
 
 #include <stdio.h>

 #include <stdlib.h>
 #include <math.h>
+
+using namespace android;
 

 EGLDisplay eglDisplay;

 EGLSurface eglSurface;

@@ -117,6 +123,7 @@
     EGLConfig myConfig = {0};

     EGLint attrib[] =

     {

+            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT|EGL_WINDOW_BIT,
             EGL_DEPTH_SIZE,     16,

             EGL_NONE

     };

@@ -132,15 +139,12 @@
         printf("eglInitialize failed\n");

         return 0;

     }

-

-    if ( eglChooseConfig(eglDisplay, attrib, &myConfig, 1, &numConfigs) != EGL_TRUE )

-    {

-        printf("eglChooseConfig failed\n");

-        return 0;

-    }

+
+    EGLNativeWindowType window = android_createDisplaySurface();

+    EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig);

 

     if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
-            android_createDisplaySurface(), 0)) == EGL_NO_SURFACE )

+            window, 0)) == EGL_NO_SURFACE )

     {

         printf("eglCreateWindowSurface failed\n");

         return 0;

@@ -239,12 +243,12 @@
             0,            FIXED_ONE

     };

 

-    const GLushort template[] = { 0, 1, 2,  0, 2, 3 };
+    const GLushort quadIndices[] = { 0, 1, 2,  0, 2, 3 };
 
 
-    GLushort* indices = (GLushort*)malloc(quads*sizeof(template));
+    GLushort* indices = (GLushort*)malloc(quads*sizeof(quadIndices));
     for (i=0 ; i<quads ; i++)
-        memcpy(indices+(sizeof(template)/sizeof(indices[0]))*i, template, sizeof(template));
+        memcpy(indices+(sizeof(quadIndices)/sizeof(indices[0]))*i, quadIndices, sizeof(quadIndices));
 

     glVertexPointer(3, GL_FLOAT, 0, vertices);

     glTexCoordPointer(2, GL_FIXED, 0, texCoords);
@@ -262,7 +266,7 @@
     for (j=0 ; j<10 ; j++) {
         printf("loop %d / 10 (%d quads / loop)\n", j, quads);
 
-        int nelem = sizeof(template)/sizeof(template[0]);
+        int nelem = sizeof(quadIndices)/sizeof(quadIndices[0]);
         glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
         glDrawElements(GL_TRIANGLES, nelem*quads, GL_UNSIGNED_SHORT, indices);
         eglSwapBuffers(eglDisplay, eglSurface);