Merge change 25465 into eclair

* changes:
  Reset typeface when changing from visible password inputType
diff --git a/cmds/keystore/Android.mk b/cmds/keystore/Android.mk
index 8804636..15a199f 100644
--- a/cmds/keystore/Android.mk
+++ b/cmds/keystore/Android.mk
@@ -1,22 +1,36 @@
+#
+# 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.
+#
+
 ifneq ($(TARGET_SIMULATOR),true)
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    netkeystore.c netkeystore_main.c keymgmt.c
-
-LOCAL_C_INCLUDES := \
-    $(call include-path-for, system-core)/cutils \
-    external/openssl/include
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils libssl
-
-LOCAL_STATIC_LIBRARIES :=
-
+LOCAL_SRC_FILES := keystore.c
+LOCAL_C_INCLUDES := external/openssl/include
+LOCAL_SHARED_LIBRARIES := libcutils libcrypto
 LOCAL_MODULE:= keystore
-
 include $(BUILD_EXECUTABLE)
 
-endif # !simulator))
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := keystore_cli.c
+LOCAL_C_INCLUDES := external/openssl/include
+LOCAL_SHARED_LIBRARIES := libcutils libcrypto
+LOCAL_MODULE:= keystore_cli
+LOCAL_MODULE_TAGS := debug
+include $(BUILD_EXECUTABLE)
+
+endif
diff --git a/cmds/keystore/keystore.c b/cmds/keystore/keystore.c
index 2bcba97..ba74c78 100644
--- a/cmds/keystore/keystore.c
+++ b/cmds/keystore/keystore.c
@@ -125,6 +125,12 @@
     return length;
 }
 
+static int recv_end_of_file()
+{
+    uint8_t byte;
+    return recv(the_socket, &byte, 1, 0) == 0;
+}
+
 static void send_code(int8_t code)
 {
     send(the_socket, &code, 1, 0);
@@ -217,8 +223,10 @@
 /* Here are the actions. Each of them is a function without arguments. All
  * information is defined in global variables, which are set properly before
  * performing an action. The number of parameters required by each action is
- * fixed and defined in a table. Note that the lengths of parameters are checked
- * when they are received, so boundary checks on parameters are omitted. */
+ * fixed and defined in a table. If the return value of an action is positive,
+ * it will be treated as a response code and transmitted to the client. Note
+ * that the lengths of parameters are checked when they are received, so
+ * boundary checks on parameters are omitted. */
 
 #define MAX_PARAM   2
 #define MAX_RETRY   4
@@ -283,7 +291,7 @@
     return NO_ERROR;
 }
 
-static int8_t scan()
+static int8_t saw()
 {
     DIR *dir = opendir(".");
     struct dirent *file;
@@ -321,12 +329,10 @@
         return SYSTEM_ERROR;
     }
     while ((file = readdir(dir)) != NULL) {
-        if (strcmp(".", file->d_name) || strcmp("..", file->d_name)) {
-            unlink(file->d_name);
-        }
+        unlink(file->d_name);
     }
     closedir(dir);
-    return UNINITIALIZED;
+    return NO_ERROR;
 }
 
 #define MASTER_KEY_FILE ".masterkey"
@@ -358,7 +364,8 @@
         }
         if (n != NO_ERROR || blob.length != MASTER_KEY_SIZE) {
             if (retry <= 0) {
-                return reset();
+                reset();
+                return UNINITIALIZED;
             }
             return WRONG_PASSWORD + --retry;
         }
@@ -387,7 +394,7 @@
     memset(&encryption_key, 0, sizeof(encryption_key));
     memset(&decryption_key, 0, sizeof(decryption_key));
     state = LOCKED;
-    return LOCKED;
+    return NO_ERROR;
 }
 
 static int8_t unlock()
@@ -404,7 +411,7 @@
     INSERT   =   4,
     DELETE   =   8,
     EXIST    =  16,
