summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/keystore/certtool.h89
-rw-r--r--cmds/keystore/common.h60
-rw-r--r--cmds/keystore/keymgmt.c421
-rw-r--r--cmds/keystore/keymgmt.h83
-rw-r--r--cmds/keystore/netkeystore.c429
-rw-r--r--cmds/keystore/netkeystore.h106
-rw-r--r--cmds/keystore/netkeystore_main.c29
-rw-r--r--cmds/keystore/tests/Android.mk28
-rw-r--r--cmds/keystore/tests/netkeystore_test.c287
-rw-r--r--include/ui/SurfaceComposerClient.h4
-rw-r--r--libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp16
-rw-r--r--libs/surfaceflinger/DisplayHardware/DisplayHardware.h2
-rw-r--r--libs/surfaceflinger/Layer.cpp21
-rw-r--r--libs/surfaceflinger/Layer.h2
-rw-r--r--libs/surfaceflinger/LayerBase.cpp176
-rw-r--r--libs/surfaceflinger/LayerBase.h6
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.cpp32
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.h1
-rw-r--r--libs/surfaceflinger/Transform.h8
-rw-r--r--libs/ui/FramebufferNativeWindow.cpp18
-rw-r--r--libs/ui/SurfaceComposerClient.cpp65
-rw-r--r--libs/utils/BackupData.cpp3
-rw-r--r--opengl/libagl/array.cpp4
-rw-r--r--opengl/tests/gl2_basic/gl2_basic.cpp1
-rw-r--r--opengl/tests/gl2_jni/Android.mk53
-rw-r--r--opengl/tests/gl2_jni/AndroidManifest.xml35
-rw-r--r--opengl/tests/gl2_jni/jni/gl_code.cpp165
-rw-r--r--opengl/tests/gl2_jni/res/values/strings.xml29
-rw-r--r--opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIActivity.java46
-rw-r--r--opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNILib.java33
-rw-r--r--opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIView.java134
-rw-r--r--opengl/tests/gl_jni/Android.mk53
-rw-r--r--opengl/tests/gl_jni/AndroidManifest.xml38
-rw-r--r--opengl/tests/gl_jni/jni/gl_code.cpp177
-rw-r--r--opengl/tests/gl_jni/res/values/strings.xml29
-rw-r--r--opengl/tests/gl_jni/src/com/android/gljni/GLJNIActivity.java46
-rw-r--r--opengl/tests/gl_jni/src/com/android/gljni/GLJNILib.java33
-rw-r--r--opengl/tests/gl_jni/src/com/android/gljni/GLJNIView.java84
-rw-r--r--opengl/tests/tritex/Android.mk2
-rw-r--r--opengl/tests/tritex/tritex.cpp (renamed from opengl/tests/tritex/tritex.c)26
40 files changed, 1165 insertions, 1709 deletions
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/SurfaceComposerClient.h b/include/ui/SurfaceComposerClient.h
index 269959c..8701928 100644
--- a/include/ui/SurfaceComposerClient.h
+++ b/include/ui/SurfaceComposerClient.h
@@ -20,6 +20,8 @@
#include <stdint.h>
#include <sys/types.h>
+#include <binder/IBinder.h>
+
#include <utils/SortedVector.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
@@ -106,6 +108,8 @@ public:
static ssize_t getDisplayHeight(DisplayID dpy);
static ssize_t getDisplayOrientation(DisplayID dpy);
+ status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
+ void* cookie = NULL, uint32_t flags = 0);
private:
friend class Surface;
diff --git a/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 @@ void DisplayHardware::init(uint32_t dpy)
if (mNativeWindow->isUpdateOnDemand()) {
- mFlags |= UPDATE_ON_DEMAND;
+ mFlags |= PARTIAL_UPDATES;
}
if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
@@ -174,9 +174,9 @@ void DisplayHardware::init(uint32_t dpy)
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 @@ void DisplayHardware::init(uint32_t dpy)
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 @@ void DisplayHardware::flip(const Region& dirty) const
}
#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 @@ public:
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 @@ Layer::Layer(SurfaceFlinger* flinger, DisplayID display,
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 @@ void Layer::destroy()
mBuffers[i].clear();
mWidth = mHeight = 0;
}
+ mSurface.clear();
}
sp<LayerBaseClient::Surface> Layer::createSurface() const
@@ -98,18 +100,23 @@ sp<LayerBaseClient::Surface> Layer::createSurface() const
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 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
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 @@ void Layer::onDraw(const Region& clip) const
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 @@ public:
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 @@ private:
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 @@ LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
: dpy(display), contentDirty(false),
mFlinger(flinger),
mTransformed(false),
+ mUseLinearFiltering(false),
mOrientation(0),
mTransactionFlags(0),
mPremultipliedAlpha(true),
@@ -208,7 +209,19 @@ uint32_t LayerBase::doTransaction(uint32_t flags)
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 @@ GLuint LayerBase::createTexture() const
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 @@ void LayerBase::clearWithOpenGL(const Region& clip, GLclampx red,
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 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
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 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
}
}
+ 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 }
- };
-
- 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);
- }
-
- 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);
- }
+ 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);
+ }
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glVertexPointer(2, GL_FIXED, 0, mVertices);
- glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+ 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);
+ }
- 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);
- }
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glVertexPointer(2, GL_FIXED, 0, mVertices);
+ glTexCoordPointer(2, GL_FIXED, 0, texCoords);
- 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);
+ 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 @@ void LayerBase::validateTexture(GLint textureName) const
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 @@ public:
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 @@ protected:
// 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 @@ void SurfaceFlinger::handleRepaint()
// 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 @@ void SurfaceFlinger::debugFlashRegions()
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::removeLayer_l(const sp<LayerBase>& layerBase)
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 @@ status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
* 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 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
"+ %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 @@ private:
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 @@ public:
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/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index fc2e2f6..c5e22e5 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -117,15 +117,17 @@ FramebufferNativeWindow::FramebufferNativeWindow()
LOGE_IF(err, "fb buffer 1 allocation failed w=%d, h=%d, err=%s",
fbDev->width, fbDev->height, strerror(-err));
- }
- const_cast<uint32_t&>(android_native_window_t::flags) = fbDev->flags;
- const_cast<float&>(android_native_window_t::xdpi) = fbDev->xdpi;
- const_cast<float&>(android_native_window_t::ydpi) = fbDev->ydpi;
- const_cast<int&>(android_native_window_t::minSwapInterval) =
- fbDev->minSwapInterval;
- const_cast<int&>(android_native_window_t::maxSwapInterval) =
- fbDev->maxSwapInterval;
+ const_cast<uint32_t&>(android_native_window_t::flags) = fbDev->flags;
+ const_cast<float&>(android_native_window_t::xdpi) = fbDev->xdpi;
+ const_cast<float&>(android_native_window_t::ydpi) = fbDev->ydpi;
+ const_cast<int&>(android_native_window_t::minSwapInterval) =
+ fbDev->minSwapInterval;
+ const_cast<int&>(android_native_window_t::maxSwapInterval) =
+ fbDev->maxSwapInterval;
+ } else {
+ LOGE("Couldn't get gralloc module");
+ }
android_native_window_t::setSwapInterval = setSwapInterval;
android_native_window_t::dequeueBuffer = dequeueBuffer;
diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp
index 8401cb6..3baa281 100644
--- a/libs/ui/SurfaceComposerClient.cpp
+++ b/libs/ui/SurfaceComposerClient.cpp
@@ -62,34 +62,42 @@ static SortedVector<sp<SurfaceComposerClient> > gOpenTransactions;
static sp<IMemoryHeap> gServerCblkMemory;
static volatile surface_flinger_cblk_t* gServerCblk;
-const sp<ISurfaceComposer>& _get_surface_manager()
+static sp<ISurfaceComposer> getComposerService()
{
+ sp<ISurfaceComposer> sc;
+ Mutex::Autolock _l(gLock);
if (gSurfaceManager != 0) {
- return gSurfaceManager;
- }
+ sc = gSurfaceManager;
+ } else {
+ // release the lock while we're waiting...
+ gLock.unlock();
+
+ sp<IBinder> binder;
+ sp<IServiceManager> sm = defaultServiceManager();
+ do {
+ binder = sm->getService(String16("SurfaceFlinger"));
+ if (binder == 0) {
+ LOGW("SurfaceFlinger not published, waiting...");
+ usleep(500000); // 0.5 s
+ }
+ } while(binder == 0);
- sp<IBinder> binder;
- sp<IServiceManager> sm = defaultServiceManager();
- do {
- binder = sm->getService(String16("SurfaceFlinger"));
- if (binder == 0) {
- LOGW("SurfaceFlinger not published, waiting...");
- usleep(500000); // 0.5 s
+ // grab the lock again for updating gSurfaceManager
+ gLock.lock();
+ if (gSurfaceManager == 0) {
+ sc = interface_cast<ISurfaceComposer>(binder);
+ gSurfaceManager = sc;
+ } else {
+ sc = gSurfaceManager;
}
- } while(binder == 0);
- sp<ISurfaceComposer> sc(interface_cast<ISurfaceComposer>(binder));
-
- Mutex::Autolock _l(gLock);
- if (gSurfaceManager == 0) {
- gSurfaceManager = sc;
}
- return gSurfaceManager;
+ return sc;
}
static volatile surface_flinger_cblk_t const * get_cblk()
{
if (gServerCblk == 0) {
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
+ sp<ISurfaceComposer> sm(getComposerService());
Mutex::Autolock _l(gLock);
if (gServerCblk == 0) {
gServerCblkMemory = sm->getCblk();
@@ -112,7 +120,7 @@ static inline int compare_type( const layer_state_t& lhs,
SurfaceComposerClient::SurfaceComposerClient()
{
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
+ sp<ISurfaceComposer> sm(getComposerService());
if (sm == 0) {
_init(0, 0);
return;
@@ -133,6 +141,15 @@ SurfaceComposerClient::SurfaceComposerClient(
_init(sm, interface_cast<ISurfaceFlingerClient>(conn));
}
+
+status_t SurfaceComposerClient::linkToComposerDeath(
+ const sp<IBinder::DeathRecipient>& recipient,
+ void* cookie, uint32_t flags)
+{
+ sp<ISurfaceComposer> sm(getComposerService());
+ return sm->asBinder()->linkToDeath(recipient, cookie, flags);
+}
+
void SurfaceComposerClient::_init(
const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
{
@@ -183,7 +200,7 @@ SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
if (client == 0) {
// Need to make a new client.
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
+ sp<ISurfaceComposer> sm(getComposerService());
client = new SurfaceComposerClient(sm, conn);
if (client != 0 && client->initCheck() == NO_ERROR) {
Mutex::Autolock _l(gLock);
@@ -377,7 +394,7 @@ void SurfaceComposerClient::closeGlobalTransaction()
const size_t N = clients.size();
VERBOSE("closeGlobalTransaction (%ld clients)", N);
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
+ sp<ISurfaceComposer> sm(getComposerService());
sm->openGlobalTransaction();
for (size_t i=0; i<N; i++) {
clients[i]->closeTransaction();
@@ -389,20 +406,20 @@ void SurfaceComposerClient::closeGlobalTransaction()
status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
{
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
+ sp<ISurfaceComposer> sm(getComposerService());
return sm->freezeDisplay(dpy, flags);
}
status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
{
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
+ sp<ISurfaceComposer> sm(getComposerService());
return sm->unfreezeDisplay(dpy, flags);
}
int SurfaceComposerClient::setOrientation(DisplayID dpy,
int orientation, uint32_t flags)
{
- const sp<ISurfaceComposer>& sm(_get_surface_manager());
+ sp<ISurfaceComposer> sm(getComposerService());
return sm->setOrientation(dpy, orientation, flags);
}
diff --git a/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 @@ BackupDataReader::Status()
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 @@ void glColorPointer(
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/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index f97d347..ba9a717 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -291,6 +291,7 @@ int main(int argc, char** argv) {
for (;;) {
renderFrame();
eglSwapBuffers(dpy, surface);
+ checkEglError("eglSwapBuffers");
}
return 0;
diff --git a/opengl/tests/gl2_jni/Android.mk b/opengl/tests/gl2_jni/Android.mk
new file mode 100644
index 0000000..ff15814
--- /dev/null
+++ b/opengl/tests/gl2_jni/Android.mk
@@ -0,0 +1,53 @@
+#########################################################################
+# OpenGL ES JNI sample
+# This makefile builds both an activity and a shared library.
+#########################################################################
+ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean
+
+TOP_LOCAL_PATH:= $(call my-dir)
+
+# Build activity
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := user
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := GL2JNI
+
+LOCAL_JNI_SHARED_LIBRARIES := libgl2jni
+
+include $(BUILD_PACKAGE)
+
+#########################################################################
+# Build JNI Shared Library
+#########################################################################
+
+LOCAL_PATH:= $(LOCAL_PATH)/jni
+
+include $(CLEAR_VARS)
+
+# Optional tag would mean it doesn't get installed by default
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS := -Werror
+
+LOCAL_SRC_FILES:= \
+ gl_code.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libEGL \
+ libGLESv2
+
+LOCAL_MODULE := libgl2jni
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif # TARGET_SIMULATOR
diff --git a/opengl/tests/gl2_jni/AndroidManifest.xml b/opengl/tests/gl2_jni/AndroidManifest.xml
new file mode 100644
index 0000000..a72a6a5
--- /dev/null
+++ b/opengl/tests/gl2_jni/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** 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.
+*/
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.gl2jni">
+ <application
+ android:label="@string/gl2jni_activity">
+ <activity android:name="GL2JNIActivity"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+ android:launchMode="singleTask"
+ android:configChanges="orientation|keyboardHidden">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/opengl/tests/gl2_jni/jni/gl_code.cpp b/opengl/tests/gl2_jni/jni/gl_code.cpp
new file mode 100644
index 0000000..146d52a
--- /dev/null
+++ b/opengl/tests/gl2_jni/jni/gl_code.cpp
@@ -0,0 +1,165 @@
+// OpenGL ES 2.0 code
+
+#include <nativehelper/jni.h>
+#define LOG_TAG "GL2JNI gl_code.cpp"
+#include <utils/Log.h>
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+static void printGLString(const char *name, GLenum s) {
+ const char *v = (const char *) glGetString(s);
+ LOGI("GL %s = %s\n", name, v);
+}
+
+static void checkGlError(const char* op) {
+ for (GLint error = glGetError(); error; error
+ = glGetError()) {
+ LOGI("after %s() glError (0x%x)\n", op, error);
+ }
+}
+
+static const char gVertexShader[] = "attribute vec4 vPosition;\n"
+ "void main() {\n"
+ " gl_Position = vPosition;\n"
+ "}\n";
+
+static const char gFragmentShader[] = "precision mediump float;\n"
+ "void main() {\n"
+ " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ "}\n";
+
+GLuint loadShader(GLenum shaderType, const char* pSource) {
+ GLuint shader = glCreateShader(shaderType);
+ if (shader) {
+ glShaderSource(shader, 1, &pSource, NULL);
+ glCompileShader(shader);
+ GLint compiled = 0;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ GLint infoLen = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen) {
+ char* buf = (char*) malloc(infoLen);
+ if (buf) {
+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
+ LOGE("Could not compile shader %d:\n%s\n",
+ shaderType, buf);
+ free(buf);
+ }
+ glDeleteShader(shader);
+ shader = 0;
+ }
+ }
+ }
+ return shader;
+}
+
+GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
+ if (!vertexShader) {
+ return 0;
+ }
+
+ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
+ if (!pixelShader) {
+ return 0;
+ }
+
+ GLuint program = glCreateProgram();
+ if (program) {
+ glAttachShader(program, vertexShader);
+ checkGlError("glAttachShader");
+ glAttachShader(program, pixelShader);
+ checkGlError("glAttachShader");
+ glLinkProgram(program);
+ GLint linkStatus = GL_FALSE;
+ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+ if (linkStatus != GL_TRUE) {
+ GLint bufLength = 0;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+ if (bufLength) {
+ char* buf = (char*) malloc(bufLength);
+ if (buf) {
+ glGetProgramInfoLog(program, bufLength, NULL, buf);
+ LOGE("Could not link program:\n%s\n", buf);
+ free(buf);
+ }
+ }
+ glDeleteProgram(program);
+ program = 0;
+ }
+ }
+ return program;
+}
+
+GLuint gProgram;
+GLuint gvPositionHandle;
+
+bool setupGraphics(int w, int h) {
+ printGLString("Version", GL_VERSION);
+ printGLString("Vendor", GL_VENDOR);
+ printGLString("Renderer", GL_RENDERER);
+ printGLString("Extensions", GL_EXTENSIONS);
+
+ LOGI("setupGraphics(%d, %d)", w, h);
+ gProgram = createProgram(gVertexShader, gFragmentShader);
+ if (!gProgram) {
+ LOGE("Could not create program.");
+ return false;
+ }
+ gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
+ checkGlError("glGetAttribLocation");
+ LOGI("glGetAttribLocation(\"vPosition\") = %d\n",
+ gvPositionHandle);
+
+ glViewport(0, 0, w, h);
+ checkGlError("glViewport");
+ return true;
+}
+
+const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f };
+
+void renderFrame() {
+ static float grey;
+ grey += 0.01f;
+ if (grey > 1.0f) {
+ grey = 0.0f;
+ }
+ glClearColor(grey, grey, grey, 1.0f);
+ checkGlError("glClearColor");
+ glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+ checkGlError("glClear");
+
+ glUseProgram(gProgram);
+ checkGlError("glUseProgram");
+
+ glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
+ checkGlError("glVertexAttribPointer");
+ glEnableVertexAttribArray(gvPositionHandle);
+ checkGlError("glEnableVertexAttribArray");
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ checkGlError("glDrawArrays");
+}
+
+extern "C" {
+ JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height);
+ JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj);
+};
+
+JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height)
+{
+ setupGraphics(width, height);
+}
+
+JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj)
+{
+ renderFrame();
+}
+
diff --git a/opengl/tests/gl2_jni/res/values/strings.xml b/opengl/tests/gl2_jni/res/values/strings.xml
new file mode 100644
index 0000000..e3f7331
--- /dev/null
+++ b/opengl/tests/gl2_jni/res/values/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2006, 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.
+*/
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+ them to be changed based on the locale and options. -->
+
+<resources>
+ <!-- Simple strings. -->
+ <string name="gl2jni_activity">GL2JNI</string>
+
+</resources>
+
diff --git a/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIActivity.java b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIActivity.java
new file mode 100644
index 0000000..c366a2c
--- /dev/null
+++ b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIActivity.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gl2jni;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+
+public class GL2JNIActivity extends Activity {
+
+ GL2JNIView mView;
+
+ @Override protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mView = new GL2JNIView(getApplication());
+ setContentView(mView);
+ }
+
+ @Override protected void onPause() {
+ super.onPause();
+ mView.onPause();
+ }
+
+ @Override protected void onResume() {
+ super.onResume();
+ mView.onResume();
+ }
+}
diff --git a/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNILib.java b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNILib.java
new file mode 100644
index 0000000..040a984
--- /dev/null
+++ b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNILib.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gl2jni;
+
+// Wrapper for native library
+
+public class GL2JNILib {
+
+ static {
+ System.loadLibrary("gl2jni");
+ }
+
+ /**
+ * @param width the current view width
+ * @param height the current view height
+ */
+ public static native void init(int width, int height);
+ public static native void step();
+}
diff --git a/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIView.java b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIView.java
new file mode 100644
index 0000000..baa10af
--- /dev/null
+++ b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIView.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gl2jni;
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.opengles.GL10;
+/**
+ * An implementation of SurfaceView that uses the dedicated surface for
+ * displaying an OpenGL animation. This allows the animation to run in a
+ * separate thread, without requiring that it be driven by the update mechanism
+ * of the view hierarchy.
+ *
+ * The application-specific rendering code is delegated to a GLView.Renderer
+ * instance.
+ */
+class GL2JNIView extends GLSurfaceView {
+ private static String TAG = "GL2JNIView";
+ GL2JNIView(Context context) {
+ super(context);
+ init();
+ }
+
+ public GL2JNIView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ private void init() {
+ setEGLContextFactory(new ContextFactory());
+ // setEGLConfigChooser(new ConfigChooser());
+ setRenderer(new Renderer());
+ }
+
+ private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
+ private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+ public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
+ checkEglError("Before eglCreateContext", egl);
+ int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
+ EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
+ checkEglError("After eglCreateContext", egl);
+ return context;
+ }
+
+ public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
+ egl.eglDestroyContext(display, context);
+ }
+ }
+
+ private static void checkEglError(String prompt, EGL10 egl) {
+ int error;
+ while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
+ Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
+ }
+ }
+
+ private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
+ private static int EGL_OPENGL_ES2_BIT = 4;
+ private static int[] s_configAttribs2 =
+ {
+ EGL10.EGL_DEPTH_SIZE, 16,
+ // EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL10.EGL_NONE
+ };
+ public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
+
+ int[] num_config = new int[1];
+ egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
+
+ int numConfigs = num_config[0];
+
+ if (numConfigs <= 0) {
+ throw new IllegalArgumentException("No configs match configSpec");
+ }
+ EGLConfig[] configs = new EGLConfig[numConfigs];
+ egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
+ return configs[0];
+ }
+ }
+
+ private static class Renderer implements GLSurfaceView.Renderer {
+ public void onDrawFrame(GL10 gl) {
+ GL2JNILib.step();
+ }
+
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ GL2JNILib.init(width, height);
+ }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ // Do nothing.
+ }
+ }
+}
+
diff --git a/opengl/tests/gl_jni/Android.mk b/opengl/tests/gl_jni/Android.mk
new file mode 100644
index 0000000..4029fa1
--- /dev/null
+++ b/opengl/tests/gl_jni/Android.mk
@@ -0,0 +1,53 @@
+#########################################################################
+# OpenGL ES JNI sample
+# This makefile builds both an activity and a shared library.
+#########################################################################
+ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean
+
+TOP_LOCAL_PATH:= $(call my-dir)
+
+# Build activity
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := user
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := GLJNI
+
+LOCAL_JNI_SHARED_LIBRARIES := libgljni
+
+include $(BUILD_PACKAGE)
+
+#########################################################################
+# Build JNI Shared Library
+#########################################################################
+
+LOCAL_PATH:= $(LOCAL_PATH)/jni
+
+include $(CLEAR_VARS)
+
+# Optional tag would mean it doesn't get installed by default
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS := -Werror
+
+LOCAL_SRC_FILES:= \
+ gl_code.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libEGL \
+ libGLESv1_CM
+
+LOCAL_MODULE := libgljni
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif # TARGET_SIMULATOR
diff --git a/opengl/tests/gl_jni/AndroidManifest.xml b/opengl/tests/gl_jni/AndroidManifest.xml
new file mode 100644
index 0000000..64bd6bf
--- /dev/null
+++ b/opengl/tests/gl_jni/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** 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.
+*/
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.gljni">
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <application
+ android:label="@string/gljni_activity">
+ <activity android:name="GLJNIActivity"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+ android:launchMode="singleTask"
+ android:screenOrientation="landscape"
+ android:configChanges="orientation|keyboardHidden">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/opengl/tests/gl_jni/jni/gl_code.cpp b/opengl/tests/gl_jni/jni/gl_code.cpp
new file mode 100644
index 0000000..b85a433
--- /dev/null
+++ b/opengl/tests/gl_jni/jni/gl_code.cpp
@@ -0,0 +1,177 @@
+// OpenGL ES 1.0 code
+
+#include <nativehelper/jni.h>
+#define LOG_TAG "GLJNI gl_code.cpp"
+#include <utils/Log.h>
+#include <GLES/gl.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+GLuint texture;
+
+#define FIXED_ONE 0x10000
+
+static void printGLString(const char *name, GLenum s) {
+ const char *v = (const char *) glGetString(s);
+ LOGI("GL %s = %s\n", name, v);
+}
+
+static void gluLookAt(float eyeX, float eyeY, float eyeZ,
+ float centerX, float centerY, float centerZ, float upX, float upY,
+ float upZ)
+{
+ // See the OpenGL GLUT documentation for gluLookAt for a description
+ // of the algorithm. We implement it in a straightforward way:
+
+ float fx = centerX - eyeX;
+ float fy = centerY - eyeY;
+ float fz = centerZ - eyeZ;
+
+ // Normalize f
+ float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
+ fx *= rlf;
+ fy *= rlf;
+ fz *= rlf;
+
+ // Normalize up
+ float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
+ upX *= rlup;
+ upY *= rlup;
+ upZ *= rlup;
+
+ // compute s = f x up (x means "cross product")
+
+ float sx = fy * upZ - fz * upY;
+ float sy = fz * upX - fx * upZ;
+ float sz = fx * upY - fy * upX;
+
+ // compute u = s x f
+ float ux = sy * fz - sz * fy;
+ float uy = sz * fx - sx * fz;
+ float uz = sx * fy - sy * fx;
+
+ float m[16] ;
+ m[0] = sx;
+ m[1] = ux;
+ m[2] = -fx;
+ m[3] = 0.0f;
+
+ m[4] = sy;
+ m[5] = uy;
+ m[6] = -fy;
+ m[7] = 0.0f;
+
+ m[8] = sz;
+ m[9] = uz;
+ m[10] = -fz;
+ m[11] = 0.0f;
+
+ m[12] = 0.0f;
+ m[13] = 0.0f;
+ m[14] = 0.0f;
+ m[15] = 1.0f;
+
+ glMultMatrixf(m);
+ glTranslatef(-eyeX, -eyeY, -eyeZ);
+}
+
+void init_scene(int width, int height)
+{
+ printGLString("Version", GL_VERSION);
+ printGLString("Vendor", GL_VENDOR);
+ printGLString("Renderer", GL_RENDERER);
+ printGLString("Extensions", GL_EXTENSIONS);
+ glDisable(GL_DITHER);
+ glEnable(GL_CULL_FACE);
+
+
+ float ratio = width / height;
+ glViewport(0, 0, width, height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustumf(-ratio, ratio, -1, 1, 1, 10);
+
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ gluLookAt(
+ 0, 0, 3, // eye
+ 0, 0, 0, // center
+ 0, 1, 0); // up
+
+ glEnable(GL_TEXTURE_2D);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+}
+
+void create_texture()
+{
+ const unsigned int on = 0xff0000ff;
+ const unsigned int off = 0xffffffff;
+ const unsigned int pixels[] =
+ {
+ on, off, on, off, on, off, on, off,
+ off, on, off, on, off, on, off, on,
+ on, off, on, off, on, off, on, off,
+ off, on, off, on, off, on, off, on,
+ on, off, on, off, on, off, on, off,
+ off, on, off, on, off, on, off, on,
+ on, off, on, off, on, off, on, off,
+ off, on, off, on, off, on, off, on,
+ };
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+}
+
+extern "C" {
+ JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_init(JNIEnv * env, jobject obj, jint width, jint height);
+ JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * env, jobject obj);
+};
+
+
+JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_init(JNIEnv * env, jobject obj, jint width, jint height)
+{
+ init_scene(width, height);
+ create_texture();
+}
+
+JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * env, jobject obj)
+{
+ const GLfloat vertices[] = {
+ -1, -1, 0,
+ 1, -1, 0,
+ 1, 1, 0,
+ -1, 1, 0
+ };
+
+ const GLfixed texCoords[] = {
+ 0, 0,
+ FIXED_ONE, 0,
+ FIXED_ONE, FIXED_ONE,
+ 0, FIXED_ONE
+ };
+
+ const GLushort quadIndices[] = { 0, 1, 2, 0, 2, 3 };
+
+ glVertexPointer(3, GL_FLOAT, 0, vertices);
+ glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+
+
+ int nelem = sizeof(quadIndices)/sizeof(quadIndices[0]);
+ static float grey;
+ grey += 0.01f;
+ if (grey > 1.0f) {
+ grey = 0.0f;
+ }
+ glClearColor(grey, grey, grey, 1.0f);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+ glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, quadIndices);
+}
+
diff --git a/opengl/tests/gl_jni/res/values/strings.xml b/opengl/tests/gl_jni/res/values/strings.xml
new file mode 100644
index 0000000..880f5c9
--- /dev/null
+++ b/opengl/tests/gl_jni/res/values/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2006, 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.
+*/
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+ them to be changed based on the locale and options. -->
+
+<resources>
+ <!-- Simple strings. -->
+ <string name="gljni_activity">GLJNI</string>
+
+</resources>
+
diff --git a/opengl/tests/gl_jni/src/com/android/gljni/GLJNIActivity.java b/opengl/tests/gl_jni/src/com/android/gljni/GLJNIActivity.java
new file mode 100644
index 0000000..df1f957
--- /dev/null
+++ b/opengl/tests/gl_jni/src/com/android/gljni/GLJNIActivity.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gljni;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+
+public class GLJNIActivity extends Activity {
+
+ GLJNIView mView;
+
+ @Override protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mView = new GLJNIView(getApplication());
+ setContentView(mView);
+ }
+
+ @Override protected void onPause() {
+ super.onPause();
+ mView.onPause();
+ }
+
+ @Override protected void onResume() {
+ super.onResume();
+ mView.onResume();
+ }
+}
diff --git a/opengl/tests/gl_jni/src/com/android/gljni/GLJNILib.java b/opengl/tests/gl_jni/src/com/android/gljni/GLJNILib.java
new file mode 100644
index 0000000..8662725
--- /dev/null
+++ b/opengl/tests/gl_jni/src/com/android/gljni/GLJNILib.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gljni;
+
+// Wrapper for native library
+
+public class GLJNILib {
+
+ static {
+ System.loadLibrary("gljni");
+ }
+
+ /**
+ * @param width the current view width
+ * @param height the current view height
+ */
+ public static native void init(int width, int height);
+ public static native void step();
+}
diff --git a/opengl/tests/gl_jni/src/com/android/gljni/GLJNIView.java b/opengl/tests/gl_jni/src/com/android/gljni/GLJNIView.java
new file mode 100644
index 0000000..9ea1059
--- /dev/null
+++ b/opengl/tests/gl_jni/src/com/android/gljni/GLJNIView.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gljni;
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+/**
+ * An implementation of SurfaceView that uses the dedicated surface for
+ * displaying an OpenGL animation. This allows the animation to run in a
+ * separate thread, without requiring that it be driven by the update mechanism
+ * of the view hierarchy.
+ *
+ * The application-specific rendering code is delegated to a GLView.Renderer
+ * instance.
+ */
+class GLJNIView extends GLSurfaceView {
+ GLJNIView(Context context) {
+ super(context);
+ init();
+ }
+
+ public GLJNIView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ private void init() {
+ setRenderer(new Renderer());
+ }
+
+ private class Renderer implements GLSurfaceView.Renderer {
+ private static final String TAG = "Renderer";
+ public void onDrawFrame(GL10 gl) {
+ GLJNILib.step();
+ }
+
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ GLJNILib.init(width, height);
+ }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ // Do nothing.
+ }
+ }
+}
+
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 @@ LOCAL_PATH:= $(call my-dir)
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
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 @@ int init_gl_surface(void)
EGLConfig myConfig = {0};
EGLint attrib[] =
{
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT|EGL_WINDOW_BIT,
EGL_DEPTH_SIZE, 16,
EGL_NONE
};
@@ -132,15 +139,12 @@ int init_gl_surface(void)
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 @@ void render(int quads)
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 @@ void render(int quads)
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);