-    SCAN     =  32,
+    SAW      =  32,
     RESET    =  64,
     PASSWORD = 128,
     LOCK     = 256,
@@ -421,9 +428,9 @@
     {test,     't', 0,        TEST,     {0}},
     {get,      'g', NO_ERROR, GET,      {KEY_SIZE}},
     {insert,   'i', NO_ERROR, INSERT,   {KEY_SIZE, VALUE_SIZE}},
-    {delete,   'd', NO_ERROR, DELETE,   {KEY_SIZE}},
-    {exist,    'e', NO_ERROR, EXIST,    {KEY_SIZE}},
-    {scan,     's', NO_ERROR, SCAN,     {KEY_SIZE}},
+    {delete,   'd', 0,        DELETE,   {KEY_SIZE}},
+    {exist,    'e', 0,        EXIST,    {KEY_SIZE}},
+    {saw,      's', 0,        SAW,      {KEY_SIZE}},
     {reset,    'r', 0,        RESET,    {0}},
     {password, 'p', 0,        PASSWORD, {PASSWORD_SIZE, PASSWORD_SIZE}},
     {lock,     'l', NO_ERROR, LOCK,     {0}},
@@ -439,7 +446,7 @@
     {AID_SYSTEM,   0,          ~GET},
     {AID_VPN,      AID_SYSTEM, GET},
     {AID_WIFI,     AID_SYSTEM, GET},
-    {0,            0,          TEST | GET | INSERT | DELETE | EXIST | SCAN},
+    {0,            0,          TEST | GET | INSERT | DELETE | EXIST | SAW},
 };
 
 static int8_t process(int8_t code) {
@@ -471,6 +478,9 @@
             return PROTOCOL_ERROR;
         }
     }
+    if (!recv_end_of_file()) {
+        return PROTOCOL_ERROR;
+    }
     return action->run();
 }
 
diff --git a/cmds/keystore/keystore_cli.c b/cmds/keystore/keystore_cli.c
index b0b76ff..e8afb5a 100644
--- a/cmds/keystore/keystore_cli.c
+++ b/cmds/keystore/keystore_cli.c
@@ -53,8 +53,8 @@
         return 0;
     }
 
-    sock = socket_local_client("keystore",
-            ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
+    sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED,
+                               SOCK_STREAM);
     if (sock == -1) {
         puts("Failed to connect");
         return 1;
diff --git a/cmds/keystore/keystore_get.h b/cmds/keystore/keystore_get.h
index 7665e81..0e7e1ae 100644
--- a/cmds/keystore/keystore_get.h
+++ b/cmds/keystore/keystore_get.h
@@ -1,53 +1,69 @@
 /*
-**
-** 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.
-*/
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 #ifndef __KEYSTORE_GET_H__
 #define __KEYSTORE_GET_H__
 
 #include <stdio.h>
-#include <stdlib.h>
+#include <stdint.h>
 #include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 
-#include "certtool.h"
+#include <cutils/sockets.h>
 
-/* This function is provided to native components to get values from keystore.
- * Users are required to link against libcutils. If something goes wrong, NULL
- * is returned. Otherwise it returns the value in dynamically allocated memory
- * and sets the size if the pointer is not NULL. One can release the memory by
- * calling free(). */
-static char *keystore_get(const char *key, int *size)
+#define KEYSTORE_MESSAGE_SIZE 65535
+
+/* This function is provided for native components to get values from keystore.
+ * Users are required to link against libcutils. The lengths of keys and values
+ * are limited to KEYSTORE_MESSAGE_SIZE. This function returns the length of
+ * the requested value or -1 if something goes wrong. */
+static int keystore_get(const char *key, char *value)
 {
-    char buffer[MAX_KEY_VALUE_LENGTH];
-    char *value;
-    int length;
+    int length = strlen(key);
+    uint8_t bytes[2] = {length >> 8, length};
+    uint8_t code = 'g';
+    int sock;
 
-    if (get_cert(key, (unsigned char *)buffer, &length) != 0) {
-        return NULL;
+    if (length > KEYSTORE_MESSAGE_SIZE) {
+        return -1;
     }
-    value = malloc(length + 1);
-    if (!value) {
-        return NULL;
+    sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED,
+                               SOCK_STREAM);
+    if (sock == -1) {
+        return -1;
     }
-    memcpy(value, buffer, length);
-    value[length] = 0;
-    if (size) {
-        *size = length;
+    if (send(sock, &code, 1, 0) == 1 && send(sock, bytes, 2, 0) == 2 &&
+        send(sock, key, length, 0) == length && shutdown(sock, SHUT_WR) == 0 &&
+        recv(sock, &code, 1, 0) == 1 && code == /* NO_ERROR */ 1 &&
+        recv(sock, &bytes[0], 1, 0) == 1 && recv(sock, &bytes[1], 1, 0) == 1) {
+        int offset = 0;
+        length = bytes[0] << 8 | bytes[1];
+        while (offset < length) {
+            int n = recv(sock, &value[offset], length - offset, 0);
+            if (n <= 0) {
+                length = -1;
+                break;
+            }
+            offset += n;
+        }
     }
-    return value;
+    close(sock);
+    return length;
 }
 
 #endif
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index e534447..6500791 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1227,44 +1227,46 @@
             enabledTracks = prepareTracks_l(activeTracks, &tracksToRemove);
        }
 
-
-        // output audio to hardware
-        if (mSuspended) {
-            usleep(kMaxBufferRecoveryInUsecs);
+        if (LIKELY(enabledTracks)) {
+            // mix buffers...
+            mAudioMixer->process(curBuf);
+            sleepTime = 0;
+            standbyTime = systemTime() + kStandbyTimeInNsecs;
         } else {
-            if (LIKELY(enabledTracks)) {
-                // mix buffers...
-                mAudioMixer->process(curBuf);
+            sleepTime += kBufferRecoveryInUsecs;
+            if (sleepTime > kMaxBufferRecoveryInUsecs) {
+                sleepTime = kMaxBufferRecoveryInUsecs;
+            }
+            // There was nothing to mix this round, which means all
+            // active tracks were late. Sleep a little bit to give
+            // them another chance. If we're too late, write 0s to audio
+            // hardware to avoid underrun.
+            if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs) {
+                memset (curBuf, 0, mixBufferSize);
                 sleepTime = 0;
-                standbyTime = systemTime() + kStandbyTimeInNsecs;
-            } else {
-                sleepTime += kBufferRecoveryInUsecs;
-                // There was nothing to mix this round, which means all
-                // active tracks were late. Sleep a little bit to give
-                // them another chance. If we're too late, write 0s to audio
-                // hardware to avoid underrun.
-                if (mBytesWritten == 0 || sleepTime < kMaxBufferRecoveryInUsecs) {
-                    usleep(kBufferRecoveryInUsecs);
-                } else {
-                    memset (curBuf, 0, mixBufferSize);
-                    sleepTime = 0;
-                }
             }
-            // sleepTime == 0 means PCM data were written to mMixBuffer[]
-            if (sleepTime == 0) {
-                mLastWriteTime = systemTime();
-                mInWrite = true;
-                int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize);
-                if (bytesWritten > 0) mBytesWritten += bytesWritten;
-                mNumWrites++;
-                mInWrite = false;
-                mStandby = false;
-                nsecs_t delta = systemTime() - mLastWriteTime;
-                if (delta > maxPeriod) {
-                    LOGW("write blocked for %llu msecs", ns2ms(delta));
-                    mNumDelayedWrites++;
-                }
+        }
+
+        if (mSuspended) {
+            sleepTime = kMaxBufferRecoveryInUsecs;
+        }
+        // sleepTime == 0 means we must write to audio hardware
+        if (sleepTime == 0) {
+            mLastWriteTime = systemTime();
+            mInWrite = true;
+            LOGV("mOutput->write() thread %p frames %d", this, mFrameCount);
+            int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize);
+            if (bytesWritten > 0) mBytesWritten += bytesWritten;
+            mNumWrites++;
+            mInWrite = false;
+            mStandby = false;
+            nsecs_t delta = systemTime() - mLastWriteTime;
+            if (delta > maxPeriod) {
+                LOGW("write blocked for %llu msecs, thread %p", ns2ms(delta), this);
+                mNumDelayedWrites++;
             }
+        } else {
+            usleep(sleepTime);
         }
 
         // finally let go of all our tracks, without the lock held
@@ -1718,50 +1720,55 @@
             }
        }
 
-        // output audio to hardware
-        if (mSuspended) {
-            usleep(kMaxBufferRecoveryInUsecs);
+        if (activeTrack != 0) {
+            AudioBufferProvider::Buffer buffer;
+            size_t frameCount = mFrameCount;
+            curBuf = (int8_t *)mMixBuffer;
+            // output audio to hardware
+            while(frameCount) {
+                buffer.frameCount = frameCount;
+                activeTrack->getNextBuffer(&buffer);
+                if (UNLIKELY(buffer.raw == 0)) {
+                    memset(curBuf, 0, frameCount * mFrameSize);
+                    break;
+                }
+                memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
+                frameCount -= buffer.frameCount;
+                curBuf += buffer.frameCount * mFrameSize;
+                activeTrack->releaseBuffer(&buffer);
+            }
+            sleepTime = 0;
+            standbyTime = systemTime() + kStandbyTimeInNsecs;
         } else {
-            if (activeTrack != 0) {
-                AudioBufferProvider::Buffer buffer;
-                size_t frameCount = mFrameCount;
-                curBuf = (int8_t *)mMixBuffer;
-                // output audio to hardware
-                while(frameCount) {
-                    buffer.frameCount = frameCount;
-                    activeTrack->getNextBuffer(&buffer);
-                    if (UNLIKELY(buffer.raw == 0)) {
-                        memset(curBuf, 0, frameCount * mFrameSize);
-                        break;
-                    }
-                    memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
-                    frameCount -= buffer.frameCount;
-                    curBuf += buffer.frameCount * mFrameSize;
-                    activeTrack->releaseBuffer(&buffer);
-                }
+            sleepTime += kBufferRecoveryInUsecs;
+            if (sleepTime > kMaxBufferRecoveryInUsecs) {
+                sleepTime = kMaxBufferRecoveryInUsecs;
+            }
+            // There was nothing to mix this round, which means all
+            // active tracks were late. Sleep a little bit to give
+            // them another chance. If we're too late, write 0s to audio
+            // hardware to avoid underrun.
+            if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs &&
+                AudioSystem::isLinearPCM(mFormat)) {
+                memset (mMixBuffer, 0, mFrameCount * mFrameSize);
                 sleepTime = 0;
-                standbyTime = systemTime() + kStandbyTimeInNsecs;
-            } else {
-                sleepTime += kBufferRecoveryInUsecs;
-                if (mBytesWritten == 0 || !AudioSystem::isLinearPCM(mFormat) ||
-                    sleepTime < kMaxBufferRecoveryInUsecs) {
-                    usleep(kBufferRecoveryInUsecs);
-                } else {
-                    memset (mMixBuffer, 0, mFrameCount * mFrameSize);
-                    sleepTime = 0;
-                }
             }
+        }
 
-            // sleepTime == 0 means PCM data were written to mMixBuffer[]
-            if (sleepTime == 0) {
-                mLastWriteTime = systemTime();
-                mInWrite = true;
-                int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
-                if (bytesWritten) mBytesWritten += bytesWritten;
-                mNumWrites++;
-                mInWrite = false;
-                mStandby = false;
-            }
+        if (mSuspended) {
+            sleepTime = kMaxBufferRecoveryInUsecs;
+        }
+        // sleepTime == 0 means we must write to audio hardware
+        if (sleepTime == 0) {
+            mLastWriteTime = systemTime();
+            mInWrite = true;
+            int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
+            if (bytesWritten) mBytesWritten += bytesWritten;
+            mNumWrites++;
+            mInWrite = false;
+            mStandby = false;
+        } else {
+            usleep(sleepTime);
         }
 
         // finally let go of removed track, without the lock held
@@ -1913,38 +1920,40 @@
             }
 
             enabledTracks = prepareTracks_l(activeTracks, &tracksToRemove);
-       }
+        }
 
-        bool mustSleep = true;
         if (LIKELY(enabledTracks)) {
             // mix buffers...
             mAudioMixer->process(curBuf);
-            if (!mSuspended) {
-                for (size_t i = 0; i < outputTracks.size(); i++) {
-                    outputTracks[i]->write(curBuf, mFrameCount);
-                    mustSleep = false;
-                }
-                mStandby = false;
-                mBytesWritten += mixBufferSize;
-            }
+            sleepTime = 0;
+            standbyTime = systemTime() + kStandbyTimeInNsecs;
         } else {
-            // flush remaining overflow buffers in output tracks
-            for (size_t i = 0; i < outputTracks.size(); i++) {
-                if (outputTracks[i]->isActive()) {
-                    outputTracks[i]->write(curBuf, 0);
-                    standbyTime = systemTime() + kStandbyTimeInNsecs;
-                    mustSleep = false;
-                }
+            sleepTime += kBufferRecoveryInUsecs;
+            if (sleepTime > kMaxBufferRecoveryInUsecs) {
+                sleepTime = kMaxBufferRecoveryInUsecs;
+            }
+            // There was nothing to mix this round, which means all
+            // active tracks were late. Sleep a little bit to give
+            // them another chance. If we're too late, write 0s to audio
+            // hardware to avoid underrun.
+            if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs) {
+                memset (curBuf, 0, mixBufferSize);
+                sleepTime = 0;
             }
         }
-        if (mustSleep) {
-//            LOGV("threadLoop() sleeping %d", sleepTime);
-            usleep(sleepTime);
-            if (sleepTime < kMaxBufferRecoveryInUsecs) {
-                sleepTime += kBufferRecoveryInUsecs;
+
+        if (mSuspended) {
+            sleepTime = kMaxBufferRecoveryInUsecs;
+        }
+        // sleepTime == 0 means we must write to audio hardware
+        if (sleepTime == 0) {
+            for (size_t i = 0; i < outputTracks.size(); i++) {
+                outputTracks[i]->write(curBuf, mFrameCount);
             }
+            mStandby = false;
+            mBytesWritten += mixBufferSize;
         } else {
-            sleepTime = kBufferRecoveryInUsecs;
+            usleep(sleepTime);
         }
 
         // finally let go of all our tracks, without the lock held
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 8dfc2cf..5ff9284 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -88,7 +88,6 @@
         mBuffers[i].clear();
         mWidth = mHeight = 0;
     }
-    mSurface.clear();
 }
 
 sp<LayerBaseClient::Surface> Layer::createSurface() const
@@ -99,7 +98,8 @@
 status_t Layer::ditch()
 {
     // the layer is not on screen anymore. free as much resources as possible
-    destroy();
+    //destroy();
+    mSurface.clear();
     return NO_ERROR;
 }
 
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index e87b563..831c446 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -1084,9 +1084,12 @@
 
 status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
 {
-    // remove the layer from the main list (through a transaction).
+    // 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).
     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(),
@@ -1359,8 +1362,18 @@
              * to use the purgatory.
              */
             status_t err = flinger->removeLayer_l(l);
-            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
-                    "error removing layer=%p (%s)", l.get(), strerror(-err));
+            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());
+            }
             return true;
         }
     };
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index f207f85..493e777 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -250,7 +250,9 @@
           GraphicPlane&     graphicPlane(int dpy);
 
             void        waitForEvent();
+public:     // hack to work around gcc 4.0.3 bug
             void        signalEvent();
+private:
             void        signalDelayedEvent(nsecs_t delay);
 
             void        handleConsoleEvents();
@@ -312,6 +314,7 @@
     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/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index f80843d..a5a8cc9 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -1740,7 +1740,11 @@
     const int e = Res_GETENTRY(resID);
 
     if (p < 0) {
-        LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+        if (Res_GETPACKAGE(resID)+1 == 0) {
+            LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+        } else {
+            LOGW("Resources don't contain pacakge for resource number 0x%08x", resID);
+        }
         return false;
     }
     if (t < 0) {
@@ -1786,7 +1790,11 @@
     const int e = Res_GETENTRY(resID);
 
     if (p < 0) {
-        LOGW("No package identifier when getting value for resource number 0x%08x", resID);
+        if (Res_GETPACKAGE(resID)+1 == 0) {
+            LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+        } else {
+            LOGW("Resources don't contain pacakge for resource number 0x%08x", resID);
+        }
         return BAD_INDEX;
     }
     if (t < 0) {
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index d51b333..7e7da1b 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -222,19 +222,28 @@
     }
 }
 
-void *Loader::load_driver(const char* driver, gl_hooks_t* hooks, uint32_t mask)
+void *Loader::load_driver(const char* driver_absolute_path,
+        gl_hooks_t* hooks, uint32_t mask)
 {
-    void* dso = dlopen(driver, RTLD_NOW | RTLD_LOCAL);
-    if (dso == 0)
+    if (access(driver_absolute_path, R_OK)) {
+        // this happens often, we don't want to log an error
         return 0;
+    }
 
-    LOGD("loaded %s", driver);
+    void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
+    if (dso == 0) {
+        const char* err = dlerror();
+        LOGE("load_driver(%s): %s", driver_absolute_path, err?err:"unknown");
+        return 0;
+    }
+
+    LOGD("loaded %s", driver_absolute_path);
 
     if (mask & EGL) {
         getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");
 
         LOGE_IF(!getProcAddress, 
-                "can't find eglGetProcAddress() in %s", driver);        
+                "can't find eglGetProcAddress() in %s", driver_absolute_path);
 
         gl_hooks_t::egl_t* egl = &hooks->egl;
         __eglMustCastToProperFunctionPointerType* curr =
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index d4887ba..f97d347 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -21,8 +21,8 @@
 #include <sys/resource.h>
 
 #include <EGL/egl.h>
-#include <GLES/gl.h>
-#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
 
 #include <utils/Timers.h>
 
@@ -31,144 +31,267 @@
 
 using namespace android;
 
-static void printGLString(const char *name, GLenum s)
-{
-     fprintf(stderr, "printGLString %s, %d\n", name, s);
-#if 0 // causes hangs
-     const char *v = (const char *)glGetString(s);
-     int error = glGetError();
-     fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
-         (unsigned int)v);
-     if ((v < (const char*) 0) || (v > (const char*) 0x10000))
-         fprintf(stderr, "GL %s = %s\n", name, v);
-     else
-         fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
-#endif
+static void printGLString(const char *name, GLenum s) {
+    // fprintf(stderr, "printGLString %s, %d\n", name, s);
+    const char *v = (const char *) glGetString(s);
+    // int error = glGetError();
+    // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
+    //        (unsigned int) v);
+    // if ((v < (const char*) 0) || (v > (const char*) 0x10000))
+    //    fprintf(stderr, "GL %s = %s\n", name, v);
+    // else
+    //    fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
+    fprintf(stderr, "GL %s = %s\n", name, v);
 }
 
 static const char* eglErrorToString[] = {
-    "EGL_SUCCESS",      // 0x3000 12288
-    "EGL_NOT_INITIALIZED",
-    "EGL_BAD_ACCESS",   // 0x3002 12290
-    "EGL_BAD_ALLOC",
-    "EGL_BAD_ATTRIBUTE",
-    "EGL_BAD_CONFIG",
-    "EGL_BAD_CONTEXT",  // 0x3006 12294
-    "EGL_BAD_CURRENT_SURFACE",
-    "EGL_BAD_DISPLAY",
-    "EGL_BAD_MATCH",
-    "EGL_BAD_NATIVE_PIXMAP",
-    "EGL_BAD_NATIVE_WINDOW",
-    "EGL_BAD_PARAMETER",  // 0x300c 12300
-    "EGL_BAD_SURFACE"
-};
+        "EGL_SUCCESS", // 0x3000 12288
+        "EGL_NOT_INITIALIZED",
+        "EGL_BAD_ACCESS", // 0x3002 12290
+        "EGL_BAD_ALLOC", "EGL_BAD_ATTRIBUTE",
+        "EGL_BAD_CONFIG",
+        "EGL_BAD_CONTEXT", // 0x3006 12294
+        "EGL_BAD_CURRENT_SURFACE", "EGL_BAD_DISPLAY", "EGL_BAD_MATCH",
+        "EGL_BAD_NATIVE_PIXMAP", "EGL_BAD_NATIVE_WINDOW", "EGL_BAD_PARAMETER", // 0x300c 12300
+        "EGL_BAD_SURFACE" };
 
 static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
     if (returnVal != EGL_TRUE) {
         fprintf(stderr, "%s() returned %d\n", op, returnVal);
     }
 
-    for(EGLint error = eglGetError();
-		error != EGL_SUCCESS;
-	error = eglGetError()) {
+    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+            = eglGetError()) {
         const char* errorString = "unknown";
         if (error >= EGL_SUCCESS && error <= EGL_BAD_SURFACE) {
             errorString = eglErrorToString[error - EGL_SUCCESS];
         }
-        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op,
-            errorString, error);
+        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, errorString,
+                error);
     }
 }
 
-int main(int argc, char** argv)
-{
+static void checkGlError(const char* op) {
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        fprintf(stderr, "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);
+                    fprintf(stderr, "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);
+                    fprintf(stderr, "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) {
+    gProgram = createProgram(gVertexShader, gFragmentShader);
+    if (!gProgram) {
+        return false;
+    }
+    gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
+    checkGlError("glGetAttribLocation");
+    fprintf(stderr, "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() {
+    glClearColor(0.0f, 0.0f, 1.0f, 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");
+}
+
+int main(int argc, char** argv) {
     EGLBoolean returnValue;
     EGLConfig configs[2];
     EGLint config_count;
 
-	EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
-    EGLint s_configAttribs[] = {
-	EGL_BUFFER_SIZE,     EGL_DONT_CARE,
-	EGL_RED_SIZE,        5,
-	EGL_GREEN_SIZE,      6,
-	EGL_BLUE_SIZE,       5,
-	EGL_DEPTH_SIZE,      8,
-	EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-	EGL_NONE
-     };
+    EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+    EGLint s_configAttribs[] = { EGL_BUFFER_SIZE, EGL_DONT_CARE, EGL_RED_SIZE,
+            5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 8,
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE };
 
-     EGLint majorVersion;
-     EGLint minorVersion;
-     EGLContext context;
-     EGLSurface surface;
-     EGLint w, h;
+    EGLint s_configAttribs2[] =
+    {
+            EGL_DEPTH_SIZE,     16,
+            EGL_NONE
+    };
 
-     EGLDisplay dpy;
+    EGLint majorVersion;
+    EGLint minorVersion;
+    EGLContext context;
+    EGLSurface surface;
+    EGLint w, h;
 
-     EGLNativeWindowType window = 0;
-     window = android_createDisplaySurface();
+    EGLDisplay dpy;
 
-     checkEglError("<init>");
-     dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-     checkEglError("eglGetDisplay");
-     if (dpy == EGL_NO_DISPLAY) {
-         printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
-         return 0;
-     }
-     returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
-     checkEglError("eglInitialize", returnValue);
-     fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+    EGLNativeWindowType window = 0;
+    window = android_createDisplaySurface();
 
-     returnValue = eglGetConfigs (dpy, configs, 2, &config_count);
-     checkEglError("eglGetConfigs", returnValue);
-     fprintf(stderr, "Config count: %d\n", config_count);
-     for(int i = 0; i < config_count; i++) {
+    checkEglError("<init>");
+    dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    checkEglError("eglGetDisplay");
+    if (dpy == EGL_NO_DISPLAY) {
+        printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
+        return 0;
+    }
+
+    returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
+    checkEglError("eglInitialize", returnValue);
+    fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+    if (returnValue != EGL_TRUE) {
+        printf("eglInitialize failed\n");
+        return 0;
+    }
+
+    returnValue = eglGetConfigs(dpy, configs, 2, &config_count);
+    checkEglError("eglGetConfigs", returnValue);
+    fprintf(stderr, "Config count: %d\n", config_count);
+    for (int i = 0; i < config_count; i++) {
         fprintf(stderr, "%d: 0x%08x\n", i, (unsigned int) configs[i]);
-     }
+    }
+
 #if 0
-     EGLConfig config;
-     EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
-     checkEglError("EGLUtils::selectConfigForNativeWindow");
+    EGLConfig config;
+    EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
+    checkEglError("EGLUtils::selectConfigForNativeWindow");
 #else
-    int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs, configs, 2, &config_count);
+    int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs2, configs, 2,
+            &config_count);
     checkEglError("eglChooseConfig", chooseConfigResult);
-    if (chooseConfigResult != EGL_TRUE )

-    {

+    if (chooseConfigResult != EGL_TRUE) {
         printf("eglChooseConfig failed\n");
-        return 0;

+        return 0;
     }
 #endif
 
-     surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);
-     checkEglError("eglCreateWindowSurface");
-     if (surface == EGL_NO_SURFACE)
-	 {
-         printf("gelCreateWindowSurface failed.\n");
-         return 0;
-	 }
-     EGLint gl2_0Attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
+    surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);
+    checkEglError("eglCreateWindowSurface");
+    if (surface == EGL_NO_SURFACE) {
+        printf("gelCreateWindowSurface failed.\n");
+        return 0;
+    }
+    EGLint gl2_0Attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
 
-     context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);
-     checkEglError("eglCreateContext");
-	 if (context == EGL_NO_CONTEXT)
-     {
+    context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);
+    checkEglError("eglCreateContext");
+    if (context == EGL_NO_CONTEXT) {
         printf("eglCreateContext failed\n");
         return 0;
-	 }
-     eglMakeCurrent(dpy, surface, surface, context);
-     checkEglError("eglMakeCurrent");
-     eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
-     checkEglError("eglQuerySurface");
-     eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
-     checkEglError("eglQuerySurface");
-     GLint dim = w<h ? w : h;
+    }
+    eglMakeCurrent(dpy, surface, surface, context);
+    checkEglError("eglMakeCurrent");
+    eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+    checkEglError("eglQuerySurface");
+    eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+    checkEglError("eglQuerySurface");
+    GLint dim = w < h ? w : h;
 
-     fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
+    fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
 
-     printGLString("Version", GL_VERSION);
-     printGLString("Vendor", GL_VENDOR);
-     printGLString("Renderer", GL_RENDERER);
-     printGLString("Extensions", GL_EXTENSIONS);
+    printGLString("Version", GL_VERSION);
+    printGLString("Vendor", GL_VENDOR);
+    printGLString("Renderer", GL_RENDERER);
+    printGLString("Extensions", GL_EXTENSIONS);
 
-     return 0;
+    if(!setupGraphics(w, h)) {
+        fprintf(stderr, "Could not set up graphics.\n");
+        return 0;
+    }
+
+    for (;;) {
+        renderFrame();
+        eglSwapBuffers(dpy, surface);
+    }
+
+    return 0;
 }