diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
new file mode 100644
index 0000000..eb00f8c
--- /dev/null
+++ b/libs/audioflinger/A2dpAudioInterface.cpp
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+#include <math.h>
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "A2dpAudioInterface"
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include "A2dpAudioInterface.h"
+#include "audio/liba2dp.h"
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+A2dpAudioInterface::A2dpAudioInterface() :
+    mOutput(0)
+{
+}
+
+A2dpAudioInterface::~A2dpAudioInterface()
+{
+    delete mOutput;
+}
+
+status_t A2dpAudioInterface::initCheck()
+{
+    return 0;
+}
+
+AudioStreamOut* A2dpAudioInterface::openOutputStream(
+        int format, int channelCount, uint32_t sampleRate, status_t *status)
+{
+    LOGD("A2dpAudioInterface::openOutputStream %d, %d, %d\n", format, channelCount, sampleRate);
+    Mutex::Autolock lock(mLock);
+    status_t err = 0;
+
+    // only one output stream allowed
+    if (mOutput) {
+        if (status)
+            *status = -1;
+        return NULL;
+    }
+
+    // create new output stream
+    A2dpAudioStreamOut* out = new A2dpAudioStreamOut();
+    if ((err = out->set(format, channelCount, sampleRate)) == NO_ERROR) {
+        mOutput = out;
+    } else {
+        delete out;
+    }
+    
+    if (status)
+        *status = err;
+    return mOutput;
+}
+
+AudioStreamIn* A2dpAudioInterface::openInputStream(
+        int format, int channelCount, uint32_t sampleRate, status_t *status,
+        AudioSystem::audio_in_acoustics acoustics)
+{
+    if (status)
+        *status = -1;
+    return NULL;
+}
+
+status_t A2dpAudioInterface::setMicMute(bool state)
+{
+    return 0;
+}
+
+status_t A2dpAudioInterface::getMicMute(bool* state)
+{
+    return 0;
+}
+
+status_t A2dpAudioInterface::setParameter(const char *key, const char *value)
+{
+    LOGD("setParameter %s,%s\n", key, value);
+    
+    if (!key || !value)
+        return -EINVAL;
+    
+    if (strcmp(key, "a2dp_sink_address") == 0) {        
+        return mOutput->setAddress(value);
+    }
+    if (strcmp(key, "bluetooth_enabled") == 0 &&
+        strcmp(value, "false") == 0) {
+        return mOutput->close();
+    }
+
+    return 0;
+}
+
+status_t A2dpAudioInterface::setVoiceVolume(float v)
+{
+    return 0;
+}
+
+status_t A2dpAudioInterface::setMasterVolume(float v)
+{
+    return 0;
+}
+
+status_t A2dpAudioInterface::doRouting()
+{
+    return 0;
+}
+
+status_t A2dpAudioInterface::dump(int fd, const Vector<String16>& args)
+{
+    return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+A2dpAudioInterface::A2dpAudioStreamOut::A2dpAudioStreamOut() :
+    mFd(-1), mStandby(true), mStartCount(0), mRetryCount(0), mData(NULL)
+{
+    // use any address by default
+    strncpy(mA2dpAddress, "00:00:00:00:00:00", sizeof(mA2dpAddress));
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::set(
+        int format, int channels, uint32_t rate)
+{
+    LOGD("A2dpAudioStreamOut::set %d, %d, %d\n", format, channels, rate);
+
+    // fix up defaults
+    if (format == 0) format = AudioSystem::PCM_16_BIT;
+    if (channels == 0) channels = channelCount();
+    if (rate == 0) rate = sampleRate();
+
+    // check values
+    if ((format != AudioSystem::PCM_16_BIT) ||
+            (channels != channelCount()) ||
+            (rate != sampleRate()))
+        return BAD_VALUE;
+
+    return NO_ERROR;
+}
+
+A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut()
+{
+    close();
+}
+
+ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes)
+{    
+    status_t status = NO_INIT;
+    size_t remaining = bytes;
+
+    if (!mData) {
+        status = a2dp_init(44100, 2, &mData);
+        if (status < 0) {
+            LOGE("a2dp_init failed err: %d\n", status);
+            mData = NULL;
+            goto Error;
+        }
+        a2dp_set_sink(mData, mA2dpAddress);
+    }
+    
+    while (remaining > 0) {
+        status = a2dp_write(mData, buffer, remaining);
+        if (status <= 0) {
+            LOGE("a2dp_write failed err: %d\n", status);
+            goto Error;
+        }
+        remaining -= status;
+        buffer = ((char *)buffer) + status;
+    }
+
+    mStandby = false;
+    
+    return bytes;
+
+Error:
+    // Simulate audio output timing in case of error
+    usleep(bytes * 1000000 / frameSize() / sampleRate());
+
+    return status;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
+{
+    int result = 0;
+
+    if (!mStandby) {
+        result = a2dp_stop(mData);
+        if (result == 0)
+            mStandby = true;
+    }
+
+    return result;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::setAddress(const char* address)
+{
+    if (strlen(address) < sizeof(mA2dpAddress))
+        return -EINVAL;
+
+    if (strcmp(address, mA2dpAddress)) {
+        strcpy(mA2dpAddress, address);
+        if (mData)
+            a2dp_set_sink(mData, mA2dpAddress);
+    }
+    
+    return NO_ERROR;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::close()
+{
+    if (mData) {
+        a2dp_cleanup(mData);
+        mData = NULL;
+    }
+    return NO_ERROR;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::dump(int fd, const Vector<String16>& args)
+{
+    return NO_ERROR;
+}
+
+
+}; // namespace android
diff --git a/libs/audioflinger/A2dpAudioInterface.h b/libs/audioflinger/A2dpAudioInterface.h
new file mode 100644
index 0000000..a56e8a0
--- /dev/null
+++ b/libs/audioflinger/A2dpAudioInterface.h
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+#ifndef A2DP_AUDIO_HARDWARE_H
+#define A2DP_AUDIO_HARDWARE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+
+#include <hardware_legacy/AudioHardwareBase.h>
+
+
+namespace android {
+
+class A2dpAudioInterface : public AudioHardwareBase
+{
+    class A2dpAudioStreamOut;
+
+public:
+                        A2dpAudioInterface();
+    virtual             ~A2dpAudioInterface();
+    virtual status_t    initCheck();
+
+    virtual status_t    setVoiceVolume(float volume);
+    virtual status_t    setMasterVolume(float volume);
+
+    // mic mute
+    virtual status_t    setMicMute(bool state);
+    virtual status_t    getMicMute(bool* state);
+
+    // Temporary interface, do not use
+    // TODO: Replace with a more generic key:value get/set mechanism
+    virtual status_t    setParameter(const char *key, const char *value);
+
+    // create I/O streams
+    virtual AudioStreamOut* openOutputStream(
+                                int format=0,
+                                int channelCount=0,
+                                uint32_t sampleRate=0,
+                                status_t *status=0);
+
+    virtual AudioStreamIn* openInputStream(
+                                int format,
+                                int channelCount,
+                                uint32_t sampleRate,
+                                status_t *status,
+                                AudioSystem::audio_in_acoustics acoustics);
+
+protected:
+    virtual status_t    doRouting();
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+private:
+    class A2dpAudioStreamOut : public AudioStreamOut {
+    public:
+                            A2dpAudioStreamOut();
+        virtual             ~A2dpAudioStreamOut();
+                status_t    set(int format,
+                                int channelCount,
+                                uint32_t sampleRate);
+        virtual uint32_t    sampleRate() const { return 44100; }
+        // SBC codec wants a multiple of 512
+        virtual size_t      bufferSize() const { return 512 * 20; }
+        virtual int         channelCount() const { return 2; }
+        virtual int         format() const { return AudioSystem::PCM_16_BIT; }
+        virtual uint32_t    latency() const { return ((1000*bufferSize())/frameSize())/sampleRate() + 200; }
+        virtual status_t    setVolume(float volume) { return INVALID_OPERATION; }
+        virtual ssize_t     write(const void* buffer, size_t bytes);
+                status_t    standby();
+                status_t    close();
+        virtual status_t    dump(int fd, const Vector<String16>& args);
+
+    private:
+        friend class A2dpAudioInterface;
+        status_t            setAddress(const char* address);
+
+    private:
+                int         mFd;
+                bool        mStandby;
+                int         mStartCount;
+                int         mRetryCount;
+                char        mA2dpAddress[20];
+                void*       mData;
+    };
+
+    Mutex                   mLock;
+    A2dpAudioStreamOut*     mOutput;
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // A2DP_AUDIO_HARDWARE_H
diff --git a/libs/audioflinger/Android.mk b/libs/audioflinger/Android.mk
new file mode 100644
index 0000000..50d516b
--- /dev/null
+++ b/libs/audioflinger/Android.mk
@@ -0,0 +1,56 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    AudioHardwareGeneric.cpp \
+    AudioHardwareStub.cpp \
+    AudioDumpInterface.cpp \
+    AudioHardwareInterface.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    libmedia \
+    libhardware_legacy
+
+ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
+  LOCAL_CFLAGS += -DGENERIC_AUDIO
+endif
+
+LOCAL_MODULE:= libaudiointerface
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=               \
+    AudioFlinger.cpp            \
+    AudioMixer.cpp.arm          \
+    AudioResampler.cpp.arm      \
+    AudioResamplerSinc.cpp.arm  \
+    AudioResamplerCubic.cpp.arm
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    libmedia \
+    libhardware_legacy
+
+ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
+  LOCAL_STATIC_LIBRARIES += libaudiointerface
+else
+  LOCAL_SHARED_LIBRARIES += libaudio
+endif
+
+LOCAL_MODULE:= libaudioflinger
+
+ifeq ($(BOARD_HAVE_BLUETOOTH),true)
+  LOCAL_SRC_FILES += A2dpAudioInterface.cpp
+  LOCAL_SHARED_LIBRARIES += liba2dp
+  LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
+  LOCAL_C_INCLUDES += $(call include-path-for, bluez-libs)
+  LOCAL_C_INCLUDES += $(call include-path-for, bluez-utils)
+endif
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/audioflinger/AudioBufferProvider.h b/libs/audioflinger/AudioBufferProvider.h
new file mode 100644
index 0000000..1a467c7
--- /dev/null
+++ b/libs/audioflinger/AudioBufferProvider.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_AUDIO_BUFFER_PROVIDER_H
+#define ANDROID_AUDIO_BUFFER_PROVIDER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Errors.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class AudioBufferProvider
+{
+public:
+
+    struct Buffer {
+        union {
+            void*       raw;
+            short*      i16;
+            int8_t*     i8;
+        };
+        size_t frameCount;
+    };
+    
+    virtual status_t getNextBuffer(Buffer* buffer) = 0;
+    virtual void releaseBuffer(Buffer* buffer) = 0;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_AUDIO_BUFFER_PROVIDER_H
diff --git a/libs/audioflinger/AudioDumpInterface.cpp b/libs/audioflinger/AudioDumpInterface.cpp
new file mode 100644
index 0000000..b4940cb
--- /dev/null
+++ b/libs/audioflinger/AudioDumpInterface.cpp
@@ -0,0 +1,117 @@
+/* //device/servers/AudioFlinger/AudioDumpInterface.cpp
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     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 "AudioFlingerDump"
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Log.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "AudioDumpInterface.h"
+
+namespace android {
+
+bool gFirst = true;       // true if first write after a standby
+
+// ----------------------------------------------------------------------------
+
+AudioDumpInterface::AudioDumpInterface(AudioHardwareInterface* hw)
+{
+    if(hw == 0) {
+        LOGE("Dump construct hw = 0");
+    }
+    mFinalInterface = hw;
+    mStreamOut = 0;
+}
+
+
+AudioDumpInterface::~AudioDumpInterface()
+{
+    if(mFinalInterface) delete mFinalInterface;
+    if(mStreamOut) delete mStreamOut;
+}
+
+
+AudioStreamOut* AudioDumpInterface::openOutputStream(
+        int format, int channelCount, uint32_t sampleRate, status_t *status)
+{
+    AudioStreamOut* outFinal = mFinalInterface->openOutputStream(format, channelCount, sampleRate, status);
+
+    if(outFinal) {
+        mStreamOut =  new AudioStreamOutDump(outFinal);
+        return mStreamOut;
+    } else {
+        LOGE("Dump outFinal=0");
+        return 0;
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+AudioStreamOutDump::AudioStreamOutDump( AudioStreamOut* finalStream)
+{
+    mFinalStream = finalStream;
+    mOutFile = 0;
+}
+
+
+AudioStreamOutDump::~AudioStreamOutDump()
+{
+    Close();
+    delete mFinalStream;
+}
+
+ssize_t AudioStreamOutDump::write(const void* buffer, size_t bytes)
+{
+    ssize_t ret;
+
+    ret = mFinalStream->write(buffer, bytes);
+    if(!mOutFile && gFirst) {
+        gFirst = false;
+        // check if dump file exist
+        mOutFile = fopen(FLINGER_DUMP_NAME, "r");
+        if(mOutFile) {
+            fclose(mOutFile);
+            mOutFile = fopen(FLINGER_DUMP_NAME, "ab");
+        }
+    }
+    if (mOutFile) {
+        fwrite(buffer, bytes, 1, mOutFile);
+    }
+    return ret;
+}
+
+status_t AudioStreamOutDump::standby()
+{
+    Close();
+    gFirst = true;
+    return mFinalStream->standby();
+}
+
+
+void AudioStreamOutDump::Close(void)
+{
+    if(mOutFile) {
+        fclose(mOutFile);
+        mOutFile = 0;
+    }
+}
+
+}; // namespace android
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
new file mode 100644
index 0000000..9a94102
--- /dev/null
+++ b/libs/audioflinger/AudioDumpInterface.h
@@ -0,0 +1,97 @@
+/* //device/servers/AudioFlinger/AudioDumpInterface.h
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     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 ANDROID_AUDIO_DUMP_INTERFACE_H
+#define ANDROID_AUDIO_DUMP_INTERFACE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <hardware_legacy/AudioHardwareBase.h>
+
+namespace android {
+
+#define FLINGER_DUMP_NAME "/data/FlingerOut.pcm" // name of file used for dump
+
+class AudioStreamOutDump : public AudioStreamOut {
+public:
+                        AudioStreamOutDump( AudioStreamOut* FinalStream);
+                        ~AudioStreamOutDump();
+                        virtual ssize_t     write(const void* buffer, size_t bytes);
+
+    virtual uint32_t    sampleRate() const { return mFinalStream->sampleRate(); }
+    virtual size_t      bufferSize() const { return mFinalStream->bufferSize(); }
+    virtual int         channelCount() const { return mFinalStream->channelCount(); }
+    virtual int         format() const { return mFinalStream->format(); }
+    virtual uint32_t    latency() const { return mFinalStream->latency(); }
+    virtual status_t    setVolume(float volume)
+                            { return mFinalStream->setVolume(volume); }
+    virtual status_t    standby();
+    virtual status_t    dump(int fd, const Vector<String16>& args) { return mFinalStream->dump(fd, args); }
+    void                Close(void);
+
+private:
+    AudioStreamOut      *mFinalStream;
+    FILE                *mOutFile;     // output file
+};
+
+
+class AudioDumpInterface : public AudioHardwareBase
+{
+
+public:
+                        AudioDumpInterface(AudioHardwareInterface* hw);
+    virtual AudioStreamOut* openOutputStream(
+                                int format=0,
+                                int channelCount=0,
+                                uint32_t sampleRate=0,
+                                status_t *status=0);
+    virtual             ~AudioDumpInterface();
+
+    virtual status_t    initCheck()
+                            {return mFinalInterface->initCheck();}
+    virtual status_t    setVoiceVolume(float volume)
+                            {return mFinalInterface->setVoiceVolume(volume);}
+    virtual status_t    setMasterVolume(float volume)
+                            {return mFinalInterface->setMasterVolume(volume);}
+
+    // mic mute
+    virtual status_t    setMicMute(bool state)
+                            {return mFinalInterface->setMicMute(state);}
+    virtual status_t    getMicMute(bool* state)
+                            {return mFinalInterface->getMicMute(state);}
+
+    virtual status_t    setParameter(const char* key, const char* value)
+                            {return mFinalInterface->setParameter(key, value);}
+
+    virtual AudioStreamIn* openInputStream( int format, int channelCount, uint32_t sampleRate, status_t *status,
+                                            AudioSystem::audio_in_acoustics acoustics)
+                            {return mFinalInterface->openInputStream( format, channelCount, sampleRate, status, acoustics);}
+
+    virtual status_t    dump(int fd, const Vector<String16>& args) { return mFinalInterface->dumpState(fd, args); }
+
+protected:
+    virtual status_t    doRouting() {return mFinalInterface->setRouting(mMode, mRoutes[mMode]);}
+
+    AudioHardwareInterface  *mFinalInterface;
+    AudioStreamOutDump      *mStreamOut;
+
+};
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_DUMP_INTERFACE_H
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
new file mode 100644
index 0000000..92c40e9
--- /dev/null
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -0,0 +1,2474 @@
+/* //device/include/server/AudioFlinger/AudioFlinger.cpp
+**
+** Copyright 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.
+*/
+
+
+#define LOG_TAG "AudioFlinger"
+//#define LOG_NDEBUG 0
+
+#include <math.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <utils/IServiceManager.h>
+#include <utils/Log.h>
+#include <utils/Parcel.h>
+#include <utils/IPCThreadState.h>
+#include <utils/String16.h>
+#include <utils/threads.h>
+
+#include <cutils/properties.h>
+
+#include <media/AudioTrack.h>
+#include <media/AudioRecord.h>
+
+#include <private/media/AudioTrackShared.h>
+
+#include <hardware_legacy/AudioHardwareInterface.h>
+
+#include "AudioMixer.h"
+#include "AudioFlinger.h"
+
+#ifdef WITH_A2DP
+#include "A2dpAudioInterface.h"
+#endif
+
+// ----------------------------------------------------------------------------
+// the sim build doesn't have gettid
+
+#ifndef HAVE_GETTID
+# define gettid getpid
+#endif
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
+static const unsigned long kBufferRecoveryInUsecs = 2000;
+static const unsigned long kMaxBufferRecoveryInUsecs = 20000;
+static const float MAX_GAIN = 4096.0f;
+
+// retry counts for buffer fill timeout
+// 50 * ~20msecs = 1 second
+static const int8_t kMaxTrackRetries = 50;
+static const int8_t kMaxTrackStartupRetries = 50;
+
+static const int kStartSleepTime = 30000;
+static const int kStopSleepTime = 30000;
+
+// Maximum number of pending buffers allocated by OutputTrack::write()
+static const uint8_t kMaxOutputTrackBuffers = 5;
+
+
+#define AUDIOFLINGER_SECURITY_ENABLED 1
+
+// ----------------------------------------------------------------------------
+
+static bool recordingAllowed() {
+#ifndef HAVE_ANDROID_OS
+    return true;
+#endif
+#if AUDIOFLINGER_SECURITY_ENABLED
+    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
+    bool ok = checkCallingPermission(String16("android.permission.RECORD_AUDIO"));
+    if (!ok) LOGE("Request requires android.permission.RECORD_AUDIO");
+    return ok;
+#else
+    if (!checkCallingPermission(String16("android.permission.RECORD_AUDIO")))
+        LOGW("WARNING: Need to add android.permission.RECORD_AUDIO to manifest");
+    return true;
+#endif
+}
+
+static bool settingsAllowed() {
+#ifndef HAVE_ANDROID_OS
+    return true;
+#endif
+#if AUDIOFLINGER_SECURITY_ENABLED
+    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
+    bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
+    if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
+    return ok;
+#else
+    if (!checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")))
+        LOGW("WARNING: Need to add android.permission.MODIFY_AUDIO_SETTINGS to manifest");
+    return true;
+#endif
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::AudioFlinger()
+    : BnAudioFlinger(),
+        mAudioHardware(0), mA2dpAudioInterface(0),
+        mA2dpEnabled(false), mA2dpEnabledReq(false),
+        mForcedSpeakerCount(0), mForcedRoute(0), mRouteRestoreTime(0), mMusicMuteSaved(false)
+{
+    mHardwareStatus = AUDIO_HW_IDLE;
+    mAudioHardware = AudioHardwareInterface::create();
+    mHardwareStatus = AUDIO_HW_INIT;
+    if (mAudioHardware->initCheck() == NO_ERROR) {
+        // open 16-bit output stream for s/w mixer
+        mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
+        status_t status;
+        AudioStreamOut *hwOutput = mAudioHardware->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
+        mHardwareStatus = AUDIO_HW_IDLE;
+        if (hwOutput) {
+            mHardwareMixerThread = new MixerThread(this, hwOutput, AudioSystem::AUDIO_OUTPUT_HARDWARE);
+        } else {
+            LOGE("Failed to initialize hardware output stream, status: %d", status);
+        }
+        
+#ifdef WITH_A2DP
+        // Create A2DP interface
+        mA2dpAudioInterface = new A2dpAudioInterface();
+        AudioStreamOut *a2dpOutput = mA2dpAudioInterface->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
+        if (a2dpOutput) {
+            mA2dpMixerThread = new MixerThread(this, a2dpOutput, AudioSystem::AUDIO_OUTPUT_A2DP);
+            if (hwOutput) {  
+                uint32_t frameCount = ((a2dpOutput->bufferSize()/a2dpOutput->frameSize()) * hwOutput->sampleRate()) / a2dpOutput->sampleRate();
+                MixerThread::OutputTrack *a2dpOutTrack = new MixerThread::OutputTrack(mA2dpMixerThread,
+                                                            hwOutput->sampleRate(),
+                                                            AudioSystem::PCM_16_BIT,
+                                                            hwOutput->channelCount(),
+                                                            frameCount);
+                mHardwareMixerThread->setOuputTrack(a2dpOutTrack);                
+            }
+        } else {
+            LOGE("Failed to initialize A2DP output stream, status: %d", status);
+        }
+#endif
+ 
+        // FIXME - this should come from settings
+        setRouting(AudioSystem::MODE_NORMAL, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
+        setRouting(AudioSystem::MODE_RINGTONE, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
+        setRouting(AudioSystem::MODE_IN_CALL, AudioSystem::ROUTE_EARPIECE, AudioSystem::ROUTE_ALL);
+        setMode(AudioSystem::MODE_NORMAL);
+
+        setMasterVolume(1.0f);
+        setMasterMute(false);
+
+        // Start record thread
+        mAudioRecordThread = new AudioRecordThread(mAudioHardware);
+        if (mAudioRecordThread != 0) {
+            mAudioRecordThread->run("AudioRecordThread", PRIORITY_URGENT_AUDIO);            
+        }
+     } else {
+        LOGE("Couldn't even initialize the stubbed audio hardware!");
+    }
+}
+
+AudioFlinger::~AudioFlinger()
+{
+    if (mAudioRecordThread != 0) {
+        mAudioRecordThread->exit();
+        mAudioRecordThread.clear();        
+    }
+    mHardwareMixerThread.clear();
+    delete mAudioHardware;
+    // deleting mA2dpAudioInterface also deletes mA2dpOutput;
+#ifdef WITH_A2DP
+    mA2dpMixerThread.clear();
+    delete mA2dpAudioInterface;
+#endif
+}
+
+
+#ifdef WITH_A2DP
+void AudioFlinger::setA2dpEnabled(bool enable)
+{
+    LOGV_IF(enable, "set output to A2DP\n");
+    LOGV_IF(!enable, "set output to hardware audio\n");
+
+    mA2dpEnabledReq = enable;
+    mA2dpMixerThread->wakeUp();
+}
+#endif // WITH_A2DP
+
+bool AudioFlinger::streamForcedToSpeaker(int streamType)
+{
+    // NOTE that streams listed here must not be routed to A2DP by default:
+    // AudioSystem::routedToA2dpOutput(streamType) == false
+    return (streamType == AudioSystem::RING ||
+            streamType == AudioSystem::ALARM ||
+            streamType == AudioSystem::NOTIFICATION);
+}
+
+status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    result.append("Clients:\n");
+    for (size_t i = 0; i < mClients.size(); ++i) {
+        wp<Client> wClient = mClients.valueAt(i);
+        if (wClient != 0) {
+            sp<Client> client = wClient.promote();
+            if (client != 0) {
+                snprintf(buffer, SIZE, "  pid: %d\n", client->pid());
+                result.append(buffer);
+            }
+        }
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+
+status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "Hardware status: %d\n", mHardwareStatus);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "Permission Denial: "
+            "can't dump AudioFlinger from pid=%d, uid=%d\n",
+            IPCThreadState::self()->getCallingPid(),
+            IPCThreadState::self()->getCallingUid());
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
+{
+    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+        dumpPermissionDenial(fd, args);
+    } else {
+        AutoMutex lock(&mLock);
+
+        dumpClients(fd, args);
+        dumpInternals(fd, args);
+        mHardwareMixerThread->dump(fd, args);
+#ifdef WITH_A2DP
+        mA2dpMixerThread->dump(fd, args);
+#endif
+
+        // dump record client
+        if (mAudioRecordThread != 0) mAudioRecordThread->dump(fd, args);
+
+        if (mAudioHardware) {
+            mAudioHardware->dumpState(fd, args);
+        }
+    }
+    return NO_ERROR;
+}
+
+// IAudioFlinger interface
+
+
+sp<IAudioTrack> AudioFlinger::createTrack(
+        pid_t pid,
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int frameCount,
+        uint32_t flags,
+        const sp<IMemory>& sharedBuffer,
+        status_t *status)
+{
+    sp<MixerThread::Track> track;
+    sp<TrackHandle> trackHandle;
+    sp<Client> client;
+    wp<Client> wclient;
+    status_t lStatus;
+
+    if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
+        LOGE("invalid stream type");
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
+
+    {
+        Mutex::Autolock _l(mLock);
+
+        wclient = mClients.valueFor(pid);
+
+        if (wclient != NULL) {
+            client = wclient.promote();
+        } else {
+            client = new Client(this, pid);
+            mClients.add(pid, client);
+        }
+#ifdef WITH_A2DP
+        if (isA2dpEnabled() && AudioSystem::routedToA2dpOutput(streamType)) {
+            track = mA2dpMixerThread->createTrack(client, streamType, sampleRate, format,
+                    channelCount, frameCount, sharedBuffer, &lStatus);            
+        } else 
+#endif
+        {
+            track = mHardwareMixerThread->createTrack(client, streamType, sampleRate, format,
+                    channelCount, frameCount, sharedBuffer, &lStatus);            
+        }
+        if (track != NULL) {
+            trackHandle = new TrackHandle(track);
+            lStatus = NO_ERROR;            
+        }
+    }
+
+Exit:
+    if(status) {
+        *status = lStatus;
+    }
+    return trackHandle;
+}
+
+uint32_t AudioFlinger::sampleRate(int output) const
+{
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->sampleRate();
+     }
+#endif
+     return mHardwareMixerThread->sampleRate();
+}
+
+int AudioFlinger::channelCount(int output) const
+{
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->channelCount();
+     }
+#endif
+     return mHardwareMixerThread->channelCount();
+}
+
+int AudioFlinger::format(int output) const
+{
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->format();
+     }
+#endif
+     return mHardwareMixerThread->format();
+}
+
+size_t AudioFlinger::frameCount(int output) const
+{
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->frameCount();
+     }
+#endif
+     return mHardwareMixerThread->frameCount();
+}
+
+uint32_t AudioFlinger::latency(int output) const
+{
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->latency();
+     }
+#endif
+     return mHardwareMixerThread->latency();
+}
+
+status_t AudioFlinger::setMasterVolume(float value)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    // when hw supports master volume, don't scale in sw mixer
+    AutoMutex lock(mHardwareLock);
+    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+    if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
+        value = 1.0f;
+    }
+    mHardwareStatus = AUDIO_HW_IDLE;
+    mHardwareMixerThread->setMasterVolume(value);
+#ifdef WITH_A2DP
+    mA2dpMixerThread->setMasterVolume(value);
+#endif
+    
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
+{
+    status_t err = NO_ERROR;
+
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    if ((mode < AudioSystem::MODE_CURRENT) || (mode >= AudioSystem::NUM_MODES)) {
+        LOGW("Illegal value: setRouting(%d, %u, %u)", mode, routes, mask);
+        return BAD_VALUE;
+    }
+
+#ifdef WITH_A2DP
+    LOGD("setRouting %d %d %d, tid %d, calling tid %d\n", mode, routes, mask, gettid(), IPCThreadState::self()->getCallingPid());
+    if (mode == AudioSystem::MODE_NORMAL && 
+            (mask & AudioSystem::ROUTE_BLUETOOTH_A2DP)) {
+        AutoMutex lock(&mLock);
+
+        bool enableA2dp = false;
+        if (routes & AudioSystem::ROUTE_BLUETOOTH_A2DP) {
+            enableA2dp = true;
+        }
+        setA2dpEnabled(enableA2dp);
+        LOGV("setOutput done\n");
+    }
+#endif
+
+    // do nothing if only A2DP routing is affected
+    mask &= ~AudioSystem::ROUTE_BLUETOOTH_A2DP;
+    if (mask) {
+        AutoMutex lock(mHardwareLock);
+        mHardwareStatus = AUDIO_HW_GET_ROUTING;
+        uint32_t r;
+        err = mAudioHardware->getRouting(mode, &r);
+        if (err == NO_ERROR) {
+            r = (r & ~mask) | (routes & mask);
+            if (mode == AudioSystem::MODE_NORMAL || 
+                (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
+                mSavedRoute = r;
+                r |= mForcedRoute;
+                LOGV("setRouting mSavedRoute %08x mForcedRoute %08x\n", mSavedRoute, mForcedRoute);
+            }
+            mHardwareStatus = AUDIO_HW_SET_ROUTING;
+            err = mAudioHardware->setRouting(mode, r);
+        }
+        mHardwareStatus = AUDIO_HW_IDLE;
+    }
+    return err;
+}
+
+uint32_t AudioFlinger::getRouting(int mode) const
+{
+    uint32_t routes = 0;
+    if ((mode >= AudioSystem::MODE_CURRENT) && (mode < AudioSystem::NUM_MODES)) {
+        if (mode == AudioSystem::MODE_NORMAL || 
+            (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
+            routes = mSavedRoute;                
+        } else {
+            mHardwareStatus = AUDIO_HW_GET_ROUTING;
+            mAudioHardware->getRouting(mode, &routes);
+            mHardwareStatus = AUDIO_HW_IDLE;
+        }
+    } else {
+        LOGW("Illegal value: getRouting(%d)", mode);
+    }
+    return routes;
+}
+
+status_t AudioFlinger::setMode(int mode)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
+        LOGW("Illegal value: setMode(%d)", mode);
+        return BAD_VALUE;
+    }
+
+    AutoMutex lock(mHardwareLock);
+    mHardwareStatus = AUDIO_HW_SET_MODE;
+    status_t ret = mAudioHardware->setMode(mode);
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return ret;
+}
+
+int AudioFlinger::getMode() const
+{
+    int mode = AudioSystem::MODE_INVALID;
+    mHardwareStatus = AUDIO_HW_SET_MODE;
+    mAudioHardware->getMode(&mode);
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return mode;
+}
+
+status_t AudioFlinger::setMicMute(bool state)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    AutoMutex lock(mHardwareLock);
+    mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
+    status_t ret = mAudioHardware->setMicMute(state);
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return ret;
+}
+
+bool AudioFlinger::getMicMute() const
+{
+    bool state = AudioSystem::MODE_INVALID;
+    mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
+    mAudioHardware->getMicMute(&state);
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return state;
+}
+
+status_t AudioFlinger::setMasterMute(bool muted)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    mHardwareMixerThread->setMasterMute(muted);
+#ifdef WITH_A2DP
+    mA2dpMixerThread->setMasterMute(muted);
+#endif
+    return NO_ERROR;
+}
+
+float AudioFlinger::masterVolume() const
+{
+    return mHardwareMixerThread->masterVolume();
+}
+
+bool AudioFlinger::masterMute() const
+{
+    return mHardwareMixerThread->masterMute();
+}
+
+status_t AudioFlinger::setStreamVolume(int stream, float value)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
+        return BAD_VALUE;
+    }
+
+    mHardwareMixerThread->setStreamVolume(stream, value);
+#ifdef WITH_A2DP
+    mA2dpMixerThread->setStreamVolume(stream, value);
+#endif
+
+    status_t ret = NO_ERROR;
+    if (stream == AudioSystem::VOICE_CALL ||
+        stream == AudioSystem::BLUETOOTH_SCO) {
+        
+        if (stream == AudioSystem::VOICE_CALL) {
+            value = (float)AudioSystem::logToLinear(value)/100.0f;
+        } else { // (type == AudioSystem::BLUETOOTH_SCO)
+            value = 1.0f;
+        }
+
+        AutoMutex lock(mHardwareLock);
+        mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
+        ret = mAudioHardware->setVoiceVolume(value);
+        mHardwareStatus = AUDIO_HW_IDLE;
+    }
+
+    return ret;
+}
+
+status_t AudioFlinger::setStreamMute(int stream, bool muted)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
+        return BAD_VALUE;
+    }
+    
+#ifdef WITH_A2DP
+    mA2dpMixerThread->setStreamMute(stream, muted);
+#endif
+    if (stream == AudioSystem::MUSIC) 
+    {
+        AutoMutex lock(&mHardwareLock);
+        if (mForcedRoute != 0)
+            mMusicMuteSaved = muted;
+        else
+            mHardwareMixerThread->setStreamMute(stream, muted);
+    } else {
+        mHardwareMixerThread->setStreamMute(stream, muted);
+    }
+
+    
+
+    return NO_ERROR;
+}
+
+float AudioFlinger::streamVolume(int stream) const
+{
+    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
+        return 0.0f;
+    }
+    return mHardwareMixerThread->streamVolume(stream);
+}
+
+bool AudioFlinger::streamMute(int stream) const
+{
+    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
+        return true;
+    }
+    
+    if (stream == AudioSystem::MUSIC && mForcedRoute != 0) 
+    {
+        return mMusicMuteSaved;
+    }
+    return mHardwareMixerThread->streamMute(stream);
+}
+
+bool AudioFlinger::isMusicActive() const
+{
+ #ifdef WITH_A2DP
+     if (isA2dpEnabled()) {
+         return mA2dpMixerThread->isMusicActive();
+     }
+ #endif
+    return mHardwareMixerThread->isMusicActive();
+}
+
+status_t AudioFlinger::setParameter(const char* key, const char* value)
+{
+    status_t result, result2;
+    AutoMutex lock(mHardwareLock);
+    mHardwareStatus = AUDIO_SET_PARAMETER;
+    
+    LOGV("setParameter() key %s, value %s, tid %d, calling tid %d", key, value, gettid(), IPCThreadState::self()->getCallingPid());
+    result = mAudioHardware->setParameter(key, value);
+    if (mA2dpAudioInterface) {
+        result2 = mA2dpAudioInterface->setParameter(key, value);
+        if (result2)
+            result = result2;
+    }
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return result;
+}
+
+size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
+{
+    return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
+}
+
+void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
+{
+    
+    LOGV("registerClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
+    Mutex::Autolock _l(mLock);
+
+    sp<IBinder> binder = client->asBinder();
+    if (mNotificationClients.indexOf(binder) < 0) {
+        LOGV("Adding notification client %p", binder.get());
+        binder->linkToDeath(this);
+        mNotificationClients.add(binder);
+        client->a2dpEnabledChanged(isA2dpEnabled());
+    }
+}
+
+void AudioFlinger::binderDied(const wp<IBinder>& who) {
+    
+    LOGV("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
+    Mutex::Autolock _l(mLock);
+
+    IBinder *binder = who.unsafe_get();
+
+    if (binder != NULL) {
+        int index = mNotificationClients.indexOf(binder);
+        if (index >= 0) {
+            LOGV("Removing notification client %p", binder);
+            mNotificationClients.removeAt(index);
+        }
+    }
+}
+
+void AudioFlinger::handleOutputSwitch()
+{
+    if (mA2dpEnabled != mA2dpEnabledReq)
+    {
+        Mutex::Autolock _l(mLock);
+
+        if (mA2dpEnabled != mA2dpEnabledReq)
+        {
+            mA2dpEnabled = mA2dpEnabledReq;
+            SortedVector < sp<MixerThread::Track> > tracks;
+            SortedVector < wp<MixerThread::Track> > activeTracks;
+            
+            // We hold mA2dpMixerThread mLock already 
+            Mutex::Autolock _l(mHardwareMixerThread->mLock);
+            
+            // Transfer tracks playing on MUSIC stream from one mixer to the other
+            if (mA2dpEnabled) {
+                mHardwareMixerThread->getTracks(tracks, activeTracks);
+                mA2dpMixerThread->putTracks(tracks, activeTracks);
+            } else {
+                mA2dpMixerThread->getTracks(tracks, activeTracks);
+                mHardwareMixerThread->putTracks(tracks, activeTracks);
+            }            
+            
+            // Notify AudioSystem of the A2DP activation/deactivation
+            size_t size = mNotificationClients.size();
+            for (size_t i = 0; i < size; i++) {
+                sp<IBinder> binder = mNotificationClients.itemAt(i).promote();
+                if (binder != NULL) {
+                    LOGV("Notifying output change to client %p", binder.get());
+                    sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder);
+                    client->a2dpEnabledChanged(mA2dpEnabled);
+                }
+            }
+
+            mHardwareMixerThread->wakeUp();
+        }
+    }
+}
+
+void AudioFlinger::removeClient(pid_t pid)
+{
+    LOGV("removeClient() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
+    Mutex::Autolock _l(mLock);
+    mClients.removeItem(pid);
+}
+
+void AudioFlinger::wakeUp()
+{
+    mHardwareMixerThread->wakeUp();
+#ifdef WITH_A2DP
+    mA2dpMixerThread->wakeUp();
+#endif // WITH_A2DP
+}
+
+bool AudioFlinger::isA2dpEnabled() const
+{
+    return mA2dpEnabledReq;
+}
+
+void AudioFlinger::handleForcedSpeakerRoute(int command)
+{
+    switch(command) {
+    case ACTIVE_TRACK_ADDED:
+        {
+            AutoMutex lock(mHardwareLock);
+            if (mForcedSpeakerCount++ == 0) {
+                mRouteRestoreTime = 0;
+                mMusicMuteSaved = mHardwareMixerThread->streamMute(AudioSystem::MUSIC);
+                if (mForcedRoute == 0 && !(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
+                    LOGV("Route forced to Speaker ON %08x", mSavedRoute | AudioSystem::ROUTE_SPEAKER);
+                    mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, true);
+                    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+                    mAudioHardware->setMasterVolume(0);
+                    usleep(mHardwareMixerThread->latency()*1000);
+                    mHardwareStatus = AUDIO_HW_SET_ROUTING;
+                    mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute | AudioSystem::ROUTE_SPEAKER);
+                    mHardwareStatus = AUDIO_HW_IDLE;
+                    // delay track start so that audio hardware has time to siwtch routes
+                    usleep(kStartSleepTime);
+                    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+                    mAudioHardware->setMasterVolume(mHardwareMixerThread->masterVolume());
+                    mHardwareStatus = AUDIO_HW_IDLE;
+                }
+                mForcedRoute = AudioSystem::ROUTE_SPEAKER;
+            }
+            LOGV("mForcedSpeakerCount incremented to %d", mForcedSpeakerCount);
+        }
+        break;
+    case ACTIVE_TRACK_REMOVED:
+        {
+            AutoMutex lock(mHardwareLock);
+            if (mForcedSpeakerCount > 0){
+                if (--mForcedSpeakerCount == 0) {
+                    mRouteRestoreTime = systemTime() + milliseconds(kStopSleepTime/1000);
+                }
+                LOGV("mForcedSpeakerCount decremented to %d", mForcedSpeakerCount);            
+            } else {
+                LOGE("mForcedSpeakerCount is already zero");            
+            }            
+        }
+        break;
+    case CHECK_ROUTE_RESTORE_TIME:
+    case FORCE_ROUTE_RESTORE:
+        if (mRouteRestoreTime) {
+            AutoMutex lock(mHardwareLock);
+            if (mRouteRestoreTime && 
+               (systemTime() > mRouteRestoreTime || command == FORCE_ROUTE_RESTORE)) {
+                mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, mMusicMuteSaved);
+                mForcedRoute = 0;
+                if (!(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
+                    mHardwareStatus = AUDIO_HW_SET_ROUTING;
+                    mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute);
+                    mHardwareStatus = AUDIO_HW_IDLE;
+                    LOGV("Route forced to Speaker OFF %08x", mSavedRoute);
+                }
+                mRouteRestoreTime = 0;
+            }
+        }
+        break;
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType)
+    :   Thread(false),
+        mAudioFlinger(audioFlinger), mAudioMixer(0), mOutput(output), mOutputType(outputType), 
+        mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0), mMixBuffer(0),
+        mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mStandby(false),
+        mInWrite(false)
+{
+    mSampleRate = output->sampleRate();
+    mChannelCount = output->channelCount();
+
+    // FIXME - Current mixer implementation only supports stereo output
+    if (mChannelCount == 1) {
+        LOGE("Invalid audio hardware channel count");
+    }
+
+    mFormat = output->format();
+    mFrameCount = output->bufferSize() / output->channelCount() / sizeof(int16_t);
+    mAudioMixer = new AudioMixer(mFrameCount, output->sampleRate());
+
+    // FIXME - Current mixer implementation only supports stereo output: Always
+    // Allocate a stereo buffer even if HW output is mono.
+    mMixBuffer = new int16_t[mFrameCount * 2];
+    memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t));
+}
+
+AudioFlinger::MixerThread::~MixerThread()
+{
+    delete [] mMixBuffer;
+    delete mAudioMixer;
+}
+
+status_t AudioFlinger::MixerThread::dump(int fd, const Vector<String16>& args)
+{
+    dumpInternals(fd, args);
+    dumpTracks(fd, args);
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::MixerThread::dumpTracks(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "Output %d mixer thread tracks\n", mOutputType);
+    result.append(buffer);
+    result.append("   Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
+    for (size_t i = 0; i < mTracks.size(); ++i) {
+        wp<Track> wTrack = mTracks[i];
+        if (wTrack != 0) {
+            sp<Track> track = wTrack.promote();
+            if (track != 0) {
+                track->dump(buffer, SIZE);
+                result.append(buffer);
+            }
+        }
+    }
+
+    snprintf(buffer, SIZE, "Output %d mixer thread active tracks\n", mOutputType);
+    result.append(buffer);
+    result.append("   Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
+    for (size_t i = 0; i < mActiveTracks.size(); ++i) {
+        wp<Track> wTrack = mTracks[i];
+        if (wTrack != 0) {
+            sp<Track> track = wTrack.promote();
+            if (track != 0) {
+                track->dump(buffer, SIZE);
+                result.append(buffer);
+            }
+        }
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "Output %d mixer thread internals\n", mOutputType);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
+    result.append(buffer);
+    snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "standby: %d\n", mStandby);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+// Thread virtuals
+bool AudioFlinger::MixerThread::threadLoop()
+{
+    unsigned long sleepTime = kBufferRecoveryInUsecs;
+    int16_t* curBuf = mMixBuffer;
+    Vector< sp<Track> > tracksToRemove;
+    size_t enabledTracks = 0;
+    nsecs_t standbyTime = systemTime();   
+    size_t mixBufferSize = mFrameCount*mChannelCount*sizeof(int16_t);
+    nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 2;
+
+#ifdef WITH_A2DP
+    bool outputTrackActive = false;
+#endif
+
+    do {
+        enabledTracks = 0;
+        { // scope for the mLock
+        
+            Mutex::Autolock _l(mLock);
+
+#ifdef WITH_A2DP
+            if (mOutputType == AudioSystem::AUDIO_OUTPUT_A2DP) {
+                mAudioFlinger->handleOutputSwitch();
+            }
+            if (mOutputTrack != NULL && !mAudioFlinger->isA2dpEnabled()) {
+                if (outputTrackActive) {
+                    mOutputTrack->stop();
+                    outputTrackActive = false;
+                }
+            }
+#endif
+
+            const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
+
+            // put audio hardware into standby after short delay
+            if UNLIKELY(!activeTracks.size() && systemTime() > standbyTime) {
+                // wait until we have something to do...
+                LOGV("Audio hardware entering standby, output %d\n", mOutputType);
+//                mAudioFlinger->mHardwareStatus = AUDIO_HW_STANDBY;
+                if (!mStandby) {
+                    mOutput->standby();
+                    mStandby = true;
+                }
+                
+#ifdef WITH_A2DP
+                if (outputTrackActive) {
+                    mOutputTrack->stop();
+                    outputTrackActive = false;
+                }
+#endif
+                if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
+                    mAudioFlinger->handleForcedSpeakerRoute(FORCE_ROUTE_RESTORE);
+                }                
+//                mHardwareStatus = AUDIO_HW_IDLE;
+                // we're about to wait, flush the binder command buffer
+                IPCThreadState::self()->flushCommands();
+                mWaitWorkCV.wait(mLock);
+                LOGV("Audio hardware exiting standby, output %d\n", mOutputType);
+                
+                if (mMasterMute == false) {
+                    char value[PROPERTY_VALUE_MAX];
+                    property_get("ro.audio.silent", value, "0");
+                    if (atoi(value)) {
+                        LOGD("Silence is golden");
+                        setMasterMute(true);
+                    }                    
+                }
+                
+                standbyTime = systemTime() + kStandbyTimeInNsecs;
+                continue;
+            }
+
+            // Forced route to speaker is handled by hardware mixer thread
+            if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
+                mAudioFlinger->handleForcedSpeakerRoute(CHECK_ROUTE_RESTORE_TIME);
+            }
+
+            // find out which tracks need to be processed
+            size_t count = activeTracks.size();
+            for (size_t i=0 ; i<count ; i++) {
+                sp<Track> t = activeTracks[i].promote();
+                if (t == 0) continue;
+
+                Track* const track = t.get();
+                audio_track_cblk_t* cblk = track->cblk();
+
+                // The first time a track is added we wait
+                // for all its buffers to be filled before processing it
+                mAudioMixer->setActiveTrack(track->name());
+                if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
+                        !track->isPaused())
+                {
+                    //LOGV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
+
+                    // compute volume for this track
+                    int16_t left, right;
+                    if (track->isMuted() || mMasterMute || track->isPausing()) {
+                        left = right = 0;
+                        if (track->isPausing()) {
+                            LOGV("paused(%d)", track->name());
+                            track->setPaused();
+                        }
+                    } else {
+                        float typeVolume = mStreamTypes[track->type()].volume;
+                        float v = mMasterVolume * typeVolume;
+                        float v_clamped = v * cblk->volume[0];
+                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
+                        left = int16_t(v_clamped);
+                        v_clamped = v * cblk->volume[1];
+                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
+                        right = int16_t(v_clamped);
+                    }
+
+                    // XXX: these things DON'T need to be done each time
+                    mAudioMixer->setBufferProvider(track);
+                    mAudioMixer->enable(AudioMixer::MIXING);
+
+                    int param;
+                    if ( track->mFillingUpStatus == Track::FS_FILLED) {
+                        // no ramp for the first volume setting
+                        track->mFillingUpStatus = Track::FS_ACTIVE;
+                        if (track->mState == TrackBase::RESUMING) {
+                            track->mState = TrackBase::ACTIVE;
+                            param = AudioMixer::RAMP_VOLUME;
+                        } else {
+                            param = AudioMixer::VOLUME;
+                        }
+                    } else {
+                        param = AudioMixer::RAMP_VOLUME;
+                    }
+                    mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
+                    mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
+                    mAudioMixer->setParameter(
+                        AudioMixer::TRACK,
+                        AudioMixer::FORMAT, track->format());
+                    mAudioMixer->setParameter(
+                        AudioMixer::TRACK,
+                        AudioMixer::CHANNEL_COUNT, track->channelCount());
+                    mAudioMixer->setParameter(
+                        AudioMixer::RESAMPLE,
+                        AudioMixer::SAMPLE_RATE,
+                        int(cblk->sampleRate));
+
+                    // reset retry count
+                    track->mRetryCount = kMaxTrackRetries;
+                    enabledTracks++;
+                } else {
+                    //LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
+                    if (track->isStopped()) {
+                        track->reset();
+                    }
+                    if (track->isTerminated() || track->isStopped() || track->isPaused()) {
+                        // We have consumed all the buffers of this track.
+                        // Remove it from the list of active tracks.
+                        LOGV("remove(%d) from active list", track->name());
+                        tracksToRemove.add(track);
+                    } else {
+                        // No buffers for this track. Give it a few chances to
+                        // fill a buffer, then remove it from active list.
+                        if (--(track->mRetryCount) <= 0) {
+                            LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
+                            tracksToRemove.add(track);
+                        }
+                    }
+                    // LOGV("disable(%d)", track->name());
+                    mAudioMixer->disable(AudioMixer::MIXING);
+                }
+            }
+
+            // remove all the tracks that need to be...
+            count = tracksToRemove.size();
+            if (UNLIKELY(count)) {
+                for (size_t i=0 ; i<count ; i++) {
+                    const sp<Track>& track = tracksToRemove[i];
+                    removeActiveTrack(track);
+                    if (track->isTerminated()) {
+                        mTracks.remove(track);
+                        deleteTrackName(track->mName);
+                    }
+                }
+            }  
+       }
+        
+        if (LIKELY(enabledTracks)) {
+            // mix buffers...
+            mAudioMixer->process(curBuf);
+
+#ifdef WITH_A2DP
+            if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
+                if (!outputTrackActive) {
+                    LOGV("starting output track in mixer for output %d", mOutputType);
+                    mOutputTrack->start();
+                    outputTrackActive = true;
+                }
+                mOutputTrack->write(curBuf, mFrameCount);
+            }
+#endif
+
+            // output audio to hardware
+            mLastWriteTime = systemTime();
+            mInWrite = true;
+            mOutput->write(curBuf, mixBufferSize);
+            mNumWrites++;
+            mInWrite = false;
+            mStandby = false;
+            nsecs_t temp = systemTime();
+            standbyTime = temp + kStandbyTimeInNsecs;
+            nsecs_t delta = temp - mLastWriteTime;
+            if (delta > maxPeriod) {
+                LOGW("write blocked for %llu msecs", ns2ms(delta));
+                mNumDelayedWrites++;
+            }
+            sleepTime = kBufferRecoveryInUsecs;
+        } else {         
+#ifdef WITH_A2DP
+            if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
+                if (outputTrackActive) {
+                    mOutputTrack->write(curBuf, 0);
+                    if (mOutputTrack->bufferQueueEmpty()) {
+                        mOutputTrack->stop();
+                        outputTrackActive = false;
+                    } else {
+                        standbyTime = systemTime() + kStandbyTimeInNsecs;
+                    }
+                }
+            }
+#endif
+            // 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, the audio
+            // hardware will zero-fill for us.
+            //LOGV("no buffers - usleep(%lu)", sleepTime);
+            usleep(sleepTime);
+            if (sleepTime < kMaxBufferRecoveryInUsecs) {
+                sleepTime += kBufferRecoveryInUsecs;
+            }
+        }
+
+        // finally let go of all our tracks, without the lock held
+        // since we can't guarantee the destructors won't acquire that
+        // same lock.
+        tracksToRemove.clear();
+    } while (true);
+
+    return false;
+}
+
+status_t AudioFlinger::MixerThread::readyToRun()
+{
+    if (mSampleRate == 0) {
+        LOGE("No working audio driver found.");
+        return NO_INIT;
+    }
+    LOGI("AudioFlinger's thread ready to run for output %d", mOutputType);
+    return NO_ERROR;
+}
+
+void AudioFlinger::MixerThread::onFirstRef()
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+
+    snprintf(buffer, SIZE, "Mixer Thread for output %d", mOutputType);
+
+    run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
+}
+
+
+sp<AudioFlinger::MixerThread::Track>  AudioFlinger::MixerThread::createTrack(
+        const sp<AudioFlinger::Client>& client,
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int frameCount,
+        const sp<IMemory>& sharedBuffer,
+        status_t *status)
+{
+    sp<Track> track;
+    status_t lStatus;
+    
+    // Resampler implementation limits input sampling rate to 2 x output sampling rate.
+    if (sampleRate > MAX_SAMPLE_RATE || sampleRate > mSampleRate*2) {
+        LOGE("Sample rate out of range: %d mSampleRate %d", sampleRate, mSampleRate);
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
+
+    {
+        Mutex::Autolock _l(mLock);
+
+        if (mSampleRate == 0) {
+            LOGE("Audio driver not initialized.");
+            lStatus = NO_INIT;
+            goto Exit;
+        }
+
+        track = new Track(this, client, streamType, sampleRate, format,
+                channelCount, frameCount, sharedBuffer);
+        if (track->getCblk() == NULL) {
+            track.clear();
+            lStatus = NO_MEMORY;
+            goto Exit;
+        }
+        mTracks.add(track);
+        lStatus = NO_ERROR;
+    }
+
+Exit:
+    if(status) {
+        *status = lStatus;
+    }
+    return track;
+}
+
+void AudioFlinger::MixerThread::getTracks(
+        SortedVector < sp<Track> >& tracks,
+        SortedVector < wp<Track> >& activeTracks)
+{
+    size_t size = mTracks.size();
+    LOGV ("MixerThread::getTracks() for output %d, mTracks.size %d, mActiveTracks.size %d", mOutputType,  mTracks.size(), mActiveTracks.size());
+    for (size_t i = 0; i < size; i++) {
+        sp<Track> t = mTracks[i];
+        if (AudioSystem::routedToA2dpOutput(t->mStreamType)) {
+            tracks.add(t);
+            int j = mActiveTracks.indexOf(t);
+            if (j >= 0) {
+                t = mActiveTracks[j].promote();
+                if (t != NULL) {
+                    activeTracks.add(t);                                    
+                }                            
+            }
+        }
+    }
+
+    size = activeTracks.size();
+    for (size_t i = 0; i < size; i++) {
+        removeActiveTrack(activeTracks[i]);
+    }
+    
+    size = tracks.size();
+    for (size_t i = 0; i < size; i++) {
+        sp<Track> t = tracks[i];
+        mTracks.remove(t);
+        deleteTrackName(t->name());
+    }
+}
+
+void AudioFlinger::MixerThread::putTracks(
+        SortedVector < sp<Track> >& tracks,
+        SortedVector < wp<Track> >& activeTracks)
+{
+
+    LOGV ("MixerThread::putTracks() for output %d, tracks.size %d, activeTracks.size %d", mOutputType,  tracks.size(), activeTracks.size());
+
+    size_t size = tracks.size();
+    for (size_t i = 0; i < size ; i++) {
+        sp<Track> t = tracks[i];
+        int name = getTrackName();
+
+        if (name < 0) return;
+        
+        t->mName = name;
+        t->mMixerThread = this;
+        mTracks.add(t);
+
+        int j = activeTracks.indexOf(t);
+        if (j >= 0) {
+            addActiveTrack(t);
+        }            
+    }
+}
+
+uint32_t AudioFlinger::MixerThread::sampleRate() const
+{
+    return mSampleRate;
+}
+
+int AudioFlinger::MixerThread::channelCount() const
+{
+    return mChannelCount;
+}
+
+int AudioFlinger::MixerThread::format() const
+{
+    return mFormat;
+}
+
+size_t AudioFlinger::MixerThread::frameCount() const
+{
+    return mFrameCount;
+}
+
+uint32_t AudioFlinger::MixerThread::latency() const
+{
+    if (mOutput) {
+        return mOutput->latency();
+    }
+    else {
+        return 0;
+    }
+}
+
+status_t AudioFlinger::MixerThread::setMasterVolume(float value)
+{
+    mMasterVolume = value;
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::MixerThread::setMasterMute(bool muted)
+{
+    mMasterMute = muted;
+    return NO_ERROR;
+}
+
+float AudioFlinger::MixerThread::masterVolume() const
+{
+    return mMasterVolume;
+}
+
+bool AudioFlinger::MixerThread::masterMute() const
+{
+    return mMasterMute;
+}
+
+status_t AudioFlinger::MixerThread::setStreamVolume(int stream, float value)
+{
+    mStreamTypes[stream].volume = value;
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::MixerThread::setStreamMute(int stream, bool muted)
+{
+    mStreamTypes[stream].mute = muted;
+    return NO_ERROR;
+}
+
+float AudioFlinger::MixerThread::streamVolume(int stream) const
+{
+    return mStreamTypes[stream].volume;
+}
+
+bool AudioFlinger::MixerThread::streamMute(int stream) const
+{
+    return mStreamTypes[stream].mute;
+}
+
+bool AudioFlinger::MixerThread::isMusicActive() const
+{
+    size_t count = mActiveTracks.size();
+    for (size_t i = 0 ; i < count ; ++i) {
+        sp<Track> t = mActiveTracks[i].promote();
+        if (t == 0) continue;
+        Track* const track = t.get();
+        if (t->mStreamType == AudioSystem::MUSIC)
+            return true;
+    }
+    return false;
+}
+
+status_t AudioFlinger::MixerThread::addTrack(const sp<Track>& track)
+{
+    status_t status = ALREADY_EXISTS;
+    Mutex::Autolock _l(mLock);
+
+    // here the track could be either new, or restarted
+    // in both cases "unstop" the track
+    if (track->isPaused()) {
+        track->mState = TrackBase::RESUMING;
+        LOGV("PAUSED => RESUMING (%d)", track->name());
+    } else {
+        track->mState = TrackBase::ACTIVE;
+        LOGV("? => ACTIVE (%d)", track->name());
+    }
+    // set retry count for buffer fill
+    track->mRetryCount = kMaxTrackStartupRetries;
+    if (mActiveTracks.indexOf(track) < 0) {
+        // the track is newly added, make sure it fills up all its
+        // buffers before playing. This is to ensure the client will
+        // effectively get the latency it requested.
+        track->mFillingUpStatus = Track::FS_FILLING;
+        track->mResetDone = false;
+        addActiveTrack(track);
+        status = NO_ERROR;
+    }
+    
+    LOGV("mWaitWorkCV.broadcast");
+    mWaitWorkCV.broadcast();
+
+    return status;
+}
+
+void AudioFlinger::MixerThread::removeTrack(wp<Track> track, int name)
+{
+    Mutex::Autolock _l(mLock);
+    sp<Track> t = track.promote();
+    if (t!=NULL && (t->mState <= TrackBase::STOPPED)) {
+        remove_track_l(track, name);
+    }
+}
+
+void AudioFlinger::MixerThread::remove_track_l(wp<Track> track, int name)
+{
+    sp<Track> t = track.promote();
+    if (t!=NULL) {
+        t->reset();
+    }
+    deleteTrackName(name);
+    removeActiveTrack(track);
+    mWaitWorkCV.broadcast();
+}
+
+void AudioFlinger::MixerThread::destroyTrack(const sp<Track>& track)
+{
+    // NOTE: We're acquiring a strong reference on the track before
+    // acquiring the lock, this is to make sure removing it from
+    // mTracks won't cause the destructor to be called while the lock is
+    // held (note that technically, 'track' could be a reference to an item
+    // in mTracks, which is why we need to do this).
+    sp<Track> keep(track);
+    Mutex::Autolock _l(mLock);
+    track->mState = TrackBase::TERMINATED;
+    if (mActiveTracks.indexOf(track) < 0) {
+        LOGV("remove track (%d) and delete from mixer", track->name());
+        mTracks.remove(track);
+        deleteTrackName(keep->name());
+    }
+}
+
+
+void AudioFlinger::MixerThread::addActiveTrack(const wp<Track>& t)
+{
+    mActiveTracks.add(t);
+
+    // Force routing to speaker for certain stream types
+    // The forced routing to speaker is managed by hardware mixer
+    if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
+        sp<Track> track = t.promote();
+        if (track == NULL) return;
+   
+        if (streamForcedToSpeaker(track->type())) {
+            mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_ADDED);
+        }        
+    }
+}
+
+void AudioFlinger::MixerThread::removeActiveTrack(const wp<Track>& t)
+{
+    mActiveTracks.remove(t);
+
+    // Force routing to speaker for certain stream types
+    // The forced routing to speaker is managed by hardware mixer
+    if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
+        sp<Track> track = t.promote();
+        if (track == NULL) return;
+
+        if (streamForcedToSpeaker(track->type())) {
+            mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_REMOVED);
+        }
+    }
+}
+
+int AudioFlinger::MixerThread::getTrackName()
+{
+    return mAudioMixer->getTrackName();
+}
+
+void AudioFlinger::MixerThread::deleteTrackName(int name)
+{
+    mAudioMixer->deleteTrackName(name);
+}
+
+size_t AudioFlinger::MixerThread::getOutputFrameCount() 
+{
+    return mOutput->bufferSize() / mOutput->channelCount() / sizeof(int16_t);
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::MixerThread::TrackBase::TrackBase(
+            const sp<MixerThread>& mixerThread,
+            const sp<Client>& client,
+            int streamType,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount,
+            uint32_t flags,
+            const sp<IMemory>& sharedBuffer)
+    :   RefBase(),
+        mMixerThread(mixerThread),
+        mClient(client),
+        mStreamType(streamType),
+        mFrameCount(0),
+        mState(IDLE),
+        mClientTid(-1),
+        mFormat(format),
+        mFlags(flags & ~SYSTEM_FLAGS_MASK)
+{
+    mName = mixerThread->getTrackName();
+    LOGV("TrackBase contructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
+    if (mName < 0) {
+        LOGE("no more track names availlable");
+        return;
+    }
+
+    LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
+
+    // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
+   size_t size = sizeof(audio_track_cblk_t);
+   size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
+   if (sharedBuffer == 0) {
+       size += bufferSize;
+   }
+
+   if (client != NULL) {
+        mCblkMemory = client->heap()->allocate(size);
+        if (mCblkMemory != 0) {
+            mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
+            if (mCblk) { // construct the shared structure in-place.
+                new(mCblk) audio_track_cblk_t();
+                // clear all buffers
+                mCblk->frameCount = frameCount;
+                mCblk->sampleRate = sampleRate;
+                mCblk->channels = channelCount;
+                if (sharedBuffer == 0) {
+                    mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
+                    memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
+                    // Force underrun condition to avoid false underrun callback until first data is
+                    // written to buffer
+                    mCblk->flowControlFlag = 1;
+                } else {
+                    mBuffer = sharedBuffer->pointer();
+                }
+                mBufferEnd = (uint8_t *)mBuffer + bufferSize;
+            }
+        } else {
+            LOGE("not enough memory for AudioTrack size=%u", size);
+            client->heap()->dump("AudioTrack");
+            return;
+        }
+   } else {
+       mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
+       if (mCblk) { // construct the shared structure in-place.
+           new(mCblk) audio_track_cblk_t();
+           // clear all buffers
+           mCblk->frameCount = frameCount;
+           mCblk->sampleRate = sampleRate;
+           mCblk->channels = channelCount;
+           mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
+           memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
+           // Force underrun condition to avoid false underrun callback until first data is
+           // written to buffer
+           mCblk->flowControlFlag = 1;
+           mBufferEnd = (uint8_t *)mBuffer + bufferSize;
+       }
+   }
+}
+
+AudioFlinger::MixerThread::TrackBase::~TrackBase()
+{
+    if (mCblk) {
+        mCblk->~audio_track_cblk_t();   // destroy our shared-structure.        
+    }
+    mCblkMemory.clear();            // and free the shared memory
+    mClient.clear();
+}
+
+void AudioFlinger::MixerThread::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    buffer->raw = 0;
+    mFrameCount = buffer->frameCount;
+    step();
+    buffer->frameCount = 0;
+}
+
+bool AudioFlinger::MixerThread::TrackBase::step() {
+    bool result;
+    audio_track_cblk_t* cblk = this->cblk();
+
+    result = cblk->stepServer(mFrameCount);
+    if (!result) {
+        LOGV("stepServer failed acquiring cblk mutex");
+        mFlags |= STEPSERVER_FAILED;
+    }
+    return result;
+}
+
+void AudioFlinger::MixerThread::TrackBase::reset() {
+    audio_track_cblk_t* cblk = this->cblk();
+
+    cblk->user = 0;
+    cblk->server = 0;
+    cblk->userBase = 0;
+    cblk->serverBase = 0;
+    mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
+    LOGV("TrackBase::reset");
+}
+
+sp<IMemory> AudioFlinger::MixerThread::TrackBase::getCblk() const
+{
+    return mCblkMemory;
+}
+
+int AudioFlinger::MixerThread::TrackBase::sampleRate() const {
+    return mCblk->sampleRate;
+}
+
+int AudioFlinger::MixerThread::TrackBase::channelCount() const {
+    return mCblk->channels;
+}
+
+void* AudioFlinger::MixerThread::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
+    audio_track_cblk_t* cblk = this->cblk();
+    int16_t *bufferStart = (int16_t *)mBuffer + (offset-cblk->serverBase)*cblk->channels;
+    int16_t *bufferEnd = bufferStart + frames * cblk->channels;
+
+    // Check validity of returned pointer in case the track control block would have been corrupted.
+    if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd) {
+        LOGW("TrackBase::getBuffer buffer out of range:\n    start: %p, end %p , mBuffer %p mBufferEnd %p\n    \
+                server %d, serverBase %d, user %d, userBase %d",
+                bufferStart, bufferEnd, mBuffer, mBufferEnd,
+                cblk->server, cblk->serverBase, cblk->user, cblk->userBase);
+        return 0;
+    }
+
+    return bufferStart;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::MixerThread::Track::Track(
+            const sp<MixerThread>& mixerThread,
+            const sp<Client>& client,
+            int streamType,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount,
+            const sp<IMemory>& sharedBuffer)
+    :   TrackBase(mixerThread, client, streamType, sampleRate, format, channelCount, frameCount, 0, sharedBuffer)
+{
+    mVolume[0] = 1.0f;
+    mVolume[1] = 1.0f;
+    mMute = false;
+    mSharedBuffer = sharedBuffer;
+}
+
+AudioFlinger::MixerThread::Track::~Track()
+{
+    wp<Track> weak(this); // never create a strong ref from the dtor
+    mState = TERMINATED;
+    mMixerThread->removeTrack(weak, mName);
+}
+
+void AudioFlinger::MixerThread::Track::destroy()
+{
+    mMixerThread->destroyTrack(this);
+}
+
+void AudioFlinger::MixerThread::Track::dump(char* buffer, size_t size)
+{
+    snprintf(buffer, size, "  %5d %5d %3u %3u %3u %3u %1d %1d %1d %5u %5u %5u %04x %04x\n",
+            mName - AudioMixer::TRACK0,
+            (mClient == NULL) ? getpid() : mClient->pid(),
+            mStreamType,
+            mFormat,
+            mCblk->channels,
+            mFrameCount,
+            mState,
+            mMute,
+            mFillingUpStatus,
+            mCblk->sampleRate,
+            mCblk->volume[0],
+            mCblk->volume[1],
+            mCblk->server,
+            mCblk->user);
+}
+
+status_t AudioFlinger::MixerThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+{
+     audio_track_cblk_t* cblk = this->cblk();
+     uint32_t framesReady;
+     uint32_t framesReq = buffer->frameCount;
+
+     // Check if last stepServer failed, try to step now
+     if (mFlags & TrackBase::STEPSERVER_FAILED) {
+         if (!step())  goto getNextBuffer_exit;
+         LOGV("stepServer recovered");
+         mFlags &= ~TrackBase::STEPSERVER_FAILED;
+     }
+
+     framesReady = cblk->framesReady();
+
+     if (LIKELY(framesReady)) {
+        uint32_t s = cblk->server;
+        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
+
+        bufferEnd = (cblk->loopEnd < bufferEnd) ? cblk->loopEnd : bufferEnd;
+        if (framesReq > framesReady) {
+            framesReq = framesReady;
+        }
+        if (s + framesReq > bufferEnd) {
+            framesReq = bufferEnd - s;
+        }
+
+         buffer->raw = getBuffer(s, framesReq);
+         if (buffer->raw == 0) goto getNextBuffer_exit;
+
+         buffer->frameCount = framesReq;
+        return NO_ERROR;
+     }
+
+getNextBuffer_exit:
+     buffer->raw = 0;
+     buffer->frameCount = 0;
+     return NOT_ENOUGH_DATA;
+}
+
+bool AudioFlinger::MixerThread::Track::isReady() const {
+    if (mFillingUpStatus != FS_FILLING) return true;
+
+    if (mCblk->framesReady() >= mCblk->frameCount ||
+        mCblk->forceReady) {
+        mFillingUpStatus = FS_FILLED;
+        mCblk->forceReady = 0;
+        LOGV("Track::isReady() track %d for output %d", mName, mMixerThread->mOutputType);
+        return true;
+    }
+    return false;
+}
+
+status_t AudioFlinger::MixerThread::Track::start()
+{
+    LOGV("start(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
+    mMixerThread->addTrack(this);
+    return NO_ERROR;
+}
+
+void AudioFlinger::MixerThread::Track::stop()
+{
+    LOGV("stop(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
+    Mutex::Autolock _l(mMixerThread->mLock);
+    if (mState > STOPPED) {
+        mState = STOPPED;
+        // If the track is not active (PAUSED and buffers full), flush buffers
+        if (mMixerThread->mActiveTracks.indexOf(this) < 0) {
+            reset();
+        }
+        LOGV("(> STOPPED) => STOPPED (%d)", mName);
+    }
+}
+
+void AudioFlinger::MixerThread::Track::pause()
+{
+    LOGV("pause(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
+    Mutex::Autolock _l(mMixerThread->mLock);
+    if (mState == ACTIVE || mState == RESUMING) {
+        mState = PAUSING;
+        LOGV("ACTIVE/RESUMING => PAUSING (%d)", mName);
+    }
+}
+
+void AudioFlinger::MixerThread::Track::flush()
+{
+    LOGV("flush(%d)", mName);
+    Mutex::Autolock _l(mMixerThread->mLock);
+    if (mState != STOPPED && mState != PAUSED && mState != PAUSING) {
+        return;
+    }
+    // No point remaining in PAUSED state after a flush => go to
+    // STOPPED state
+    mState = STOPPED;
+
+    // NOTE: reset() will reset cblk->user and cblk->server with
+    // the risk that at the same time, the AudioMixer is trying to read
+    // data. In this case, getNextBuffer() would return a NULL pointer
+    // as audio buffer => the AudioMixer code MUST always test that pointer
+    // returned by getNextBuffer() is not NULL!
+    reset();
+}
+
+void AudioFlinger::MixerThread::Track::reset()
+{
+    // Do not reset twice to avoid discarding data written just after a flush and before
+    // the audioflinger thread detects the track is stopped.
+    if (!mResetDone) {
+        TrackBase::reset();
+        // Force underrun condition to avoid false underrun callback until first data is
+        // written to buffer
+        mCblk->flowControlFlag = 1;
+        mCblk->forceReady = 0;
+        mFillingUpStatus = FS_FILLING;        
+        mResetDone = true;
+    }
+}
+
+void AudioFlinger::MixerThread::Track::mute(bool muted)
+{
+    mMute = muted;
+}
+
+void AudioFlinger::MixerThread::Track::setVolume(float left, float right)
+{
+    mVolume[0] = left;
+    mVolume[1] = right;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::MixerThread::RecordTrack::RecordTrack(
+            const sp<MixerThread>& mixerThread,
+            const sp<Client>& client,
+            int streamType,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount,
+            uint32_t flags)
+    :   TrackBase(mixerThread, client, streamType, sampleRate, format,
+                  channelCount, frameCount, flags, 0),
+        mOverflow(false)
+{
+}
+
+AudioFlinger::MixerThread::RecordTrack::~RecordTrack()
+{
+    mMixerThread->deleteTrackName(mName);
+}
+
+status_t AudioFlinger::MixerThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    audio_track_cblk_t* cblk = this->cblk();
+    uint32_t framesAvail;
+    uint32_t framesReq = buffer->frameCount;
+
+     // Check if last stepServer failed, try to step now
+    if (mFlags & TrackBase::STEPSERVER_FAILED) {
+        if (!step()) goto getNextBuffer_exit;
+        LOGV("stepServer recovered");
+        mFlags &= ~TrackBase::STEPSERVER_FAILED;
+    }
+
+    framesAvail = cblk->framesAvailable_l();
+
+    if (LIKELY(framesAvail)) {
+        uint32_t s = cblk->server;
+        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
+
+        if (framesReq > framesAvail) {
+            framesReq = framesAvail;
+        }
+        if (s + framesReq > bufferEnd) {
+            framesReq = bufferEnd - s;
+        }
+
+        buffer->raw = getBuffer(s, framesReq);
+        if (buffer->raw == 0) goto getNextBuffer_exit;
+
+        buffer->frameCount = framesReq;
+        return NO_ERROR;
+    }
+
+getNextBuffer_exit:
+    buffer->raw = 0;
+    buffer->frameCount = 0;
+    return NOT_ENOUGH_DATA;
+}
+
+status_t AudioFlinger::MixerThread::RecordTrack::start()
+{
+    return mMixerThread->mAudioFlinger->startRecord(this);
+}
+
+void AudioFlinger::MixerThread::RecordTrack::stop()
+{
+    mMixerThread->mAudioFlinger->stopRecord(this);
+    TrackBase::reset();
+    // Force overerrun condition to avoid false overrun callback until first data is
+    // read from buffer
+    mCblk->flowControlFlag = 1;
+}
+
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::MixerThread::OutputTrack::OutputTrack(
+            const sp<MixerThread>& mixerThread,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount)
+    :   Track(mixerThread, NULL, AudioSystem::SYSTEM, sampleRate, format, channelCount, frameCount, NULL),
+    mOutputMixerThread(mixerThread)
+{
+                
+    mCblk->out = 1;
+    mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
+    mCblk->volume[0] = mCblk->volume[1] = 0x1000;
+    mOutBuffer.frameCount = 0;
+    mCblk->bufferTimeoutMs = 10;
+    
+    LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p", 
+            mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd);
+    
+}
+
+AudioFlinger::MixerThread::OutputTrack::~OutputTrack()
+{
+    stop();
+}
+
+status_t AudioFlinger::MixerThread::OutputTrack::start()
+{
+    status_t status = Track::start();
+    
+    mRetryCount = 127;
+    return status;
+}
+
+void AudioFlinger::MixerThread::OutputTrack::stop()
+{
+    Track::stop();
+    clearBufferQueue();
+    mOutBuffer.frameCount = 0;
+}
+
+void AudioFlinger::MixerThread::OutputTrack::write(int16_t* data, uint32_t frames)
+{
+    Buffer *pInBuffer;
+    Buffer inBuffer;
+    uint32_t channels = mCblk->channels;
+        
+    inBuffer.frameCount = frames;
+    inBuffer.i16 = data;
+    
+    if (mCblk->user == 0) {
+        if (mOutputMixerThread->isMusicActive()) {
+            mCblk->forceReady = 1;
+            LOGV("OutputTrack::start() force ready");
+        } else if (mCblk->frameCount > frames){
+            if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
+                uint32_t startFrames = (mCblk->frameCount - frames);
+                LOGV("OutputTrack::start() write %d frames", startFrames);
+                pInBuffer = new Buffer;
+                pInBuffer->mBuffer = new int16_t[startFrames * channels];
+                pInBuffer->frameCount = startFrames;
+                pInBuffer->i16 = pInBuffer->mBuffer;
+                memset(pInBuffer->raw, 0, startFrames * channels * sizeof(int16_t));
+                mBufferQueue.add(pInBuffer);                
+            } else {
+                LOGW ("OutputTrack::write() no more buffers");
+            }
+        }        
+    }
+
+    while (1) { 
+        // First write pending buffers, then new data
+        if (mBufferQueue.size()) {
+            pInBuffer = mBufferQueue.itemAt(0);
+        } else {
+            pInBuffer = &inBuffer;
+        }
+ 
+        if (pInBuffer->frameCount == 0) {
+            break;
+        }
+        
+        if (mOutBuffer.frameCount == 0) {
+            mOutBuffer.frameCount = pInBuffer->frameCount;
+            if (obtainBuffer(&mOutBuffer) == (status_t)AudioTrack::NO_MORE_BUFFERS) {
+                break;
+            }
+        }
+            
+        uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount : pInBuffer->frameCount;
+        memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channels * sizeof(int16_t));
+        mCblk->stepUser(outFrames);
+        pInBuffer->frameCount -= outFrames;
+        pInBuffer->i16 += outFrames * channels;
+        mOutBuffer.frameCount -= outFrames;
+        mOutBuffer.i16 += outFrames * channels;            
+        
+        if (pInBuffer->frameCount == 0) {
+            if (mBufferQueue.size()) {
+                mBufferQueue.removeAt(0);
+                delete [] pInBuffer->mBuffer;
+                delete pInBuffer;
+            } else {
+                break;
+            }
+        }
+    }
+ 
+    // If we could not write all frames, allocate a buffer and queue it for next time.
+    if (inBuffer.frameCount) {
+        if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
+            pInBuffer = new Buffer;
+            pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channels];
+            pInBuffer->frameCount = inBuffer.frameCount;
+            pInBuffer->i16 = pInBuffer->mBuffer;
+            memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channels * sizeof(int16_t));
+            mBufferQueue.add(pInBuffer);
+        } else {
+            LOGW("OutputTrack::write() no more buffers");
+        }
+    }
+    
+    // Calling write() with a 0 length buffer, means that no more data will be written:
+    // If no more buffers are pending, fill output track buffer to make sure it is started 
+    // by output mixer.
+    if (frames == 0 && mBufferQueue.size() == 0 && mCblk->user < mCblk->frameCount) {
+        frames = mCblk->frameCount - mCblk->user;
+        pInBuffer = new Buffer;
+        pInBuffer->mBuffer = new int16_t[frames * channels];
+        pInBuffer->frameCount = frames;
+        pInBuffer->i16 = pInBuffer->mBuffer;
+        memset(pInBuffer->raw, 0, frames * channels * sizeof(int16_t));
+        mBufferQueue.add(pInBuffer);
+    }
+
+}
+
+status_t AudioFlinger::MixerThread::OutputTrack::obtainBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    int active;
+    int timeout = 0;
+    status_t result;
+    audio_track_cblk_t* cblk = mCblk;
+    uint32_t framesReq = buffer->frameCount;
+
+    LOGV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
+    buffer->frameCount  = 0;
+    
+    uint32_t framesAvail = cblk->framesAvailable();
+
+    if (framesAvail == 0) {
+        return AudioTrack::NO_MORE_BUFFERS;
+    }
+
+    if (framesReq > framesAvail) {
+        framesReq = framesAvail;
+    }
+
+    uint32_t u = cblk->user;
+    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
+
+    if (u + framesReq > bufferEnd) {
+        framesReq = bufferEnd - u;
+    }
+
+    buffer->frameCount  = framesReq;
+    buffer->raw         = (void *)cblk->buffer(u);
+    return NO_ERROR;
+}
+
+
+void AudioFlinger::MixerThread::OutputTrack::clearBufferQueue()
+{
+    size_t size = mBufferQueue.size();
+    Buffer *pBuffer;
+    
+    for (size_t i = 0; i < size; i++) {
+        pBuffer = mBufferQueue.itemAt(i);
+        delete [] pBuffer->mBuffer;
+        delete pBuffer;
+    }
+    mBufferQueue.clear();
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
+    :   RefBase(),
+        mAudioFlinger(audioFlinger),
+        mMemoryDealer(new MemoryDealer(1024*1024)),
+        mPid(pid)
+{
+    // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
+}
+
+AudioFlinger::Client::~Client()
+{
+    mAudioFlinger->removeClient(mPid);
+}
+
+const sp<MemoryDealer>& AudioFlinger::Client::heap() const
+{
+    return mMemoryDealer;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::MixerThread::Track>& track)
+    : BnAudioTrack(),
+      mTrack(track)
+{
+}
+
+AudioFlinger::TrackHandle::~TrackHandle() {
+    // just stop the track on deletion, associated resources
+    // will be freed from the main thread once all pending buffers have
+    // been played. Unless it's not in the active track list, in which
+    // case we free everything now...
+    mTrack->destroy();
+}
+
+status_t AudioFlinger::TrackHandle::start() {
+    return mTrack->start();
+}
+
+void AudioFlinger::TrackHandle::stop() {
+    mTrack->stop();
+}
+
+void AudioFlinger::TrackHandle::flush() {
+    mTrack->flush();
+}
+
+void AudioFlinger::TrackHandle::mute(bool e) {
+    mTrack->mute(e);
+}
+
+void AudioFlinger::TrackHandle::pause() {
+    mTrack->pause();
+}
+
+void AudioFlinger::TrackHandle::setVolume(float left, float right) {
+    mTrack->setVolume(left, right);
+}
+
+sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
+    return mTrack->getCblk();
+}
+
+status_t AudioFlinger::TrackHandle::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    return BnAudioTrack::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+
+sp<IAudioRecord> AudioFlinger::openRecord(
+        pid_t pid,
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int frameCount,
+        uint32_t flags,
+        status_t *status)
+{
+    sp<AudioRecordThread> thread;
+    sp<MixerThread::RecordTrack> recordTrack;
+    sp<RecordHandle> recordHandle;
+    sp<Client> client;
+    wp<Client> wclient;
+    AudioStreamIn* input = 0;
+    int inFrameCount;
+    size_t inputBufferSize;
+    status_t lStatus;
+
+    // check calling permissions
+    if (!recordingAllowed()) {
+        lStatus = PERMISSION_DENIED;
+        goto Exit;
+    }
+
+    if (uint32_t(streamType) >= AudioRecord::NUM_STREAM_TYPES) {
+        LOGE("invalid stream type");
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
+
+    if (sampleRate > MAX_SAMPLE_RATE) {
+        LOGE("Sample rate out of range");
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
+
+    if (mAudioRecordThread == 0) {
+        LOGE("Audio record thread not started");
+        lStatus = NO_INIT;
+        goto Exit;
+    }
+
+
+    // Check that audio input stream accepts requested audio parameters 
+    inputBufferSize = mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
+    if (inputBufferSize == 0) {
+        lStatus = BAD_VALUE;
+        LOGE("Bad audio input parameters: sampling rate %u, format %d, channels %d",  sampleRate, format, channelCount);
+        goto Exit;
+    }
+
+    // add client to list
+    {
+        Mutex::Autolock _l(mLock);
+        wclient = mClients.valueFor(pid);
+        if (wclient != NULL) {
+            client = wclient.promote();
+        } else {
+            client = new Client(this, pid);
+            mClients.add(pid, client);
+        }
+    }
+
+    // frameCount must be a multiple of input buffer size
+    inFrameCount = inputBufferSize/channelCount/sizeof(short);
+    frameCount = ((frameCount - 1)/inFrameCount + 1) * inFrameCount;
+
+    // create new record track and pass to record thread
+    recordTrack = new MixerThread::RecordTrack(mHardwareMixerThread, client, streamType, sampleRate,
+                                               format, channelCount, frameCount, flags);
+    if (recordTrack->getCblk() == NULL) {
+        recordTrack.clear();
+        lStatus = NO_MEMORY;
+        goto Exit;
+    }
+
+    // return to handle to client
+    recordHandle = new RecordHandle(recordTrack);
+    lStatus = NO_ERROR;
+
+Exit:
+    if (status) {
+        *status = lStatus;
+    }
+    return recordHandle;
+}
+
+status_t AudioFlinger::startRecord(MixerThread::RecordTrack* recordTrack) {
+    if (mAudioRecordThread != 0) {
+        return mAudioRecordThread->start(recordTrack);        
+    }
+    return NO_INIT;
+}
+
+void AudioFlinger::stopRecord(MixerThread::RecordTrack* recordTrack) {
+    if (mAudioRecordThread != 0) {
+        mAudioRecordThread->stop(recordTrack);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::MixerThread::RecordTrack>& recordTrack)
+    : BnAudioRecord(),
+    mRecordTrack(recordTrack)
+{
+}
+
+AudioFlinger::RecordHandle::~RecordHandle() {
+    stop();
+}
+
+status_t AudioFlinger::RecordHandle::start() {
+    LOGV("RecordHandle::start()");
+    return mRecordTrack->start();
+}
+
+void AudioFlinger::RecordHandle::stop() {
+    LOGV("RecordHandle::stop()");
+    mRecordTrack->stop();
+}
+
+sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
+    return mRecordTrack->getCblk();
+}
+
+status_t AudioFlinger::RecordHandle::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    return BnAudioRecord::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::AudioRecordThread::AudioRecordThread(AudioHardwareInterface* audioHardware) :
+    mAudioHardware(audioHardware),
+    mActive(false)
+{
+}
+
+AudioFlinger::AudioRecordThread::~AudioRecordThread()
+{
+}
+
+bool AudioFlinger::AudioRecordThread::threadLoop()
+{
+    LOGV("AudioRecordThread: start record loop");
+    AudioBufferProvider::Buffer buffer;
+    int inBufferSize = 0;
+    int inFrameCount = 0;
+    AudioStreamIn* input = 0;
+
+    mActive = 0;
+    
+    // start recording
+    while (!exitPending()) {
+        if (!mActive) {
+            mLock.lock();
+            if (!mActive && !exitPending()) {
+                LOGV("AudioRecordThread: loop stopping");
+                if (input) {
+                    delete input;
+                    input = 0;
+                }
+                mRecordTrack.clear();
+                mStopped.signal();
+
+                mWaitWorkCV.wait(mLock);
+               
+                LOGV("AudioRecordThread: loop starting");
+                if (mRecordTrack != 0) {
+                    input = mAudioHardware->openInputStream(mRecordTrack->format(), 
+                                    mRecordTrack->channelCount(), 
+                                    mRecordTrack->sampleRate(), 
+                                    &mStartStatus,
+                                    (AudioSystem::audio_in_acoustics)(mRecordTrack->mFlags >> 16));
+                    if (input != 0) {
+                        inBufferSize = input->bufferSize();
+                        inFrameCount = inBufferSize/input->frameSize();                        
+                    }
+                } else {
+                    mStartStatus = NO_INIT;
+                }
+                if (mStartStatus !=NO_ERROR) {
+                    LOGW("record start failed, status %d", mStartStatus);
+                    mActive = false;
+                    mRecordTrack.clear();                    
+                }
+                mWaitWorkCV.signal();
+            }
+            mLock.unlock();
+        } else if (mRecordTrack != 0) {
+
+            buffer.frameCount = inFrameCount;
+            if (LIKELY(mRecordTrack->getNextBuffer(&buffer) == NO_ERROR)) {
+                LOGV("AudioRecordThread read: %d frames", buffer.frameCount);
+                ssize_t bytesRead = input->read(buffer.raw, inBufferSize);
+                if (bytesRead < 0) {
+                    LOGE("Error reading audio input");
+                    sleep(1);
+                }
+                mRecordTrack->releaseBuffer(&buffer);
+                mRecordTrack->overflow();
+            }
+
+            // client isn't retrieving buffers fast enough
+            else {
+                if (!mRecordTrack->setOverflow())
+                    LOGW("AudioRecordThread: buffer overflow");
+                // Release the processor for a while before asking for a new buffer.
+                // This will give the application more chance to read from the buffer and
+                // clear the overflow.
+                usleep(5000);
+            }
+        }
+    }
+
+
+    if (input) {
+        delete input;
+    }
+    mRecordTrack.clear();
+    
+    return false;
+}
+
+status_t AudioFlinger::AudioRecordThread::start(MixerThread::RecordTrack* recordTrack)
+{
+    LOGV("AudioRecordThread::start");
+    AutoMutex lock(&mLock);
+    mActive = true;
+    // If starting the active track, just reset mActive in case a stop
+    // was pending and exit
+    if (recordTrack == mRecordTrack.get()) return NO_ERROR;
+
+    if (mRecordTrack != 0) return -EBUSY;
+
+    mRecordTrack = recordTrack;
+
+    // signal thread to start
+    LOGV("Signal record thread");
+    mWaitWorkCV.signal();
+    mWaitWorkCV.wait(mLock);
+    LOGV("Record started, status %d", mStartStatus);
+    return mStartStatus;
+}
+
+void AudioFlinger::AudioRecordThread::stop(MixerThread::RecordTrack* recordTrack) {
+    LOGV("AudioRecordThread::stop");
+    AutoMutex lock(&mLock);
+    if (mActive && (recordTrack == mRecordTrack.get())) {
+        mActive = false;
+        mStopped.wait(mLock);
+    }
+}
+
+void AudioFlinger::AudioRecordThread::exit()
+{
+    LOGV("AudioRecordThread::exit");
+    {
+        AutoMutex lock(&mLock);
+        requestExit();
+        mWaitWorkCV.signal();
+    }
+    requestExitAndWait();
+}
+
+status_t AudioFlinger::AudioRecordThread::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    pid_t pid = 0;
+
+    if (mRecordTrack != 0 && mRecordTrack->mClient != 0) {
+        snprintf(buffer, SIZE, "Record client pid: %d\n", mRecordTrack->mClient->pid());
+        result.append(buffer);
+    } else {
+        result.append("No record client\n");
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    return BnAudioFlinger::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+void AudioFlinger::instantiate() {
+    defaultServiceManager()->addService(
+            String16("media.audio_flinger"), new AudioFlinger());
+}
+
+}; // namespace android
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
new file mode 100644
index 0000000..77f064b
--- /dev/null
+++ b/libs/audioflinger/AudioFlinger.h
@@ -0,0 +1,637 @@
+/* //device/include/server/AudioFlinger/AudioFlinger.h
+**
+** Copyright 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.
+*/
+
+#ifndef ANDROID_AUDIO_FLINGER_H
+#define ANDROID_AUDIO_FLINGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <media/IAudioFlinger.h>
+#include <media/IAudioFlingerClient.h>
+#include <media/IAudioTrack.h>
+#include <media/IAudioRecord.h>
+#include <media/AudioTrack.h>
+
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <utils/MemoryDealer.h>
+#include <utils/KeyedVector.h>
+#include <utils/SortedVector.h>
+#include <utils/Vector.h>
+
+#include <hardware_legacy/AudioHardwareInterface.h>
+
+#include "AudioBufferProvider.h"
+
+namespace android {
+
+class audio_track_cblk_t;
+class AudioMixer;
+class AudioBuffer;
+
+
+// ----------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+
+// ----------------------------------------------------------------------------
+
+static const nsecs_t kStandbyTimeInNsecs = seconds(3);
+
+class AudioFlinger : public BnAudioFlinger, public IBinder::DeathRecipient 
+{
+public:
+    static void instantiate();
+
+    virtual     status_t    dump(int fd, const Vector<String16>& args);
+
+    // IAudioFlinger interface
+    virtual sp<IAudioTrack> createTrack(
+                                pid_t pid,
+                                int streamType,
+                                uint32_t sampleRate,
+                                int format,
+                                int channelCount,
+                                int frameCount,
+                                uint32_t flags,
+                                const sp<IMemory>& sharedBuffer,
+                                status_t *status);
+
+    virtual     uint32_t    sampleRate(int output) const;
+    virtual     int         channelCount(int output) const;
+    virtual     int         format(int output) const;
+    virtual     size_t      frameCount(int output) const;
+    virtual     uint32_t    latency(int output) const;
+
+    virtual     status_t    setMasterVolume(float value);
+    virtual     status_t    setMasterMute(bool muted);
+
+    virtual     float       masterVolume() const;
+    virtual     bool        masterMute() const;
+
+    virtual     status_t    setStreamVolume(int stream, float value);
+    virtual     status_t    setStreamMute(int stream, bool muted);
+
+    virtual     float       streamVolume(int stream) const;
+    virtual     bool        streamMute(int stream) const;
+
+    virtual     status_t    setRouting(int mode, uint32_t routes, uint32_t mask);
+    virtual     uint32_t    getRouting(int mode) const;
+
+    virtual     status_t    setMode(int mode);
+    virtual     int         getMode() const;
+
+    virtual     status_t    setMicMute(bool state);
+    virtual     bool        getMicMute() const;
+
+    virtual     bool        isMusicActive() const;
+
+    virtual     bool        isA2dpEnabled() const;
+
+    virtual     status_t    setParameter(const char* key, const char* value);
+
+    virtual     void        registerClient(const sp<IAudioFlingerClient>& client);
+    
+    virtual     size_t      getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
+    
+    virtual     void        wakeUp();
+    
+    // IBinder::DeathRecipient
+    virtual     void        binderDied(const wp<IBinder>& who);
+
+    enum hardware_call_state {
+        AUDIO_HW_IDLE = 0,
+        AUDIO_HW_INIT,
+        AUDIO_HW_OUTPUT_OPEN,
+        AUDIO_HW_OUTPUT_CLOSE,
+        AUDIO_HW_INPUT_OPEN,
+        AUDIO_HW_INPUT_CLOSE,
+        AUDIO_HW_STANDBY,
+        AUDIO_HW_SET_MASTER_VOLUME,
+        AUDIO_HW_GET_ROUTING,
+        AUDIO_HW_SET_ROUTING,
+        AUDIO_HW_GET_MODE,
+        AUDIO_HW_SET_MODE,
+        AUDIO_HW_GET_MIC_MUTE,
+        AUDIO_HW_SET_MIC_MUTE,
+        AUDIO_SET_VOICE_VOLUME,
+        AUDIO_SET_PARAMETER,
+    };
+
+    // record interface
+    virtual sp<IAudioRecord> openRecord(
+                                pid_t pid,
+                                int streamType,
+                                uint32_t sampleRate,
+                                int format,
+                                int channelCount,
+                                int frameCount,
+                                uint32_t flags,
+                                status_t *status);
+
+    virtual     status_t    onTransact(
+                                uint32_t code,
+                                const Parcel& data,
+                                Parcel* reply,
+                                uint32_t flags);
+
+private:
+                            AudioFlinger();
+    virtual                 ~AudioFlinger();
+    
+    void                    setOutput(int outputType);
+    void                    doSetOutput(int outputType);
+
+#ifdef WITH_A2DP
+    void                    setA2dpEnabled(bool enable);
+#endif
+    static bool             streamForcedToSpeaker(int streamType);
+    
+    // Management of forced route to speaker for certain track types.
+    enum force_speaker_command {
+        ACTIVE_TRACK_ADDED = 0,
+        ACTIVE_TRACK_REMOVED,
+        CHECK_ROUTE_RESTORE_TIME,
+        FORCE_ROUTE_RESTORE
+    };
+    void                    handleForcedSpeakerRoute(int command);
+
+    // Internal dump utilites.
+    status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
+    status_t dumpClients(int fd, const Vector<String16>& args);
+    status_t dumpInternals(int fd, const Vector<String16>& args);
+
+    // --- Client ---
+    class Client : public RefBase {
+    public:
+                            Client(const sp<AudioFlinger>& audioFlinger, pid_t pid);
+        virtual             ~Client();
+        const sp<MemoryDealer>&     heap() const;
+        pid_t               pid() const { return mPid; }
+    private:
+                            Client(const Client&);
+                            Client& operator = (const Client&);
+        sp<AudioFlinger>    mAudioFlinger;
+        sp<MemoryDealer>    mMemoryDealer;
+        pid_t               mPid;
+    };
+
+
+    class TrackHandle;
+    class RecordHandle;
+    class AudioRecordThread;
+
+    
+    // --- MixerThread ---
+    class MixerThread : public Thread {
+    public:
+        
+        // --- Track ---
+
+        // base for record and playback
+        class TrackBase : public AudioBufferProvider, public RefBase {
+
+        public:
+            enum track_state {
+                IDLE,
+                TERMINATED,
+                STOPPED,
+                RESUMING,
+                ACTIVE,
+                PAUSING,
+                PAUSED
+            };
+
+            enum track_flags {
+                STEPSERVER_FAILED = 0x01, //  StepServer could not acquire cblk->lock mutex
+                SYSTEM_FLAGS_MASK = 0x0000ffffUL,
+                // The upper 16 bits are used for track-specific flags.
+            };
+
+                                TrackBase(const sp<MixerThread>& mixerThread,
+                                        const sp<Client>& client,
+                                        int streamType,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        uint32_t flags,
+                                        const sp<IMemory>& sharedBuffer);
+                                ~TrackBase();
+
+            virtual status_t    start() = 0;
+            virtual void        stop() = 0;
+                    sp<IMemory> getCblk() const;
+
+        protected:
+            friend class MixerThread;
+            friend class RecordHandle;
+            friend class AudioRecordThread;
+
+                                TrackBase(const TrackBase&);
+                                TrackBase& operator = (const TrackBase&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
+            virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+
+            audio_track_cblk_t* cblk() const {
+                return mCblk;
+            }
+
+            int type() const {
+                return mStreamType;
+            }
+
+            int format() const {
+                return mFormat;
+            }
+
+            int channelCount() const ;
+
+            int sampleRate() const;
+
+            void* getBuffer(uint32_t offset, uint32_t frames) const;
+
+            int name() const {
+                return mName;
+            }
+
+            bool isStopped() const {
+                return mState == STOPPED;
+            }
+
+            bool isTerminated() const {
+                return mState == TERMINATED;
+            }
+
+            bool step();
+            void reset();
+
+            sp<MixerThread>     mMixerThread;
+            sp<Client>          mClient;
+            sp<IMemory>         mCblkMemory;
+            audio_track_cblk_t* mCblk;
+            int                 mStreamType;
+            void*               mBuffer;
+            void*               mBufferEnd;
+            uint32_t            mFrameCount;
+            int                 mName;
+            // we don't really need a lock for these
+            int                 mState;
+            int                 mClientTid;
+            uint8_t             mFormat;
+            uint32_t            mFlags;
+        };
+
+        // playback track
+        class Track : public TrackBase {
+        public:
+                                Track(  const sp<MixerThread>& mixerThread,
+                                        const sp<Client>& client,
+                                        int streamType,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        const sp<IMemory>& sharedBuffer);
+                                ~Track();
+
+                    void        dump(char* buffer, size_t size);
+            virtual status_t    start();
+            virtual void        stop();
+                    void        pause();
+
+                    void        flush();
+                    void        destroy();
+                    void        mute(bool);
+                    void        setVolume(float left, float right);
+
+        protected:
+            friend class MixerThread;
+            friend class AudioFlinger;
+            friend class AudioFlinger::TrackHandle;
+
+                                Track(const Track&);
+                                Track& operator = (const Track&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+
+            bool isMuted() const {
+                return (mMute || mMixerThread->mStreamTypes[mStreamType].mute);
+            }
+
+            bool isPausing() const {
+                return mState == PAUSING;
+            }
+
+            bool isPaused() const {
+                return mState == PAUSED;
+            }
+
+            bool isReady() const;
+
+            void setPaused() { mState = PAUSED; }
+            void reset();
+
+            // we don't really need a lock for these
+            float               mVolume[2];
+            volatile bool       mMute;
+            // FILLED state is used for suppressing volume ramp at begin of playing
+            enum {FS_FILLING, FS_FILLED, FS_ACTIVE};
+            mutable uint8_t     mFillingUpStatus;
+            int8_t              mRetryCount;
+            sp<IMemory>         mSharedBuffer;
+            bool                mResetDone;
+        };  // end of Track
+
+        // record track
+        class RecordTrack : public TrackBase {
+        public:
+                                RecordTrack(const sp<MixerThread>& mixerThread,
+                                        const sp<Client>& client,
+                                        int streamType,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        uint32_t flags);
+                                ~RecordTrack();
+
+            virtual status_t    start();
+            virtual void        stop();
+
+                    bool        overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; }
+                    bool        setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
+
+        private:
+            friend class AudioFlinger;
+            friend class AudioFlinger::RecordHandle;
+            friend class AudioFlinger::AudioRecordThread;
+            friend class MixerThread;
+
+                                RecordTrack(const Track&);
+                                RecordTrack& operator = (const Track&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+
+            bool                mOverflow;
+        };
+
+        // playback track
+        class OutputTrack : public Track {
+        public:
+            
+            class Buffer: public AudioBufferProvider::Buffer {
+            public:
+                int16_t *mBuffer;
+            };
+            
+                                OutputTrack(  const sp<MixerThread>& mixerThread,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount);
+                                ~OutputTrack();
+
+            virtual status_t    start();
+            virtual void        stop();
+                    void        write(int16_t* data, uint32_t frames);
+                    bool        bufferQueueEmpty() { return (mBufferQueue.size() == 0) ? true : false; }
+
+        private:
+
+            status_t            obtainBuffer(AudioBufferProvider::Buffer* buffer);
+            void                clearBufferQueue();
+            
+            sp<MixerThread>             mOutputMixerThread;
+            Vector < Buffer* >          mBufferQueue;
+            AudioBufferProvider::Buffer mOutBuffer;
+            uint32_t                    mFramesWritten;
+            
+         };  // end of OutputTrack
+
+        MixerThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType);
+        virtual             ~MixerThread();
+
+        virtual     status_t    dump(int fd, const Vector<String16>& args);
+
+        // Thread virtuals
+        virtual     bool        threadLoop();
+        virtual     status_t    readyToRun();
+        virtual     void        onFirstRef();
+
+        virtual     uint32_t    sampleRate() const;
+        virtual     int         channelCount() const;
+        virtual     int         format() const;
+        virtual     size_t      frameCount() const;
+        virtual     uint32_t    latency() const;
+
+        virtual     status_t    setMasterVolume(float value);
+        virtual     status_t    setMasterMute(bool muted);
+
+        virtual     float       masterVolume() const;
+        virtual     bool        masterMute() const;
+
+        virtual     status_t    setStreamVolume(int stream, float value);
+        virtual     status_t    setStreamMute(int stream, bool muted);
+
+        virtual     float       streamVolume(int stream) const;
+        virtual     bool        streamMute(int stream) const;
+
+                    bool        isMusicActive() const;
+        
+                    
+        sp<Track> createTrack(
+                                    const sp<AudioFlinger::Client>& client,
+                                    int streamType,
+                                    uint32_t sampleRate,
+                                    int format,
+                                    int channelCount,
+                                    int frameCount,
+                                    const sp<IMemory>& sharedBuffer,
+                                    status_t *status);
+
+                    void        wakeUp() { mWaitWorkCV.broadcast(); }
+                    
+                    void        getTracks(SortedVector < sp<Track> >& tracks,
+                                          SortedVector < wp<Track> >& activeTracks);
+                    void        putTracks(SortedVector < sp<Track> >& tracks,
+                                          SortedVector < wp<Track> >& activeTracks);
+                    void        setOuputTrack(OutputTrack *track) { mOutputTrack = track; }
+                    
+        struct  stream_type_t {
+            stream_type_t()
+                :   volume(1.0f),
+                    mute(false)
+            {
+            }
+            float       volume;
+            bool        mute;
+        };
+
+    private:
+
+
+        friend class AudioFlinger;
+        friend class Track;
+        friend class TrackBase;
+        friend class RecordTrack;
+        
+        MixerThread(const Client&);
+        MixerThread& operator = (const MixerThread&);
+  
+        status_t    addTrack(const sp<Track>& track);
+        void        removeTrack(wp<Track> track, int name);
+        void        remove_track_l(wp<Track> track, int name);
+        void        destroyTrack(const sp<Track>& track);
+        int         getTrackName();
+        void        deleteTrackName(int name);
+        void        addActiveTrack(const wp<Track>& t);
+        void        removeActiveTrack(const wp<Track>& t);
+        size_t      getOutputFrameCount();
+
+        status_t    dumpInternals(int fd, const Vector<String16>& args);
+        status_t    dumpTracks(int fd, const Vector<String16>& args);
+        
+        sp<AudioFlinger>                mAudioFlinger;       
+        mutable     Mutex               mLock;
+        mutable     Condition           mWaitWorkCV;
+        SortedVector< wp<Track> >       mActiveTracks;
+        SortedVector< sp<Track> >       mTracks;
+        stream_type_t                   mStreamTypes[AudioSystem::NUM_STREAM_TYPES];
+        AudioMixer*                     mAudioMixer;
+        AudioStreamOut*                 mOutput;
+        int                             mOutputType;
+        uint32_t                        mSampleRate;
+        size_t                          mFrameCount;
+        int                             mChannelCount;
+        int                             mFormat;
+        int16_t*                        mMixBuffer;
+        float                           mMasterVolume;
+        bool                            mMasterMute;
+        nsecs_t                         mLastWriteTime;
+        int                             mNumWrites;
+        int                             mNumDelayedWrites;
+        bool                            mStandby;
+        bool                            mInWrite;
+        sp <OutputTrack>                mOutputTrack;
+    };
+
+    
+    friend class AudioBuffer;
+
+    class TrackHandle : public android::BnAudioTrack {
+    public:
+                            TrackHandle(const sp<MixerThread::Track>& track);
+        virtual             ~TrackHandle();
+        virtual status_t    start();
+        virtual void        stop();
+        virtual void        flush();
+        virtual void        mute(bool);
+        virtual void        pause();
+        virtual void        setVolume(float left, float right);
+        virtual sp<IMemory> getCblk() const;
+        virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+    private:
+        sp<MixerThread::Track> mTrack;
+    };
+
+    friend class Client;
+    friend class MixerThread::Track;
+
+
+                void        removeClient(pid_t pid);
+
+
+
+    class RecordHandle : public android::BnAudioRecord {
+    public:
+        RecordHandle(const sp<MixerThread::RecordTrack>& recordTrack);
+        virtual             ~RecordHandle();
+        virtual status_t    start();
+        virtual void        stop();
+        virtual sp<IMemory> getCblk() const;
+        virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+    private:
+        sp<MixerThread::RecordTrack> mRecordTrack;
+    };
+
+    // record thread
+    class AudioRecordThread : public Thread
+    {
+    public:
+        AudioRecordThread(AudioHardwareInterface* audioHardware);
+        virtual             ~AudioRecordThread();
+        virtual bool        threadLoop();
+        virtual status_t    readyToRun() { return NO_ERROR; }
+        virtual void        onFirstRef() {}
+
+                status_t    start(MixerThread::RecordTrack* recordTrack);
+                void        stop(MixerThread::RecordTrack* recordTrack);
+                void        exit();
+                status_t    dump(int fd, const Vector<String16>& args);
+
+    private:
+                AudioRecordThread();
+                AudioHardwareInterface              *mAudioHardware;
+                sp<MixerThread::RecordTrack>        mRecordTrack;
+                Mutex                               mLock;
+                Condition                           mWaitWorkCV;
+                Condition                           mStopped;
+                volatile bool                       mActive;
+                status_t                            mStartStatus;
+    };
+
+    friend class AudioRecordThread;
+    friend class MixerThread;
+
+                status_t    startRecord(MixerThread::RecordTrack* recordTrack);
+                void        stopRecord(MixerThread::RecordTrack* recordTrack);
+                
+                void        handleOutputSwitch();
+
+    mutable     Mutex                                       mHardwareLock;
+    mutable     Mutex                                       mLock;
+                DefaultKeyedVector< pid_t, wp<Client> >     mClients;
+
+                sp<MixerThread>                     mA2dpMixerThread;
+                sp<MixerThread>                     mHardwareMixerThread;
+                AudioHardwareInterface*             mAudioHardware;
+                AudioHardwareInterface*             mA2dpAudioInterface;
+                sp<AudioRecordThread>               mAudioRecordThread;
+                bool                                mA2dpEnabled;
+                bool                                mA2dpEnabledReq;
+    mutable     int                                 mHardwareStatus;
+                SortedVector< wp<IBinder> >         mNotificationClients;
+                int                                 mForcedSpeakerCount;
+                uint32_t                            mSavedRoute;
+                uint32_t                            mForcedRoute;
+                nsecs_t                             mRouteRestoreTime;
+                bool                                mMusicMuteSaved;
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_FLINGER_H
diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp
new file mode 100644
index 0000000..62beada
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareGeneric.cpp
@@ -0,0 +1,313 @@
+/*
+**
+** Copyright 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.
+*/
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sched.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#define LOG_TAG "AudioHardware"
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include "AudioHardwareGeneric.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static char const * const kAudioDeviceName = "/dev/eac";
+
+// ----------------------------------------------------------------------------
+
+AudioHardwareGeneric::AudioHardwareGeneric()
+    : mOutput(0), mInput(0),  mFd(-1), mMicMute(false)
+{
+    mFd = ::open(kAudioDeviceName, O_RDWR);
+}
+
+AudioHardwareGeneric::~AudioHardwareGeneric()
+{
+    if (mFd >= 0) ::close(mFd);
+    delete mOutput;
+    delete mInput;
+}
+
+status_t AudioHardwareGeneric::initCheck()
+{
+    if (mFd >= 0) {
+        if (::access(kAudioDeviceName, O_RDWR) == NO_ERROR)
+            return NO_ERROR;
+    }
+    return NO_INIT;
+}
+
+AudioStreamOut* AudioHardwareGeneric::openOutputStream(
+        int format, int channelCount, uint32_t sampleRate, status_t *status)
+{
+    AutoMutex lock(mLock);
+
+    // only one output stream allowed
+    if (mOutput) {
+        if (status) {
+            *status = INVALID_OPERATION;
+        }
+        return 0;
+    }
+
+    // create new output stream
+    AudioStreamOutGeneric* out = new AudioStreamOutGeneric();
+    status_t lStatus = out->set(this, mFd, format, channelCount, sampleRate);
+    if (status) {
+        *status = lStatus;
+    }
+    if (lStatus == NO_ERROR) {
+        mOutput = out;
+    } else {
+        delete out;
+    }
+    return mOutput;
+}
+
+void AudioHardwareGeneric::closeOutputStream(AudioStreamOutGeneric* out) {
+    if (out == mOutput) mOutput = 0;
+}
+
+AudioStreamIn* AudioHardwareGeneric::openInputStream(
+        int format, int channelCount, uint32_t sampleRate, status_t *status,
+        AudioSystem::audio_in_acoustics acoustics)
+{
+    AutoMutex lock(mLock);
+
+    // only one input stream allowed
+    if (mInput) {
+        if (status) {
+            *status = INVALID_OPERATION;
+        }
+        return 0;
+    }
+
+    // create new output stream
+    AudioStreamInGeneric* in = new AudioStreamInGeneric();
+    status_t lStatus = in->set(this, mFd, format, channelCount, sampleRate, acoustics);
+    if (status) {
+        *status = lStatus;
+    }
+    if (lStatus == NO_ERROR) {
+        mInput = in;
+    } else {
+        delete in;
+    }
+    return mInput;
+}
+
+void AudioHardwareGeneric::closeInputStream(AudioStreamInGeneric* in) {
+    if (in == mInput) mInput = 0;
+}
+
+status_t AudioHardwareGeneric::setVoiceVolume(float v)
+{
+    // Implement: set voice volume
+    return NO_ERROR;
+}
+
+status_t AudioHardwareGeneric::setMasterVolume(float v)
+{
+    // Implement: set master volume
+    // return error - software mixer will handle it
+    return INVALID_OPERATION;
+}
+
+status_t AudioHardwareGeneric::setMicMute(bool state)
+{
+    mMicMute = state;
+    return NO_ERROR;
+}
+
+status_t AudioHardwareGeneric::getMicMute(bool* state)
+{
+    *state = mMicMute;
+    return NO_ERROR;
+}
+
+status_t AudioHardwareGeneric::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    result.append("AudioHardwareGeneric::dumpInternals\n");
+    snprintf(buffer, SIZE, "\tmFd: %d mMicMute: %s\n",  mFd, mMicMute? "true": "false");
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioHardwareGeneric::dump(int fd, const Vector<String16>& args)
+{
+    dumpInternals(fd, args);
+    if (mInput) {
+        mInput->dump(fd, args);
+    }
+    if (mOutput) {
+        mOutput->dump(fd, args);
+    }
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+status_t AudioStreamOutGeneric::set(
+        AudioHardwareGeneric *hw,
+        int fd,
+        int format,
+        int channels,
+        uint32_t rate)
+{
+    // fix up defaults
+    if (format == 0) format = AudioSystem::PCM_16_BIT;
+    if (channels == 0) channels = channelCount();
+    if (rate == 0) rate = sampleRate();
+
+    // check values
+    if ((format != AudioSystem::PCM_16_BIT) ||
+            (channels != channelCount()) ||
+            (rate != sampleRate()))
+        return BAD_VALUE;
+
+    mAudioHardware = hw;
+    mFd = fd;
+    return NO_ERROR;
+}
+
+AudioStreamOutGeneric::~AudioStreamOutGeneric()
+{
+    if (mAudioHardware)
+        mAudioHardware->closeOutputStream(this);
+}
+
+ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
+{
+    Mutex::Autolock _l(mLock);
+    return ssize_t(::write(mFd, buffer, bytes));
+}
+
+status_t AudioStreamOutGeneric::standby()
+{
+    // Implement: audio hardware to standby mode
+    return NO_ERROR;
+}
+
+status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "AudioStreamOutGeneric::dump\n");
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tformat: %d\n", format());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+// record functions
+status_t AudioStreamInGeneric::set(
+        AudioHardwareGeneric *hw,
+        int fd,
+        int format,
+        int channels,
+        uint32_t rate,
+        AudioSystem::audio_in_acoustics acoustics)
+{
+    // FIXME: remove logging
+    LOGD("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, format, channels, rate);
+    // check values
+    if ((format != AudioSystem::PCM_16_BIT) ||
+            (channels != channelCount()) ||
+            (rate != sampleRate())) {
+        LOGE("Error opening input channel");
+        return BAD_VALUE;
+    }
+
+    mAudioHardware = hw;
+    mFd = fd;
+    return NO_ERROR;
+}
+
+AudioStreamInGeneric::~AudioStreamInGeneric()
+{
+    // FIXME: remove logging
+    LOGD("AudioStreamInGeneric destructor");
+    if (mAudioHardware)
+        mAudioHardware->closeInputStream(this);
+}
+
+ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
+{
+    // FIXME: remove logging
+    LOGD("AudioStreamInGeneric::read(%p, %d) from fd %d", buffer, bytes, mFd);
+    AutoMutex lock(mLock);
+    if (mFd < 0) {
+        LOGE("Attempt to read from unopened device");
+        return NO_INIT;
+    }
+    return ::read(mFd, buffer, bytes);
+}
+
+status_t AudioStreamInGeneric::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "AudioStreamInGeneric::dump\n");
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tformat: %d\n", format());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/audioflinger/AudioHardwareGeneric.h b/libs/audioflinger/AudioHardwareGeneric.h
new file mode 100644
index 0000000..c949aa1
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareGeneric.h
@@ -0,0 +1,141 @@
+/*
+**
+** Copyright 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.
+*/
+
+#ifndef ANDROID_AUDIO_HARDWARE_GENERIC_H
+#define ANDROID_AUDIO_HARDWARE_GENERIC_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+
+#include <hardware_legacy/AudioHardwareBase.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class AudioHardwareGeneric;
+
+class AudioStreamOutGeneric : public AudioStreamOut {
+public:
+                        AudioStreamOutGeneric() : mAudioHardware(0), mFd(-1) {}
+    virtual             ~AudioStreamOutGeneric();
+
+    virtual status_t    set(
+            AudioHardwareGeneric *hw,
+            int mFd,
+            int format,
+            int channelCount,
+            uint32_t sampleRate);
+
+    virtual uint32_t    sampleRate() const { return 44100; }
+    virtual size_t      bufferSize() const { return 4096; }
+    virtual int         channelCount() const { return 2; }
+    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
+    virtual uint32_t    latency() const { return 20; }
+    virtual status_t    setVolume(float volume) { return INVALID_OPERATION; }
+    virtual ssize_t     write(const void* buffer, size_t bytes);
+    virtual status_t    standby();
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+private:
+    AudioHardwareGeneric *mAudioHardware;
+    Mutex   mLock;
+    int     mFd;
+};
+
+class AudioStreamInGeneric : public AudioStreamIn {
+public:
+                        AudioStreamInGeneric() : mAudioHardware(0), mFd(-1) {}
+    virtual             ~AudioStreamInGeneric();
+
+    virtual status_t    set(
+            AudioHardwareGeneric *hw,
+            int mFd,
+            int format,
+            int channelCount,
+            uint32_t sampleRate,
+            AudioSystem::audio_in_acoustics acoustics);
+
+    uint32_t    sampleRate() const { return 8000; }
+    virtual size_t      bufferSize() const { return 320; }
+    virtual int         channelCount() const { return 1; }
+    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
+    virtual status_t    setGain(float gain) { return INVALID_OPERATION; }
+    virtual ssize_t     read(void* buffer, ssize_t bytes);
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+    virtual status_t    standby() { return NO_ERROR; }
+
+private:
+    AudioHardwareGeneric *mAudioHardware;
+    Mutex   mLock;
+    int     mFd;
+};
+
+
+class AudioHardwareGeneric : public AudioHardwareBase
+{
+public:
+                        AudioHardwareGeneric();
+    virtual             ~AudioHardwareGeneric();
+    virtual status_t    initCheck();
+    virtual status_t    setVoiceVolume(float volume);
+    virtual status_t    setMasterVolume(float volume);
+
+    // mic mute
+    virtual status_t    setMicMute(bool state);
+    virtual status_t    getMicMute(bool* state);
+
+    virtual status_t    setParameter(const char* key, const char* value)
+            { return NO_ERROR; }
+
+    // create I/O streams
+    virtual AudioStreamOut* openOutputStream(
+            int format=0,
+            int channelCount=0,
+            uint32_t sampleRate=0,
+            status_t *status=0);
+
+    virtual AudioStreamIn* openInputStream(
+            int format,
+            int channelCount,
+            uint32_t sampleRate,
+            status_t *status,
+            AudioSystem::audio_in_acoustics acoustics);
+
+            void            closeOutputStream(AudioStreamOutGeneric* out);
+            void            closeInputStream(AudioStreamInGeneric* in);
+protected:
+    virtual status_t        doRouting() { return NO_ERROR; }
+    virtual status_t        dump(int fd, const Vector<String16>& args);
+
+private:
+    status_t                dumpInternals(int fd, const Vector<String16>& args);
+
+    Mutex                   mLock;
+    AudioStreamOutGeneric   *mOutput;
+    AudioStreamInGeneric    *mInput;
+    int                     mFd;
+    bool                    mMicMute;
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_HARDWARE_GENERIC_H
diff --git a/libs/audioflinger/AudioHardwareInterface.cpp b/libs/audioflinger/AudioHardwareInterface.cpp
new file mode 100644
index 0000000..ac76a19
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareInterface.cpp
@@ -0,0 +1,247 @@
+/*
+**
+** Copyright 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.
+*/
+
+#include <cutils/properties.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LOG_TAG "AudioHardwareInterface"
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include "AudioHardwareStub.h"
+#include "AudioHardwareGeneric.h"
+
+//#define DUMP_FLINGER_OUT        // if defined allows recording samples in a file
+#ifdef DUMP_FLINGER_OUT
+#include "AudioDumpInterface.h"
+#endif
+
+
+// change to 1 to log routing calls
+#define LOG_ROUTING_CALLS 0
+
+namespace android {
+
+#if LOG_ROUTING_CALLS
+static const char* routingModeStrings[] =
+{
+    "OUT OF RANGE",
+    "INVALID",
+    "CURRENT",
+    "NORMAL",
+    "RINGTONE",
+    "IN_CALL"
+};
+
+static const char* routeStrings[] =
+{
+    "EARPIECE ",
+    "SPEAKER ",
+    "BLUETOOTH ",
+    "HEADSET "
+    "BLUETOOTH_A2DP "
+};
+static const char* routeNone = "NONE";
+
+static const char* displayMode(int mode)
+{
+    if ((mode < -2) || (mode > 2))
+        return routingModeStrings[0];
+    return routingModeStrings[mode+3];
+}
+
+static const char* displayRoutes(uint32_t routes)
+{
+    static char routeStr[80];
+    if (routes == 0)
+        return routeNone;
+    routeStr[0] = 0;
+    int bitMask = 1;
+    for (int i = 0; i < 4; ++i, bitMask <<= 1) {
+        if (routes & bitMask) {
+            strcat(routeStr, routeStrings[i]);
+        }
+    }
+    routeStr[strlen(routeStr)-1] = 0;
+    return routeStr;
+}
+#endif
+
+// ----------------------------------------------------------------------------
+
+AudioHardwareInterface* AudioHardwareInterface::create()
+{
+    /*
+     * FIXME: This code needs to instantiate the correct audio device
+     * interface. For now - we use compile-time switches.
+     */
+    AudioHardwareInterface* hw = 0;
+    char value[PROPERTY_VALUE_MAX];
+
+#ifdef GENERIC_AUDIO
+    hw = new AudioHardwareGeneric();
+#else
+    // if running in emulation - use the emulator driver
+    if (property_get("ro.kernel.qemu", value, 0)) {
+        LOGD("Running in emulation - using generic audio driver");
+        hw = new AudioHardwareGeneric();
+    }
+    else {
+        LOGV("Creating Vendor Specific AudioHardware");
+        hw = createAudioHardware();
+    }
+#endif
+    if (hw->initCheck() != NO_ERROR) {
+        LOGW("Using stubbed audio hardware. No sound will be produced.");
+        delete hw;
+        hw = new AudioHardwareStub();
+    }
+    
+#ifdef DUMP_FLINGER_OUT
+    // This code adds a record of buffers in a file to write calls made by AudioFlinger.
+    // It replaces the current AudioHardwareInterface object by an intermediate one which
+    // will record buffers in a file (after sending them to hardware) for testing purpose.
+    // This feature is enabled by defining symbol DUMP_FLINGER_OUT.
+    // The output file is FLINGER_DUMP_NAME. Pause are not recorded in the file.
+    
+    hw = new AudioDumpInterface(hw);    // replace interface
+#endif
+    return hw;
+}
+
+AudioStreamOut::~AudioStreamOut()
+{
+}
+
+AudioStreamIn::~AudioStreamIn() {}
+
+AudioHardwareBase::AudioHardwareBase()
+{
+    // force a routing update on initialization
+    memset(&mRoutes, 0, sizeof(mRoutes));
+    mMode = 0;
+}
+
+// generics for audio routing - the real work is done in doRouting
+status_t AudioHardwareBase::setRouting(int mode, uint32_t routes)
+{
+#if LOG_ROUTING_CALLS
+    LOGD("setRouting: mode=%s, routes=[%s]", displayMode(mode), displayRoutes(routes));
+#endif
+    if (mode == AudioSystem::MODE_CURRENT)
+        mode = mMode;
+    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
+        return BAD_VALUE;
+    uint32_t old = mRoutes[mode];
+    mRoutes[mode] = routes;
+    if ((mode != mMode) || (old == routes))
+        return NO_ERROR;
+#if LOG_ROUTING_CALLS
+    const char* oldRouteStr = strdup(displayRoutes(old));
+    LOGD("doRouting: mode=%s, old route=[%s], new route=[%s]",
+           displayMode(mode), oldRouteStr, displayRoutes(routes));
+    delete oldRouteStr;
+#endif
+    return doRouting();
+}
+
+status_t AudioHardwareBase::getRouting(int mode, uint32_t* routes)
+{
+    if (mode == AudioSystem::MODE_CURRENT)
+        mode = mMode;
+    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
+        return BAD_VALUE;
+    *routes = mRoutes[mode];
+#if LOG_ROUTING_CALLS
+    LOGD("getRouting: mode=%s, routes=[%s]",
+           displayMode(mode), displayRoutes(*routes));
+#endif
+    return NO_ERROR;
+}
+
+status_t AudioHardwareBase::setMode(int mode)
+{
+#if LOG_ROUTING_CALLS
+    LOGD("setMode(%s)", displayMode(mode));
+#endif
+    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
+        return BAD_VALUE;
+    if (mMode == mode)
+        return NO_ERROR;
+#if LOG_ROUTING_CALLS
+    LOGD("doRouting: old mode=%s, new mode=%s route=[%s]",
+            displayMode(mMode), displayMode(mode), displayRoutes(mRoutes[mode]));
+#endif
+    mMode = mode;
+    return doRouting();
+}
+
+status_t AudioHardwareBase::getMode(int* mode)
+{
+    // Implement: set audio routing
+    *mode = mMode;
+    return NO_ERROR;
+}
+
+status_t AudioHardwareBase::setParameter(const char* key, const char* value)
+{
+    // default implementation is to ignore
+    return NO_ERROR;
+}
+
+
+// default implementation
+size_t AudioHardwareBase::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
+{
+    if (sampleRate != 8000) {
+        LOGW("getInputBufferSize bad sampling rate: %d", sampleRate);
+        return 0;
+    }
+    if (format != AudioSystem::PCM_16_BIT) {
+        LOGW("getInputBufferSize bad format: %d", format);
+        return 0;
+    }
+    if (channelCount != 1) {
+        LOGW("getInputBufferSize bad channel count: %d", channelCount);
+        return 0;
+    }
+
+    return 320;
+}
+
+status_t AudioHardwareBase::dumpState(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "AudioHardwareBase::dumpState\n");
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tmMode: %d\n", mMode);
+    result.append(buffer);
+    for (int i = 0, n = AudioSystem::NUM_MODES; i < n; ++i) {
+        snprintf(buffer, SIZE, "\tmRoutes[%d]: %d\n", i, mRoutes[i]);
+        result.append(buffer);
+    }
+    ::write(fd, result.string(), result.size());
+    dump(fd, args);  // Dump the state of the concrete child.
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp
new file mode 100644
index 0000000..b13cb1c
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareStub.cpp
@@ -0,0 +1,185 @@
+/* //device/servers/AudioFlinger/AudioHardwareStub.cpp
+**
+** Copyright 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.
+*/
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <utils/String8.h>
+
+#include "AudioHardwareStub.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+AudioHardwareStub::AudioHardwareStub() : mMicMute(false)
+{
+}
+
+AudioHardwareStub::~AudioHardwareStub()
+{
+}
+
+status_t AudioHardwareStub::initCheck()
+{
+    return NO_ERROR;
+}
+
+AudioStreamOut* AudioHardwareStub::openOutputStream(
+        int format, int channelCount, uint32_t sampleRate, status_t *status)
+{
+    AudioStreamOutStub* out = new AudioStreamOutStub();
+    status_t lStatus = out->set(format, channelCount, sampleRate);
+    if (status) {
+        *status = lStatus;
+    }
+    if (lStatus == NO_ERROR)
+        return out;
+    delete out;
+    return 0;
+}
+
+AudioStreamIn* AudioHardwareStub::openInputStream(
+        int format, int channelCount, uint32_t sampleRate,
+        status_t *status, AudioSystem::audio_in_acoustics acoustics)
+{
+    AudioStreamInStub* in = new AudioStreamInStub();
+    status_t lStatus = in->set(format, channelCount, sampleRate, acoustics);
+    if (status) {
+        *status = lStatus;
+    }
+    if (lStatus == NO_ERROR)
+        return in;
+    delete in;
+    return 0;
+}
+
+status_t AudioHardwareStub::setVoiceVolume(float volume)
+{
+    return NO_ERROR;
+}
+
+status_t AudioHardwareStub::setMasterVolume(float volume)
+{
+    return NO_ERROR;
+}
+
+status_t AudioHardwareStub::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    result.append("AudioHardwareStub::dumpInternals\n");
+    snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false");
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioHardwareStub::dump(int fd, const Vector<String16>& args)
+{
+    dumpInternals(fd, args);
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+status_t AudioStreamOutStub::set(int format, int channels, uint32_t rate)
+{
+    // fix up defaults
+    if (format == 0) format = AudioSystem::PCM_16_BIT;
+    if (channels == 0) channels = channelCount();
+    if (rate == 0) rate = sampleRate();
+
+    if ((format == AudioSystem::PCM_16_BIT) &&
+            (channels == channelCount()) &&
+            (rate == sampleRate()))
+        return NO_ERROR;
+    return BAD_VALUE;
+}
+
+ssize_t AudioStreamOutStub::write(const void* buffer, size_t bytes)
+{
+    // fake timing for audio output
+    usleep(bytes * 1000000 / sizeof(int16_t) / channelCount() / sampleRate());
+    return bytes;
+}
+
+status_t AudioStreamOutStub::standby()
+{
+    return NO_ERROR;
+}
+
+status_t AudioStreamOutStub::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "AudioStreamOutStub::dump\n");
+    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
+    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
+    snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
+    snprintf(buffer, SIZE, "\tformat: %d\n", format());
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+status_t AudioStreamInStub::set(int format, int channels, uint32_t rate,
+				AudioSystem::audio_in_acoustics acoustics)
+{
+    if ((format == AudioSystem::PCM_16_BIT) &&
+            (channels == channelCount()) &&
+            (rate == sampleRate()))
+        return NO_ERROR;
+    return BAD_VALUE;
+}
+
+ssize_t AudioStreamInStub::read(void* buffer, ssize_t bytes)
+{
+    // fake timing for audio input
+    usleep(bytes * 1000000 / sizeof(int16_t) / channelCount() / sampleRate());
+    memset(buffer, 0, bytes);
+    return bytes;
+}
+
+status_t AudioStreamInStub::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "AudioStreamInStub::dump\n");
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tformat: %d\n", format());
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/audioflinger/AudioHardwareStub.h b/libs/audioflinger/AudioHardwareStub.h
new file mode 100644
index 0000000..d406424
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareStub.h
@@ -0,0 +1,100 @@
+/* //device/servers/AudioFlinger/AudioHardwareStub.h
+**
+** Copyright 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.
+*/
+
+#ifndef ANDROID_AUDIO_HARDWARE_STUB_H
+#define ANDROID_AUDIO_HARDWARE_STUB_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <hardware_legacy/AudioHardwareBase.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class AudioStreamOutStub : public AudioStreamOut {
+public:
+    virtual status_t    set(int format, int channelCount, uint32_t sampleRate);
+    virtual uint32_t    sampleRate() const { return 44100; }
+    virtual size_t      bufferSize() const { return 4096; }
+    virtual int         channelCount() const { return 2; }
+    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
+    virtual uint32_t    latency() const { return 0; }
+    virtual status_t    setVolume(float volume) { return NO_ERROR; }
+    virtual ssize_t     write(const void* buffer, size_t bytes);
+    virtual status_t    standby();
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+};
+
+class AudioStreamInStub : public AudioStreamIn {
+public:
+    virtual status_t    set(int format, int channelCount, uint32_t sampleRate, AudioSystem::audio_in_acoustics acoustics);
+    virtual uint32_t    sampleRate() const { return 8000; }
+    virtual size_t      bufferSize() const { return 320; }
+    virtual int         channelCount() const { return 1; }
+    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
+    virtual status_t    setGain(float gain) { return NO_ERROR; }
+    virtual ssize_t     read(void* buffer, ssize_t bytes);
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+    virtual status_t    standby() { return NO_ERROR; }
+};
+
+class AudioHardwareStub : public  AudioHardwareBase
+{
+public:
+                        AudioHardwareStub();
+    virtual             ~AudioHardwareStub();
+    virtual status_t    initCheck();
+    virtual status_t    setVoiceVolume(float volume);
+    virtual status_t    setMasterVolume(float volume);
+
+    // mic mute
+    virtual status_t    setMicMute(bool state) { mMicMute = state;  return  NO_ERROR; }
+    virtual status_t    getMicMute(bool* state) { *state = mMicMute ; return NO_ERROR; }
+
+    virtual status_t    setParameter(const char* key, const char* value)
+            { return NO_ERROR; }
+
+    // create I/O streams
+    virtual AudioStreamOut* openOutputStream(
+                                int format=0,
+                                int channelCount=0,
+                                uint32_t sampleRate=0,
+                                status_t *status=0);
+
+    virtual AudioStreamIn* openInputStream(
+                                int format,
+                                int channelCount,
+                                uint32_t sampleRate,
+                                status_t *status,
+				AudioSystem::audio_in_acoustics acoustics);
+
+protected:
+    virtual status_t    doRouting() { return NO_ERROR; }
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+            bool        mMicMute;
+private:
+    status_t            dumpInternals(int fd, const Vector<String16>& args);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_HARDWARE_STUB_H
diff --git a/libs/audioflinger/AudioMixer.cpp b/libs/audioflinger/AudioMixer.cpp
new file mode 100644
index 0000000..b03467f
--- /dev/null
+++ b/libs/audioflinger/AudioMixer.cpp
@@ -0,0 +1,913 @@
+/* //device/include/server/AudioFlinger/AudioMixer.cpp
+**
+** Copyright 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.
+*/
+
+#define LOG_TAG "AudioMixer"
+
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include "AudioMixer.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+static inline int16_t clamp16(int32_t sample)
+{
+    if ((sample>>15) ^ (sample>>31))
+        sample = 0x7FFF ^ (sample>>31);
+    return sample;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate)
+    :   mActiveTrack(0), mTrackNames(0), mSampleRate(sampleRate)
+{
+    mState.enabledTracks= 0;
+    mState.needsChanged = 0;
+    mState.frameCount   = frameCount;
+    mState.outputTemp   = 0;
+    mState.resampleTemp = 0;
+    mState.hook         = process__nop;
+    track_t* t = mState.tracks;
+    for (int i=0 ; i<32 ; i++) {
+        t->needs = 0;
+        t->volume[0] = UNITY_GAIN;
+        t->volume[1] = UNITY_GAIN;
+        t->volumeInc[0] = 0;
+        t->volumeInc[1] = 0;
+        t->channelCount = 2;
+        t->enabled = 0;
+        t->format = 16;
+        t->buffer.raw = 0;
+        t->bufferProvider = 0;
+        t->hook = 0;
+        t->resampler = 0;
+        t->sampleRate = mSampleRate;
+        t->in = 0;
+        t++;
+    }
+}
+
+ AudioMixer::~AudioMixer()
+ {
+     track_t* t = mState.tracks;
+     for (int i=0 ; i<32 ; i++) {
+         delete t->resampler;
+         t++;
+     }
+     delete [] mState.outputTemp;
+     delete [] mState.resampleTemp;
+ }
+
+ int AudioMixer::getTrackName()
+ {
+    uint32_t names = mTrackNames;
+    uint32_t mask = 1;
+    int n = 0;
+    while (names & mask) {
+        mask <<= 1;
+        n++;
+    }
+    if (mask) {
+        LOGV("add track (%d)", n);
+        mTrackNames |= mask;
+        return TRACK0 + n;
+    }
+    return -1;
+ }
+
+ void AudioMixer::invalidateState(uint32_t mask)
+ {
+    if (mask) {
+        mState.needsChanged |= mask;
+        mState.hook = process__validate;
+    }
+ }
+
+ void AudioMixer::deleteTrackName(int name)
+ {
+    name -= TRACK0;
+    if (uint32_t(name) < MAX_NUM_TRACKS) {
+        LOGV("deleteTrackName(%d)", name);
+        track_t& track(mState.tracks[ name ]);
+        if (track.enabled != 0) {
+            track.enabled = 0;
+            invalidateState(1<<name);
+        }
+        if (track.resampler) {
+            // delete  the resampler
+            delete track.resampler;
+            track.resampler = 0;
+            track.sampleRate = mSampleRate;
+            invalidateState(1<<name);
+        }
+        track.volumeInc[0] = 0;
+        track.volumeInc[1] = 0;
+        mTrackNames &= ~(1<<name);
+    }
+ }
+
+status_t AudioMixer::enable(int name)
+{
+    switch (name) {
+        case MIXING: {
+            if (mState.tracks[ mActiveTrack ].enabled != 1) {
+                mState.tracks[ mActiveTrack ].enabled = 1;
+                LOGV("enable(%d)", mActiveTrack);
+                invalidateState(1<<mActiveTrack);
+            }
+        } break;
+        default:
+            return NAME_NOT_FOUND;
+    }
+    return NO_ERROR;
+}
+
+status_t AudioMixer::disable(int name)
+{
+    switch (name) {
+        case MIXING: {
+            if (mState.tracks[ mActiveTrack ].enabled != 0) {
+                mState.tracks[ mActiveTrack ].enabled = 0;
+                LOGV("disable(%d)", mActiveTrack);
+                invalidateState(1<<mActiveTrack);
+            }
+        } break;
+        default:
+            return NAME_NOT_FOUND;
+    }
+    return NO_ERROR;
+}
+
+status_t AudioMixer::setActiveTrack(int track)
+{
+    if (uint32_t(track-TRACK0) >= MAX_NUM_TRACKS) {
+        return BAD_VALUE;
+    }
+    mActiveTrack = track - TRACK0;
+    return NO_ERROR;
+}
+
+status_t AudioMixer::setParameter(int target, int name, int value)
+{
+    switch (target) {
+    case TRACK:
+        if (name == CHANNEL_COUNT) {
+            if ((uint32_t(value) <= MAX_NUM_CHANNELS) && (value)) {
+                if (mState.tracks[ mActiveTrack ].channelCount != value) {
+                    mState.tracks[ mActiveTrack ].channelCount = value;
+                    LOGV("setParameter(TRACK, CHANNEL_COUNT, %d)", value);
+                    invalidateState(1<<mActiveTrack);
+                }
+                return NO_ERROR;
+            }
+        }
+        break;
+    case RESAMPLE:
+        if (name == SAMPLE_RATE) {
+            if (value > 0) {
+                track_t& track = mState.tracks[ mActiveTrack ];
+                if (track.setResampler(uint32_t(value), mSampleRate)) {
+                    LOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
+                            uint32_t(value));
+                    invalidateState(1<<mActiveTrack);
+                }
+                return NO_ERROR;
+            }
+        }
+        break;
+    case RAMP_VOLUME:
+    case VOLUME:
+        if ((uint32_t(name-VOLUME0) < MAX_NUM_CHANNELS)) {
+            track_t& track = mState.tracks[ mActiveTrack ];
+            if (track.volume[name-VOLUME0] != value) {
+                track.prevVolume[name-VOLUME0] = track.volume[name-VOLUME0] << 16;
+                track.volume[name-VOLUME0] = value;
+                if (target == VOLUME) {
+                    track.prevVolume[name-VOLUME0] = value << 16;
+                    track.volumeInc[name-VOLUME0] = 0;
+                } else {
+                    int32_t d = (value<<16) - track.prevVolume[name-VOLUME0];
+                    int32_t volInc = d / int32_t(mState.frameCount);
+                    track.volumeInc[name-VOLUME0] = volInc;
+                    if (volInc == 0) {
+                        track.prevVolume[name-VOLUME0] = value << 16;
+                    }
+                }
+                invalidateState(1<<mActiveTrack);
+            }
+            return NO_ERROR;
+        }
+        break;
+    }
+    return BAD_VALUE;
+}
+
+bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
+{
+    if (value!=devSampleRate || resampler) {
+        if (sampleRate != value) {
+            sampleRate = value;
+            if (resampler == 0) {
+                resampler = AudioResampler::create(
+                        format, channelCount, devSampleRate);
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+bool AudioMixer::track_t::doesResample() const
+{
+    return resampler != 0;
+}
+
+inline
+void AudioMixer::track_t::adjustVolumeRamp()
+{
+    for (int i=0 ; i<2 ; i++) {
+        if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
+            ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
+            volumeInc[i] = 0;
+            prevVolume[i] = volume[i]<<16;
+        }
+    }
+}
+
+
+status_t AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
+{
+    mState.tracks[ mActiveTrack ].bufferProvider = buffer;
+    return NO_ERROR;
+}
+
+
+
+void AudioMixer::process(void* output)
+{
+    mState.hook(&mState, output);
+}
+
+
+void AudioMixer::process__validate(state_t* state, void* output)
+{
+    LOGW_IF(!state->needsChanged,
+        "in process__validate() but nothing's invalid");
+
+    uint32_t changed = state->needsChanged;
+    state->needsChanged = 0; // clear the validation flag
+
+    // recompute which tracks are enabled / disabled
+    uint32_t enabled = 0;
+    uint32_t disabled = 0;
+    while (changed) {
+        const int i = 31 - __builtin_clz(changed);
+        const uint32_t mask = 1<<i;
+        changed &= ~mask;
+        track_t& t = state->tracks[i];
+        (t.enabled ? enabled : disabled) |= mask;
+    }
+    state->enabledTracks &= ~disabled;
+    state->enabledTracks |=  enabled;
+
+    // compute everything we need...
+    int countActiveTracks = 0;
+    int all16BitsStereoNoResample = 1;
+    int resampling = 0;
+    int volumeRamp = 0;
+    uint32_t en = state->enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+
+        countActiveTracks++;
+        track_t& t = state->tracks[i];
+        uint32_t n = 0;
+        n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
+        n |= NEEDS_FORMAT_16;
+        n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
+       
+        if (t.volumeInc[0]|t.volumeInc[1]) {
+            volumeRamp = 1;
+        } else if (!t.doesResample() && t.volumeRL == 0) {
+            n |= NEEDS_MUTE_ENABLED;
+        }
+        t.needs = n;
+
+        if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
+            t.hook = track__nop;
+        } else {
+            if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
+                all16BitsStereoNoResample = 0;
+                resampling = 1;
+                t.hook = track__genericResample;
+            } else {
+                if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
+                    t.hook = track__16BitsMono;
+                    all16BitsStereoNoResample = 0;
+                }
+                if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){
+                    t.hook = track__16BitsStereo;
+                }
+            }
+        }
+    }
+
+    // select the processing hooks
+    state->hook = process__nop;
+    if (countActiveTracks) {
+        if (resampling) {
+            if (!state->outputTemp) {
+                state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
+            }
+            if (!state->resampleTemp) {
+                state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
+            }
+            state->hook = process__genericResampling;
+        } else {
+            if (state->outputTemp) {
+                delete [] state->outputTemp;
+                state->outputTemp = 0;
+            }
+            if (state->resampleTemp) {
+                delete [] state->resampleTemp;
+                state->resampleTemp = 0;
+            }
+            state->hook = process__genericNoResampling;
+            if (all16BitsStereoNoResample && !volumeRamp) {
+                if (countActiveTracks == 1) {
+                    state->hook = process__OneTrack16BitsStereoNoResampling;
+                }
+            }
+        }
+    }
+
+    LOGV("mixer configuration change: %d activeTracks (%08x) "
+        "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
+        countActiveTracks, state->enabledTracks,
+        all16BitsStereoNoResample, resampling, volumeRamp);
+
+   state->hook(state, output);
+
+   // Now that the volume ramp has been done, set optimal state and
+   // track hooks for subsequent mixer process
+   if (countActiveTracks) {
+       int allMuted = 1;
+       uint32_t en = state->enabledTracks;
+       while (en) {
+           const int i = 31 - __builtin_clz(en);
+           en &= ~(1<<i);
+           track_t& t = state->tracks[i];
+           if (!t.doesResample() && t.volumeRL == 0)
+           {
+               t.needs |= NEEDS_MUTE_ENABLED;
+               t.hook = track__nop;
+           } else {
+               allMuted = 0;
+           }
+       }
+       if (allMuted) {
+           state->hook = process__nop;
+       } else if (!resampling && all16BitsStereoNoResample) {
+           if (countActiveTracks == 1) {
+              state->hook = process__OneTrack16BitsStereoNoResampling;
+           }
+       }
+   }
+}
+
+static inline
+int32_t mulAdd(int16_t in, int16_t v, int32_t a)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    asm( "smlabb %[out], %[in], %[v], %[a] \n"
+         : [out]"=r"(out)
+         : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
+         : );
+    return out;
+#else
+    return a + in * int32_t(v);
+#endif
+}
+
+static inline
+int32_t mul(int16_t in, int16_t v)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    asm( "smulbb %[out], %[in], %[v] \n"
+         : [out]"=r"(out)
+         : [in]"%r"(in), [v]"r"(v)
+         : );
+    return out;
+#else
+    return in * int32_t(v);
+#endif
+}
+
+static inline
+int32_t mulAddRL(int left, uint32_t inRL, uint32_t vRL, int32_t a)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    if (left) {
+        asm( "smlabb %[out], %[inRL], %[vRL], %[a] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a)
+             : );
+    } else {
+        asm( "smlatt %[out], %[inRL], %[vRL], %[a] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a)
+             : );
+    }
+    return out;
+#else
+    if (left) {
+        return a + int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF);
+    } else {
+        return a + int16_t(inRL>>16) * int16_t(vRL>>16);
+    }
+#endif
+}
+
+static inline
+int32_t mulRL(int left, uint32_t inRL, uint32_t vRL)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    if (left) {
+        asm( "smulbb %[out], %[inRL], %[vRL] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [vRL]"r"(vRL)
+             : );
+    } else {
+        asm( "smultt %[out], %[inRL], %[vRL] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [vRL]"r"(vRL)
+             : );
+    }
+    return out;
+#else
+    if (left) {
+        return int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF);
+    } else {
+        return int16_t(inRL>>16) * int16_t(vRL>>16);
+    }
+#endif
+}
+
+
+void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp)
+{
+    t->resampler->setSampleRate(t->sampleRate);
+
+    // ramp gain - resample to temp buffer and scale/mix in 2nd step
+    if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
+        t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
+        memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
+        t->resampler->resample(temp, outFrameCount, t->bufferProvider);
+        volumeRampStereo(t, out, outFrameCount, temp);
+    }
+
+    // constant gain
+    else {
+        t->resampler->setVolume(t->volume[0], t->volume[1]);
+        t->resampler->resample(out, outFrameCount, t->bufferProvider);
+    }
+}
+
+void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp)
+{
+}
+
+void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
+{
+    int32_t vl = t->prevVolume[0];
+    int32_t vr = t->prevVolume[1];
+    const int32_t vlInc = t->volumeInc[0];
+    const int32_t vrInc = t->volumeInc[1];
+
+    //LOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+    //        t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
+    //       (vl + vlInc*frameCount)/65536.0f, frameCount);
+   
+    // ramp volume
+    do {
+        *out++ += (vl >> 16) * (*temp++ >> 12);
+        *out++ += (vr >> 16) * (*temp++ >> 12);
+        vl += vlInc;
+        vr += vrInc;
+    } while (--frameCount);
+
+    t->prevVolume[0] = vl;
+    t->prevVolume[1] = vr;
+    t->adjustVolumeRamp();
+}
+
+void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
+{
+    int16_t const *in = static_cast<int16_t const *>(t->in);
+
+    // ramp gain
+    if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
+        int32_t vl = t->prevVolume[0];
+        int32_t vr = t->prevVolume[1];
+        const int32_t vlInc = t->volumeInc[0];
+        const int32_t vrInc = t->volumeInc[1];
+
+        // LOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+        //        t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
+        //        (vl + vlInc*frameCount)/65536.0f, frameCount);
+
+        do {
+            *out++ += (vl >> 16) * (int32_t) *in++;
+            *out++ += (vr >> 16) * (int32_t) *in++;
+            vl += vlInc;
+            vr += vrInc;
+        } while (--frameCount);
+       
+        t->prevVolume[0] = vl;
+        t->prevVolume[1] = vr;
+        t->adjustVolumeRamp();
+    }
+
+    // constant gain
+    else {
+        const uint32_t vrl = t->volumeRL;
+        do {
+            uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
+            in += 2;
+            out[0] = mulAddRL(1, rl, vrl, out[0]);
+            out[1] = mulAddRL(0, rl, vrl, out[1]);
+            out += 2;
+        } while (--frameCount);
+    }
+    t->in = in;
+}
+
+void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
+{
+    int16_t const *in = static_cast<int16_t const *>(t->in);
+
+    // ramp gain
+    if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
+        int32_t vl = t->prevVolume[0];
+        int32_t vr = t->prevVolume[1];
+        const int32_t vlInc = t->volumeInc[0];
+        const int32_t vrInc = t->volumeInc[1];
+
+        // LOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+        //         t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
+        //         (vl + vlInc*frameCount)/65536.0f, frameCount);
+
+        do {
+            int32_t l = *in++;
+            *out++ += (vl >> 16) * l;
+            *out++ += (vr >> 16) * l;
+            vl += vlInc;
+            vr += vrInc;
+        } while (--frameCount);
+       
+        t->prevVolume[0] = vl;
+        t->prevVolume[1] = vr;
+        t->adjustVolumeRamp();
+    }
+    // constant gain
+    else {
+        const int16_t vl = t->volume[0];
+        const int16_t vr = t->volume[1];
+        do {
+            int16_t l = *in++;
+            out[0] = mulAdd(l, vl, out[0]);
+            out[1] = mulAdd(l, vr, out[1]);
+            out += 2;
+        } while (--frameCount);
+    }
+    t->in = in;
+}
+
+inline
+void AudioMixer::ditherAndClamp(int32_t* out, int32_t const *sums, size_t c)
+{
+    for (size_t i=0 ; i<c ; i++) {
+        int32_t l = *sums++;
+        int32_t r = *sums++;
+        int32_t nl = l >> 12;
+        int32_t nr = r >> 12;
+        l = clamp16(nl);
+        r = clamp16(nr);
+        *out++ = (r<<16) | (l & 0xFFFF);
+    }
+}
+
+// no-op case
+void AudioMixer::process__nop(state_t* state, void* output)
+{
+    // this assumes output 16 bits stereo, no resampling
+    memset(output, 0, state->frameCount*4);
+    uint32_t en = state->enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+        track_t& t = state->tracks[i];
+        size_t outFrames = state->frameCount;
+        while (outFrames) {
+            t.buffer.frameCount = outFrames;
+            t.bufferProvider->getNextBuffer(&t.buffer);
+            if (!t.buffer.raw) break;
+            outFrames -= t.buffer.frameCount;
+            t.bufferProvider->releaseBuffer(&t.buffer);
+        }
+    }
+}
+
+// generic code without resampling
+void AudioMixer::process__genericNoResampling(state_t* state, void* output)
+{
+    int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
+
+    // acquire each track's buffer
+    uint32_t enabledTracks = state->enabledTracks;
+    uint32_t en = enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+        track_t& t = state->tracks[i];
+        t.buffer.frameCount = state->frameCount;
+        t.bufferProvider->getNextBuffer(&t.buffer);
+        t.frameCount = t.buffer.frameCount;
+        t.in = t.buffer.raw;
+        // t.in == NULL can happen if the track was flushed just after having
+        // been enabled for mixing.
+        if (t.in == NULL)
+            enabledTracks &= ~(1<<i);
+    }
+
+    // this assumes output 16 bits stereo, no resampling
+    int32_t* out = static_cast<int32_t*>(output);
+    size_t numFrames = state->frameCount;
+    do {
+        memset(outTemp, 0, sizeof(outTemp));
+
+        en = enabledTracks;
+        while (en) {
+            const int i = 31 - __builtin_clz(en);
+            en &= ~(1<<i);
+            track_t& t = state->tracks[i];
+            size_t outFrames = BLOCKSIZE;
+           
+            while (outFrames) {
+                size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
+                if (inFrames) {
+                    (t.hook)(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp);
+                    t.frameCount -= inFrames;
+                    outFrames -= inFrames;
+                }
+                if (t.frameCount == 0 && outFrames) {
+                    t.bufferProvider->releaseBuffer(&t.buffer);
+                    t.buffer.frameCount = numFrames - (BLOCKSIZE - outFrames);
+                    t.bufferProvider->getNextBuffer(&t.buffer);
+                    t.in = t.buffer.raw;
+                    if (t.in == NULL) {
+                        enabledTracks &= ~(1<<i);
+                        break;
+                    }
+                    t.frameCount = t.buffer.frameCount;
+                 }
+            }
+        }
+
+        ditherAndClamp(out, outTemp, BLOCKSIZE);
+        out += BLOCKSIZE;
+        numFrames -= BLOCKSIZE;
+    } while (numFrames);
+
+
+    // release each track's buffer
+    en = enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+        track_t& t = state->tracks[i];
+        t.bufferProvider->releaseBuffer(&t.buffer);
+    }
+}
+
+// generic code with resampling
+void AudioMixer::process__genericResampling(state_t* state, void* output)
+{
+    int32_t* const outTemp = state->outputTemp;
+    const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
+    memset(outTemp, 0, size);
+
+    int32_t* out = static_cast<int32_t*>(output);
+    size_t numFrames = state->frameCount;
+
+    uint32_t en = state->enabledTracks;
+    while (en) {
+        const int i = 31 - __builtin_clz(en);
+        en &= ~(1<<i);
+        track_t& t = state->tracks[i];
+
+        // this is a little goofy, on the resampling case we don't
+        // acquire/release the buffers because it's done by
+        // the resampler.
+        if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
+            (t.hook)(&t, outTemp, numFrames, state->resampleTemp);
+        } else {
+
+            size_t outFrames = numFrames;
+           
+            while (outFrames) {
+                t.buffer.frameCount = outFrames;
+                t.bufferProvider->getNextBuffer(&t.buffer);
+                t.in = t.buffer.raw;
+                // t.in == NULL can happen if the track was flushed just after having
+                // been enabled for mixing.
+                if (t.in == NULL) break;
+
+                (t.hook)(&t, outTemp + (numFrames-outFrames)*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp);
+                outFrames -= t.buffer.frameCount;
+                t.bufferProvider->releaseBuffer(&t.buffer);
+            }
+        }
+    }
+
+    ditherAndClamp(out, outTemp, numFrames);
+}
+
+// one track, 16 bits stereo without resampling is the most common case
+void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state, void* output)
+{
+    const int i = 31 - __builtin_clz(state->enabledTracks);
+    const track_t& t = state->tracks[i];
+
+    AudioBufferProvider::Buffer& b(t.buffer);
+   
+    int32_t* out = static_cast<int32_t*>(output);
+    size_t numFrames = state->frameCount;
+  
+    const int16_t vl = t.volume[0];
+    const int16_t vr = t.volume[1];
+    const uint32_t vrl = t.volumeRL;
+    while (numFrames) {
+        b.frameCount = numFrames;
+        t.bufferProvider->getNextBuffer(&b);
+        int16_t const *in = b.i16;
+
+        // in == NULL can happen if the track was flushed just after having
+        // been enabled for mixing.
+        if (in == NULL) {
+            memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
+            return;
+        }
+        size_t outFrames = b.frameCount;
+       
+        if (UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
+            // volume is boosted, so we might need to clamp even though
+            // we process only one track.
+            do {
+                uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
+                in += 2;
+                int32_t l = mulRL(1, rl, vrl) >> 12;
+                int32_t r = mulRL(0, rl, vrl) >> 12;
+                // clamping...
+                l = clamp16(l);
+                r = clamp16(r);
+                *out++ = (r<<16) | (l & 0xFFFF);
+            } while (--outFrames);
+        } else {
+            do {
+                uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
+                in += 2;
+                int32_t l = mulRL(1, rl, vrl) >> 12;
+                int32_t r = mulRL(0, rl, vrl) >> 12;
+                *out++ = (r<<16) | (l & 0xFFFF);
+            } while (--outFrames);
+        }
+        numFrames -= b.frameCount;
+        t.bufferProvider->releaseBuffer(&b);
+    }
+}
+
+// 2 tracks is also a common case
+void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state, void* output)
+{
+    int i;
+    uint32_t en = state->enabledTracks;
+
+    i = 31 - __builtin_clz(en);
+    const track_t& t0 = state->tracks[i];
+    AudioBufferProvider::Buffer& b0(t0.buffer);
+
+    en &= ~(1<<i);
+    i = 31 - __builtin_clz(en);
+    const track_t& t1 = state->tracks[i];
+    AudioBufferProvider::Buffer& b1(t1.buffer);
+   
+    int16_t const *in0;
+    const int16_t vl0 = t0.volume[0];
+    const int16_t vr0 = t0.volume[1];
+    size_t frameCount0 = 0;
+  
+    int16_t const *in1;
+    const int16_t vl1 = t1.volume[0];
+    const int16_t vr1 = t1.volume[1];
+    size_t frameCount1 = 0;
+   
+    int32_t* out = static_cast<int32_t*>(output);
+    size_t numFrames = state->frameCount;
+    int16_t const *buff = NULL;
+
+  
+    while (numFrames) {
+   
+        if (frameCount0 == 0) {
+            b0.frameCount = numFrames;
+            t0.bufferProvider->getNextBuffer(&b0);
+            if (b0.i16 == NULL) {
+                if (buff == NULL) {
+                    buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
+                }
+                in0 = buff;
+                b0.frameCount = numFrames;
+            } else {
+                in0 = b0.i16;
+            }
+            frameCount0 = b0.frameCount;
+        }
+        if (frameCount1 == 0) {
+            b1.frameCount = numFrames;
+            t1.bufferProvider->getNextBuffer(&b1);
+            if (b1.i16 == NULL) {
+                if (buff == NULL) {
+                    buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
+                }
+                in1 = buff;
+                b1.frameCount = numFrames;
+               } else {
+                in1 = b1.i16;
+            }
+            frameCount1 = b1.frameCount;
+        }
+       
+        size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
+
+        numFrames -= outFrames;
+        frameCount0 -= outFrames;
+        frameCount1 -= outFrames;
+       
+        do {
+            int32_t l0 = *in0++;
+            int32_t r0 = *in0++;
+            l0 = mul(l0, vl0);
+            r0 = mul(r0, vr0);
+            int32_t l = *in1++;
+            int32_t r = *in1++;
+            l = mulAdd(l, vl1, l0) >> 12;
+            r = mulAdd(r, vr1, r0) >> 12;
+            // clamping...
+            l = clamp16(l);
+            r = clamp16(r);
+            *out++ = (r<<16) | (l & 0xFFFF);
+        } while (--outFrames);
+       
+        if (frameCount0 == 0) {
+            t0.bufferProvider->releaseBuffer(&b0);
+        }
+        if (frameCount1 == 0) {
+            t1.bufferProvider->releaseBuffer(&b1);
+        }
+    }   
+       
+    if (buff != NULL) {
+        delete [] buff;       
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/libs/audioflinger/AudioMixer.h b/libs/audioflinger/AudioMixer.h
new file mode 100644
index 0000000..72ca28a
--- /dev/null
+++ b/libs/audioflinger/AudioMixer.h
@@ -0,0 +1,192 @@
+/* //device/include/server/AudioFlinger/AudioMixer.h
+**
+** Copyright 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.
+*/
+
+#ifndef ANDROID_AUDIO_MIXER_H
+#define ANDROID_AUDIO_MIXER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "AudioBufferProvider.h"
+#include "AudioResampler.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ----------------------------------------------------------------------------
+
+class AudioMixer
+{
+public:
+                            AudioMixer(size_t frameCount, uint32_t sampleRate);
+
+                            ~AudioMixer();
+
+    static const uint32_t MAX_NUM_TRACKS = 32;
+    static const uint32_t MAX_NUM_CHANNELS = 2;
+
+    static const uint16_t UNITY_GAIN = 0x1000;
+
+    enum { // names
+
+        // track units (32 units)
+        TRACK0          = 0x1000,
+
+        // enable/disable
+        MIXING          = 0x2000,
+
+        // setParameter targets
+        TRACK           = 0x3000,
+        RESAMPLE        = 0x3001,
+        RAMP_VOLUME     = 0x3002, // ramp to new volume
+        VOLUME          = 0x3003, // don't ramp
+
+        // set Parameter names
+        // for target TRACK
+        CHANNEL_COUNT   = 0x4000,
+        FORMAT          = 0x4001,
+        // for TARGET RESAMPLE
+        SAMPLE_RATE     = 0x4100,
+        // for TARGET VOLUME (8 channels max)
+        VOLUME0         = 0x4200,
+        VOLUME1         = 0x4201,
+    };
+
+
+    int         getTrackName();
+    void        deleteTrackName(int name);
+
+    status_t    enable(int name);
+    status_t    disable(int name);
+
+    status_t    setActiveTrack(int track);
+    status_t    setParameter(int target, int name, int value);
+
+    status_t    setBufferProvider(AudioBufferProvider* bufferProvider);
+    void        process(void* output);
+
+    uint32_t    trackNames() const { return mTrackNames; }
+
+private:
+
+    enum {
+        NEEDS_CHANNEL_COUNT__MASK   = 0x00000003,
+        NEEDS_FORMAT__MASK          = 0x000000F0,
+        NEEDS_MUTE__MASK            = 0x00000100,
+        NEEDS_RESAMPLE__MASK        = 0x00001000,
+    };
+
+    enum {
+        NEEDS_CHANNEL_1             = 0x00000000,
+        NEEDS_CHANNEL_2             = 0x00000001,
+
+        NEEDS_FORMAT_16             = 0x00000010,
+
+        NEEDS_MUTE_DISABLED         = 0x00000000,
+        NEEDS_MUTE_ENABLED          = 0x00000100,
+
+        NEEDS_RESAMPLE_DISABLED     = 0x00000000,
+        NEEDS_RESAMPLE_ENABLED      = 0x00001000,
+    };
+
+    static inline int32_t applyVolume(int32_t in, int32_t v) {
+        return in * v;
+    }
+
+
+    struct state_t;
+
+    typedef void (*mix_t)(state_t* state, void* output);
+
+    static const int BLOCKSIZE = 16; // 4 cache lines
+
+    struct track_t {
+        uint32_t    needs;
+
+        union {
+        int16_t     volume[2];      // [0]3.12 fixed point
+        int32_t     volumeRL;
+        };
+
+        int32_t     prevVolume[2];
+
+        int32_t     volumeInc[2];
+
+        uint16_t    frameCount;
+
+        uint8_t     channelCount : 4;
+        uint8_t     enabled      : 1;
+        uint8_t     reserved0    : 3;
+        uint8_t     format;
+
+        AudioBufferProvider*                bufferProvider;
+        mutable AudioBufferProvider::Buffer buffer;
+
+        void (*hook)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp);
+        void const* in;             // current location in buffer
+
+        AudioResampler*     resampler;
+        uint32_t            sampleRate;
+
+        bool        setResampler(uint32_t sampleRate, uint32_t devSampleRate);
+        bool        doesResample() const;
+        void        adjustVolumeRamp();
+    };
+
+    // pad to 32-bytes to fill cache line
+    struct state_t {
+        uint32_t        enabledTracks;
+        uint32_t        needsChanged;
+        size_t          frameCount;
+        mix_t           hook;
+        int32_t         *outputTemp;
+        int32_t         *resampleTemp;
+        int32_t         reserved[2];
+        track_t         tracks[32]; __attribute__((aligned(32)));
+    };
+
+    int             mActiveTrack;
+    uint32_t        mTrackNames;
+    const uint32_t  mSampleRate;
+
+    state_t         mState __attribute__((aligned(32)));
+
+    void invalidateState(uint32_t mask);
+
+    static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
+    static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
+    static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp);
+    static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
+    static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
+    static void ditherAndClamp(int32_t* out, int32_t const *sums, size_t c);
+
+    static void process__validate(state_t* state, void* output);
+    static void process__nop(state_t* state, void* output);
+    static void process__genericNoResampling(state_t* state, void* output);
+    static void process__genericResampling(state_t* state, void* output);
+    static void process__OneTrack16BitsStereoNoResampling(state_t* state, void* output);
+    static void process__TwoTracks16BitsStereoNoResampling(state_t* state, void* output);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_AUDIO_MIXER_H
diff --git a/libs/audioflinger/AudioResampler.cpp b/libs/audioflinger/AudioResampler.cpp
new file mode 100644
index 0000000..5dabacb
--- /dev/null
+++ b/libs/audioflinger/AudioResampler.cpp
@@ -0,0 +1,595 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "AudioResampler"
+//#define LOG_NDEBUG 0
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include "AudioResampler.h"
+#include "AudioResamplerSinc.h"
+#include "AudioResamplerCubic.h"
+
+namespace android {
+
+#ifdef __ARM_ARCH_5E__  // optimized asm option
+    #define ASM_ARM_RESAMP1 // enable asm optimisation for ResamplerOrder1
+#endif // __ARM_ARCH_5E__
+// ----------------------------------------------------------------------------
+
+class AudioResamplerOrder1 : public AudioResampler {
+public:
+    AudioResamplerOrder1(int bitDepth, int inChannelCount, int32_t sampleRate) :
+        AudioResampler(bitDepth, inChannelCount, sampleRate), mX0L(0), mX0R(0) {
+    }
+    virtual void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+private:
+    // number of bits used in interpolation multiply - 15 bits avoids overflow
+    static const int kNumInterpBits = 15;
+
+    // bits to shift the phase fraction down to avoid overflow
+    static const int kPreInterpShift = kNumPhaseBits - kNumInterpBits;
+
+    void init() {}
+    void resampleMono16(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+    void resampleStereo16(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
+    void AsmMono16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
+            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
+            uint32_t &phaseFraction, uint32_t phaseIncrement);
+    void AsmStereo16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
+            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
+            uint32_t &phaseFraction, uint32_t phaseIncrement);
+#endif  // ASM_ARM_RESAMP1
+
+    static inline int32_t Interp(int32_t x0, int32_t x1, uint32_t f) {
+        return x0 + (((x1 - x0) * (int32_t)(f >> kPreInterpShift)) >> kNumInterpBits);
+    }
+    static inline void Advance(size_t* index, uint32_t* frac, uint32_t inc) {
+        *frac += inc;
+        *index += (size_t)(*frac >> kNumPhaseBits);
+        *frac &= kPhaseMask;
+    }
+    int mX0L;
+    int mX0R;
+};
+
+// ----------------------------------------------------------------------------
+AudioResampler* AudioResampler::create(int bitDepth, int inChannelCount,
+        int32_t sampleRate, int quality) {
+
+    // can only create low quality resample now
+    AudioResampler* resampler;
+
+    char value[PROPERTY_VALUE_MAX];
+    if (property_get("af.resampler.quality", value, 0)) {
+        quality = atoi(value);
+        LOGD("forcing AudioResampler quality to %d", quality);
+    }
+
+    if (quality == DEFAULT)
+        quality = LOW_QUALITY;
+
+    switch (quality) {
+    default:
+    case LOW_QUALITY:
+        LOGV("Create linear Resampler");
+        resampler = new AudioResamplerOrder1(bitDepth, inChannelCount, sampleRate);
+        break;
+    case MED_QUALITY:
+        LOGV("Create cubic Resampler");
+        resampler = new AudioResamplerCubic(bitDepth, inChannelCount, sampleRate);
+        break;
+    case HIGH_QUALITY:
+        LOGV("Create sinc Resampler");
+        resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate);
+        break;
+    }
+
+    // initialize resampler
+    resampler->init();
+    return resampler;
+}
+
+AudioResampler::AudioResampler(int bitDepth, int inChannelCount,
+        int32_t sampleRate) :
+    mBitDepth(bitDepth), mChannelCount(inChannelCount),
+            mSampleRate(sampleRate), mInSampleRate(sampleRate), mInputIndex(0),
+            mPhaseFraction(0) {
+    // sanity check on format
+    if ((bitDepth != 16) ||(inChannelCount < 1) || (inChannelCount > 2)) {
+        LOGE("Unsupported sample format, %d bits, %d channels", bitDepth,
+                inChannelCount);
+        // LOG_ASSERT(0);
+    }
+
+    // initialize common members
+    mVolume[0] = mVolume[1] = 0;
+    mBuffer.frameCount = 0;
+
+    // save format for quick lookup
+    if (inChannelCount == 1) {
+        mFormat = MONO_16_BIT;
+    } else {
+        mFormat = STEREO_16_BIT;
+    }
+}
+
+AudioResampler::~AudioResampler() {
+}
+
+void AudioResampler::setSampleRate(int32_t inSampleRate) {
+    mInSampleRate = inSampleRate;
+    mPhaseIncrement = (uint32_t)((kPhaseMultiplier * inSampleRate) / mSampleRate);
+}
+
+void AudioResampler::setVolume(int16_t left, int16_t right) {
+    // TODO: Implement anti-zipper filter
+    mVolume[0] = left;
+    mVolume[1] = right;
+}
+
+// ----------------------------------------------------------------------------
+
+void AudioResamplerOrder1::resample(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    // should never happen, but we overflow if it does
+    // LOG_ASSERT(outFrameCount < 32767);
+
+    // select the appropriate resampler
+    switch (mChannelCount) {
+    case 1:
+        resampleMono16(out, outFrameCount, provider);
+        break;
+    case 2:
+        resampleStereo16(out, outFrameCount, provider);
+        break;
+    }
+}
+
+void AudioResamplerOrder1::resampleStereo16(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    int32_t vl = mVolume[0];
+    int32_t vr = mVolume[1];
+
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    // LOGE("starting resample %d frames, inputIndex=%d, phaseFraction=%d, phaseIncrement=%d\n",
+    //      outFrameCount, inputIndex, phaseFraction, phaseIncrement);
+
+    while (outputIndex < outputSampleCount) {
+
+        // buffer is empty, fetch a new one
+        while (mBuffer.frameCount == 0) {
+            mBuffer.frameCount = inFrameCount;
+            provider->getNextBuffer(&mBuffer);
+            if (mBuffer.raw == NULL) {
+                goto resampleStereo16_exit;
+            }
+
+            // LOGE("New buffer fetched: %d frames\n", mBuffer.frameCount);
+            if (mBuffer.frameCount > inputIndex) break;
+
+            inputIndex -= mBuffer.frameCount;
+            mX0L = mBuffer.i16[mBuffer.frameCount*2-2];
+            mX0R = mBuffer.i16[mBuffer.frameCount*2-1];
+            provider->releaseBuffer(&mBuffer);
+             // mBuffer.frameCount == 0 now so we reload a new buffer
+        }
+
+        int16_t *in = mBuffer.i16;
+
+        // handle boundary case
+        while (inputIndex == 0) {
+            // LOGE("boundary case\n");
+            out[outputIndex++] += vl * Interp(mX0L, in[0], phaseFraction);
+            out[outputIndex++] += vr * Interp(mX0R, in[1], phaseFraction);
+            Advance(&inputIndex, &phaseFraction, phaseIncrement);
+            if (outputIndex == outputSampleCount)
+                break;
+        }
+
+        // process input samples
+        // LOGE("general case\n");
+
+#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
+        if (inputIndex + 2 < mBuffer.frameCount) {
+            int32_t* maxOutPt;
+            int32_t maxInIdx;
+
+            maxOutPt = out + (outputSampleCount - 2);   // 2 because 2 frames per loop
+            maxInIdx = mBuffer.frameCount - 2;
+            AsmStereo16Loop(in, maxOutPt, maxInIdx, outputIndex, out, inputIndex, vl, vr,
+                    phaseFraction, phaseIncrement);
+        }
+#endif  // ASM_ARM_RESAMP1
+
+        while (outputIndex < outputSampleCount && inputIndex < mBuffer.frameCount) {
+            out[outputIndex++] += vl * Interp(in[inputIndex*2-2],
+                    in[inputIndex*2], phaseFraction);
+            out[outputIndex++] += vr * Interp(in[inputIndex*2-1],
+                    in[inputIndex*2+1], phaseFraction);
+            Advance(&inputIndex, &phaseFraction, phaseIncrement);
+        }
+
+        // LOGE("loop done - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+        // if done with buffer, save samples
+        if (inputIndex >= mBuffer.frameCount) {
+            inputIndex -= mBuffer.frameCount;
+
+            // LOGE("buffer done, new input index %d", inputIndex);
+
+            mX0L = mBuffer.i16[mBuffer.frameCount*2-2];
+            mX0R = mBuffer.i16[mBuffer.frameCount*2-1];
+            provider->releaseBuffer(&mBuffer);
+
+            // verify that the releaseBuffer resets the buffer frameCount
+            // LOG_ASSERT(mBuffer.frameCount == 0);
+        }
+    }
+
+    // LOGE("output buffer full - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+resampleStereo16_exit:
+    // save state
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+void AudioResamplerOrder1::resampleMono16(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    int32_t vl = mVolume[0];
+    int32_t vr = mVolume[1];
+
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    // LOGE("starting resample %d frames, inputIndex=%d, phaseFraction=%d, phaseIncrement=%d\n",
+    //      outFrameCount, inputIndex, phaseFraction, phaseIncrement);
+    while (outputIndex < outputSampleCount) {
+        // buffer is empty, fetch a new one
+        while (mBuffer.frameCount == 0) {
+            mBuffer.frameCount = inFrameCount;
+            provider->getNextBuffer(&mBuffer);
+            if (mBuffer.raw == NULL) {
+                mInputIndex = inputIndex;
+                mPhaseFraction = phaseFraction;
+                goto resampleMono16_exit;
+            }
+            // LOGE("New buffer fetched: %d frames\n", mBuffer.frameCount);
+            if (mBuffer.frameCount >  inputIndex) break;
+
+            inputIndex -= mBuffer.frameCount;
+            mX0L = mBuffer.i16[mBuffer.frameCount-1];
+            provider->releaseBuffer(&mBuffer);
+            // mBuffer.frameCount == 0 now so we reload a new buffer
+        }
+        int16_t *in = mBuffer.i16;
+
+        // handle boundary case
+        while (inputIndex == 0) {
+            // LOGE("boundary case\n");
+            int32_t sample = Interp(mX0L, in[0], phaseFraction);
+            out[outputIndex++] += vl * sample;
+            out[outputIndex++] += vr * sample;
+            Advance(&inputIndex, &phaseFraction, phaseIncrement);
+            if (outputIndex == outputSampleCount)
+                break;
+        }
+
+        // process input samples
+        // LOGE("general case\n");
+
+#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
+        if (inputIndex + 2 < mBuffer.frameCount) {
+            int32_t* maxOutPt;
+            int32_t maxInIdx;
+
+            maxOutPt = out + (outputSampleCount - 2);
+            maxInIdx = (int32_t)mBuffer.frameCount - 2;
+                AsmMono16Loop(in, maxOutPt, maxInIdx, outputIndex, out, inputIndex, vl, vr,
+                        phaseFraction, phaseIncrement);
+        }
+#endif  // ASM_ARM_RESAMP1
+
+        while (outputIndex < outputSampleCount && inputIndex < mBuffer.frameCount) {
+            int32_t sample = Interp(in[inputIndex-1], in[inputIndex],
+                    phaseFraction);
+            out[outputIndex++] += vl * sample;
+            out[outputIndex++] += vr * sample;
+            Advance(&inputIndex, &phaseFraction, phaseIncrement);
+        }
+
+
+        // LOGE("loop done - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+        // if done with buffer, save samples
+        if (inputIndex >= mBuffer.frameCount) {
+            inputIndex -= mBuffer.frameCount;
+
+            // LOGE("buffer done, new input index %d", inputIndex);
+
+            mX0L = mBuffer.i16[mBuffer.frameCount-1];
+            provider->releaseBuffer(&mBuffer);
+
+            // verify that the releaseBuffer resets the buffer frameCount
+            // LOG_ASSERT(mBuffer.frameCount == 0);
+        }
+    }
+
+    // LOGE("output buffer full - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+resampleMono16_exit:
+    // save state
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
+
+/*******************************************************************
+*
+*   AsmMono16Loop
+*   asm optimized monotonic loop version; one loop is 2 frames
+*   Input:
+*       in : pointer on input samples
+*       maxOutPt : pointer on first not filled
+*       maxInIdx : index on first not used
+*       outputIndex : pointer on current output index
+*       out : pointer on output buffer
+*       inputIndex : pointer on current input index
+*       vl, vr : left and right gain
+*       phaseFraction : pointer on current phase fraction
+*       phaseIncrement
+*   Ouput:
+*       outputIndex :
+*       out : updated buffer
+*       inputIndex : index of next to use
+*       phaseFraction : phase fraction for next interpolation
+*
+*******************************************************************/
+void AudioResamplerOrder1::AsmMono16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
+            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
+            uint32_t &phaseFraction, uint32_t phaseIncrement)
+{
+#define MO_PARAM5   "36"        // offset of parameter 5 (outputIndex)
+
+    asm(
+        "stmfd  sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
+        // get parameters
+        "   ldr r6, [sp, #" MO_PARAM5 " + 20]\n"    // &phaseFraction
+        "   ldr r6, [r6]\n"                         // phaseFraction
+        "   ldr r7, [sp, #" MO_PARAM5 " + 8]\n"     // &inputIndex
+        "   ldr r7, [r7]\n"                         // inputIndex
+        "   ldr r8, [sp, #" MO_PARAM5 " + 4]\n"     // out
+        "   ldr r0, [sp, #" MO_PARAM5 " + 0]\n"     // &outputIndex
+        "   ldr r0, [r0]\n"                         // outputIndex
+        "   add r8, r0, asl #2\n"                   // curOut
+        "   ldr r9, [sp, #" MO_PARAM5 " + 24]\n"    // phaseIncrement
+        "   ldr r10, [sp, #" MO_PARAM5 " + 12]\n"   // vl
+        "   ldr r11, [sp, #" MO_PARAM5 " + 16]\n"   // vr
+
+        // r0 pin, x0, Samp
+
+        // r1 in
+        // r2 maxOutPt
+        // r3 maxInIdx
+
+        // r4 x1, i1, i3, Out1
+        // r5 out0
+
+        // r6 frac
+        // r7 inputIndex
+        // r8 curOut
+
+        // r9 inc
+        // r10 vl
+        // r11 vr
+
+        // r12
+        // r13 sp
+        // r14
+
+        // the following loop works on 2 frames
+
+        ".Y4L01:\n"
+        "   cmp r8, r2\n"                   // curOut - maxCurOut
+        "   bcs .Y4L02\n"
+
+#define MO_ONE_FRAME \
+    "   add r0, r1, r7, asl #1\n"       /* in + inputIndex */\
+    "   ldrsh r4, [r0]\n"               /* in[inputIndex] */\
+    "   ldr r5, [r8]\n"                 /* out[outputIndex] */\
+    "   ldrsh r0, [r0, #-2]\n"          /* in[inputIndex-1] */\
+    "   bic r6, r6, #0xC0000000\n"      /* phaseFraction & ... */\
+    "   sub r4, r4, r0\n"               /* in[inputIndex] - in[inputIndex-1] */\
+    "   mov r4, r4, lsl #2\n"           /* <<2 */\
+    "   smulwt r4, r4, r6\n"            /* (x1-x0)*.. */\
+    "   add r6, r6, r9\n"               /* phaseFraction + phaseIncrement */\
+    "   add r0, r0, r4\n"               /* x0 - (..) */\
+    "   mla r5, r0, r10, r5\n"          /* vl*interp + out[] */\
+    "   ldr r4, [r8, #4]\n"             /* out[outputIndex+1] */\
+    "   str r5, [r8], #4\n"             /* out[outputIndex++] = ... */\
+    "   mla r4, r0, r11, r4\n"          /* vr*interp + out[] */\
+    "   add r7, r7, r6, lsr #30\n"      /* inputIndex + phaseFraction>>30 */\
+    "   str r4, [r8], #4\n"             /* out[outputIndex++] = ... */
+
+        MO_ONE_FRAME    // frame 1
+        MO_ONE_FRAME    // frame 2
+
+        "   cmp r7, r3\n"                   // inputIndex - maxInIdx
+        "   bcc .Y4L01\n"
+        ".Y4L02:\n"
+
+        "   bic r6, r6, #0xC0000000\n"             // phaseFraction & ...
+        // save modified values
+        "   ldr r0, [sp, #" MO_PARAM5 " + 20]\n"    // &phaseFraction
+        "   str r6, [r0]\n"                         // phaseFraction
+        "   ldr r0, [sp, #" MO_PARAM5 " + 8]\n"     // &inputIndex
+        "   str r7, [r0]\n"                         // inputIndex
+        "   ldr r0, [sp, #" MO_PARAM5 " + 4]\n"     // out
+        "   sub r8, r0\n"                           // curOut - out
+        "   asr r8, #2\n"                           // new outputIndex
+        "   ldr r0, [sp, #" MO_PARAM5 " + 0]\n"     // &outputIndex
+        "   str r8, [r0]\n"                         // save outputIndex
+
+        "   ldmfd   sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc}\n"
+    );
+}
+
+/*******************************************************************
+*
+*   AsmStereo16Loop
+*   asm optimized stereo loop version; one loop is 2 frames
+*   Input:
+*       in : pointer on input samples
+*       maxOutPt : pointer on first not filled
+*       maxInIdx : index on first not used
+*       outputIndex : pointer on current output index
+*       out : pointer on output buffer
+*       inputIndex : pointer on current input index
+*       vl, vr : left and right gain
+*       phaseFraction : pointer on current phase fraction
+*       phaseIncrement
+*   Ouput:
+*       outputIndex :
+*       out : updated buffer
+*       inputIndex : index of next to use
+*       phaseFraction : phase fraction for next interpolation
+*
+*******************************************************************/
+void AudioResamplerOrder1::AsmStereo16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
+            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
+            uint32_t &phaseFraction, uint32_t phaseIncrement)
+{
+#define ST_PARAM5    "40"     // offset of parameter 5 (outputIndex)
+    asm(
+        "stmfd  sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}\n"
+        // get parameters
+        "   ldr r6, [sp, #" ST_PARAM5 " + 20]\n"    // &phaseFraction
+        "   ldr r6, [r6]\n"                         // phaseFraction
+        "   ldr r7, [sp, #" ST_PARAM5 " + 8]\n"     // &inputIndex
+        "   ldr r7, [r7]\n"                         // inputIndex
+        "   ldr r8, [sp, #" ST_PARAM5 " + 4]\n"     // out
+        "   ldr r0, [sp, #" ST_PARAM5 " + 0]\n"     // &outputIndex
+        "   ldr r0, [r0]\n"                         // outputIndex
+        "   add r8, r0, asl #2\n"                   // curOut
+        "   ldr r9, [sp, #" ST_PARAM5 " + 24]\n"    // phaseIncrement
+        "   ldr r10, [sp, #" ST_PARAM5 " + 12]\n"   // vl
+        "   ldr r11, [sp, #" ST_PARAM5 " + 16]\n"   // vr
+
+        // r0 pin, x0, Samp
+
+        // r1 in
+        // r2 maxOutPt
+        // r3 maxInIdx
+
+        // r4 x1, i1, i3, out1
+        // r5 out0
+
+        // r6 frac
+        // r7 inputIndex
+        // r8 curOut
+
+        // r9 inc
+        // r10 vl
+        // r11 vr
+
+        // r12 temporary
+        // r13 sp
+        // r14
+
+        ".Y5L01:\n"
+        "   cmp r8, r2\n"                   // curOut - maxCurOut
+        "   bcs .Y5L02\n"
+
+#define ST_ONE_FRAME \
+    "   bic r6, r6, #0xC0000000\n"      /* phaseFraction & ... */\
+\
+    "   add r0, r1, r7, asl #2\n"       /* in + 2*inputIndex */\
+\
+    "   ldrsh r4, [r0]\n"               /* in[2*inputIndex] */\
+    "   ldr r5, [r8]\n"                 /* out[outputIndex] */\
+    "   ldrsh r12, [r0, #-4]\n"         /* in[2*inputIndex-2] */\
+    "   sub r4, r4, r12\n"              /* in[2*InputIndex] - in[2*InputIndex-2] */\
+    "   mov r4, r4, lsl #2\n"           /* <<2 */\
+    "   smulwt r4, r4, r6\n"            /* (x1-x0)*.. */\
+    "   add r12, r12, r4\n"             /* x0 - (..) */\
+    "   mla r5, r12, r10, r5\n"         /* vl*interp + out[] */\
+    "   ldr r4, [r8, #4]\n"             /* out[outputIndex+1] */\
+    "   str r5, [r8], #4\n"             /* out[outputIndex++] = ... */\
+\
+    "   ldrsh r12, [r0, #+2]\n"         /* in[2*inputIndex+1] */\
+    "   ldrsh r0, [r0, #-2]\n"          /* in[2*inputIndex-1] */\
+    "   sub r12, r12, r0\n"             /* in[2*InputIndex] - in[2*InputIndex-2] */\
+    "   mov r12, r12, lsl #2\n"         /* <<2 */\
+    "   smulwt r12, r12, r6\n"          /* (x1-x0)*.. */\
+    "   add r12, r0, r12\n"             /* x0 - (..) */\
+    "   mla r4, r12, r11, r4\n"         /* vr*interp + out[] */\
+    "   str r4, [r8], #4\n"             /* out[outputIndex++] = ... */\
+\
+    "   add r6, r6, r9\n"               /* phaseFraction + phaseIncrement */\
+    "   add r7, r7, r6, lsr #30\n"      /* inputIndex + phaseFraction>>30 */
+
+    ST_ONE_FRAME    // frame 1
+    ST_ONE_FRAME    // frame 1
+
+        "   cmp r7, r3\n"                       // inputIndex - maxInIdx
+        "   bcc .Y5L01\n"
+        ".Y5L02:\n"
+
+        "   bic r6, r6, #0xC0000000\n"              // phaseFraction & ...
+        // save modified values
+        "   ldr r0, [sp, #" ST_PARAM5 " + 20]\n"    // &phaseFraction
+        "   str r6, [r0]\n"                         // phaseFraction
+        "   ldr r0, [sp, #" ST_PARAM5 " + 8]\n"     // &inputIndex
+        "   str r7, [r0]\n"                         // inputIndex
+        "   ldr r0, [sp, #" ST_PARAM5 " + 4]\n"     // out
+        "   sub r8, r0\n"                           // curOut - out
+        "   asr r8, #2\n"                           // new outputIndex
+        "   ldr r0, [sp, #" ST_PARAM5 " + 0]\n"     // &outputIndex
+        "   str r8, [r0]\n"                         // save outputIndex
+
+        "   ldmfd   sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, pc}\n"
+    );
+}
+
+#endif  // ASM_ARM_RESAMP1
+
+
+// ----------------------------------------------------------------------------
+}
+; // namespace android
+
diff --git a/libs/audioflinger/AudioResampler.h b/libs/audioflinger/AudioResampler.h
new file mode 100644
index 0000000..39656c0
--- /dev/null
+++ b/libs/audioflinger/AudioResampler.h
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_AUDIO_RESAMPLER_H
+#define ANDROID_AUDIO_RESAMPLER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "AudioBufferProvider.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class AudioResampler {
+public:
+    // Determines quality of SRC.
+    //  LOW_QUALITY: linear interpolator (1st order)
+    //  MED_QUALITY: cubic interpolator (3rd order)
+    //  HIGH_QUALITY: fixed multi-tap FIR (e.g. 48KHz->44.1KHz)
+    // NOTE: high quality SRC will only be supported for
+    // certain fixed rate conversions. Sample rate cannot be
+    // changed dynamically. 
+    enum src_quality {
+        DEFAULT=0,
+        LOW_QUALITY=1,
+        MED_QUALITY=2,
+        HIGH_QUALITY=3
+    };
+
+    static AudioResampler* create(int bitDepth, int inChannelCount,
+            int32_t sampleRate, int quality=DEFAULT);
+
+    virtual ~AudioResampler();
+
+    virtual void init() = 0;
+    virtual void setSampleRate(int32_t inSampleRate);
+    virtual void setVolume(int16_t left, int16_t right);
+
+    virtual void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider) = 0;
+
+protected:
+    // number of bits for phase fraction - 30 bits allows nearly 2x downsampling
+    static const int kNumPhaseBits = 30;
+
+    // phase mask for fraction
+    static const uint32_t kPhaseMask = (1LU<<kNumPhaseBits)-1;
+
+    // multiplier to calculate fixed point phase increment
+    static const double kPhaseMultiplier = 1L << kNumPhaseBits;
+
+    enum format {MONO_16_BIT, STEREO_16_BIT};
+    AudioResampler(int bitDepth, int inChannelCount, int32_t sampleRate);
+
+    // prevent copying
+    AudioResampler(const AudioResampler&);
+    AudioResampler& operator=(const AudioResampler&);
+
+    int32_t mBitDepth;
+    int32_t mChannelCount;
+    int32_t mSampleRate;
+    int32_t mInSampleRate;
+    AudioBufferProvider::Buffer mBuffer;
+    union {
+    	int16_t mVolume[2];
+    	uint32_t mVolumeRL;
+    };
+    int16_t mTargetVolume[2];
+    format mFormat;
+    size_t mInputIndex;
+    int32_t mPhaseIncrement;
+    uint32_t mPhaseFraction;
+};
+
+// ----------------------------------------------------------------------------
+}
+; // namespace android
+
+#endif // ANDROID_AUDIO_RESAMPLER_H
diff --git a/libs/audioflinger/AudioResamplerCubic.cpp b/libs/audioflinger/AudioResamplerCubic.cpp
new file mode 100644
index 0000000..1d247bd
--- /dev/null
+++ b/libs/audioflinger/AudioResamplerCubic.cpp
@@ -0,0 +1,184 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+
+#include "AudioResampler.h"
+#include "AudioResamplerCubic.h"
+
+#define LOG_TAG "AudioSRC"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+void AudioResamplerCubic::init() {
+    memset(&left, 0, sizeof(state));
+    memset(&right, 0, sizeof(state));
+}
+
+void AudioResamplerCubic::resample(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    // should never happen, but we overflow if it does
+    // LOG_ASSERT(outFrameCount < 32767);
+
+    // select the appropriate resampler
+    switch (mChannelCount) {
+    case 1:
+        resampleMono16(out, outFrameCount, provider);
+        break;
+    case 2:
+        resampleStereo16(out, outFrameCount, provider);
+        break;
+    }
+}
+
+void AudioResamplerCubic::resampleStereo16(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    int32_t vl = mVolume[0];
+    int32_t vr = mVolume[1];
+
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    // fetch first buffer
+    if (mBuffer.frameCount == 0) {
+        mBuffer.frameCount = inFrameCount;
+        provider->getNextBuffer(&mBuffer);
+        if (mBuffer.raw == NULL)
+            return;
+        // LOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount);
+    }
+    int16_t *in = mBuffer.i16;
+
+    while (outputIndex < outputSampleCount) {
+        int32_t sample;
+        int32_t x;
+
+        // calculate output sample
+        x = phaseFraction >> kPreInterpShift;
+        out[outputIndex++] += vl * interp(&left, x);
+        out[outputIndex++] += vr * interp(&right, x);
+        // out[outputIndex++] += vr * in[inputIndex*2];
+
+        // increment phase
+        phaseFraction += phaseIncrement;
+        uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits);
+        phaseFraction &= kPhaseMask;
+
+        // time to fetch another sample
+        while (indexIncrement--) {
+
+            inputIndex++;
+            if (inputIndex == mBuffer.frameCount) {
+                inputIndex = 0;
+                provider->releaseBuffer(&mBuffer);
+                mBuffer.frameCount = inFrameCount;
+                provider->getNextBuffer(&mBuffer);
+                if (mBuffer.raw == NULL)
+                    goto save_state;  // ugly, but efficient
+                in = mBuffer.i16;
+                // LOGW("New buffer: offset=%p, frames=%d\n", mBuffer.raw, mBuffer.frameCount);
+            }
+
+            // advance sample state
+            advance(&left, in[inputIndex*2]);
+            advance(&right, in[inputIndex*2+1]);
+        }
+    }
+
+save_state:
+    // LOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction);
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+void AudioResamplerCubic::resampleMono16(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider) {
+
+    int32_t vl = mVolume[0];
+    int32_t vr = mVolume[1];
+
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    // fetch first buffer
+    if (mBuffer.frameCount == 0) {
+        mBuffer.frameCount = inFrameCount;
+        provider->getNextBuffer(&mBuffer);
+        if (mBuffer.raw == NULL)
+            return;
+        // LOGW("New buffer: offset=%p, frames=%d\n", mBuffer.raw, mBuffer.frameCount);
+    }
+    int16_t *in = mBuffer.i16;
+
+    while (outputIndex < outputSampleCount) {
+        int32_t sample;
+        int32_t x;
+
+        // calculate output sample
+        x = phaseFraction >> kPreInterpShift;
+        sample = interp(&left, x);
+        out[outputIndex++] += vl * sample;
+        out[outputIndex++] += vr * sample;
+
+        // increment phase
+        phaseFraction += phaseIncrement;
+        uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits);
+        phaseFraction &= kPhaseMask;
+
+        // time to fetch another sample
+        while (indexIncrement--) {
+
+            inputIndex++;
+            if (inputIndex == mBuffer.frameCount) {
+                inputIndex = 0;
+                provider->releaseBuffer(&mBuffer);
+                mBuffer.frameCount = inFrameCount;
+                provider->getNextBuffer(&mBuffer);
+                if (mBuffer.raw == NULL)
+                    goto save_state;  // ugly, but efficient
+                // LOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount);
+                in = mBuffer.i16;
+            }
+
+            // advance sample state
+            advance(&left, in[inputIndex]);
+        }
+    }
+
+save_state:
+    // LOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction);
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+// ----------------------------------------------------------------------------
+}
+; // namespace android
+
diff --git a/libs/audioflinger/AudioResamplerCubic.h b/libs/audioflinger/AudioResamplerCubic.h
new file mode 100644
index 0000000..b72b62a
--- /dev/null
+++ b/libs/audioflinger/AudioResamplerCubic.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_AUDIO_RESAMPLER_CUBIC_H
+#define ANDROID_AUDIO_RESAMPLER_CUBIC_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+
+#include "AudioResampler.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class AudioResamplerCubic : public AudioResampler {
+public:
+    AudioResamplerCubic(int bitDepth, int inChannelCount, int32_t sampleRate) :
+        AudioResampler(bitDepth, inChannelCount, sampleRate) {
+    }
+    virtual void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+private:
+    // number of bits used in interpolation multiply - 14 bits avoids overflow
+    static const int kNumInterpBits = 14;
+
+    // bits to shift the phase fraction down to avoid overflow
+    static const int kPreInterpShift = kNumPhaseBits - kNumInterpBits;
+    typedef struct {
+        int32_t a, b, c, y0, y1, y2, y3;
+    } state;
+    void init();
+    void resampleMono16(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+    void resampleStereo16(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+    static inline int32_t interp(state* p, int32_t x) {
+        return (((((p->a * x >> 14) + p->b) * x >> 14) + p->c) * x >> 14) + p->y1;
+    }
+    static inline void advance(state* p, int16_t in) {
+        p->y0 = p->y1;
+        p->y1 = p->y2;
+        p->y2 = p->y3;
+        p->y3 = in;
+        p->a = (3 * (p->y1 - p->y2) - p->y0 + p->y3) >> 1;            
+        p->b = (p->y2 << 1) + p->y0 - (((5 * p->y1 + p->y3)) >> 1);
+        p->c = (p->y2 - p->y0) >> 1;
+    }
+    state left, right;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif /*ANDROID_AUDIO_RESAMPLER_CUBIC_H*/
diff --git a/libs/audioflinger/AudioResamplerSinc.cpp b/libs/audioflinger/AudioResamplerSinc.cpp
new file mode 100644
index 0000000..9e5e254
--- /dev/null
+++ b/libs/audioflinger/AudioResamplerSinc.cpp
@@ -0,0 +1,358 @@
+/*
+ * 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.
+ */
+
+#include <string.h>
+#include "AudioResamplerSinc.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+
+/*
+ * These coeficients are computed with the "fir" utility found in
+ * tools/resampler_tools
+ * TODO: A good optimization would be to transpose this matrix, to take
+ * better advantage of the data-cache.
+ */
+const int32_t AudioResamplerSinc::mFirCoefsUp[] = {
+        0x7fffffff, 0x7f15d078, 0x7c5e0da6, 0x77ecd867, 0x71e2e251, 0x6a6c304a, 0x61be7269, 0x58170412, 0x4db8ab05, 0x42e92ea6, 0x37eee214, 0x2d0e3bb1, 0x22879366, 0x18951e95, 0x0f693d0d, 0x072d2621,
+        0x00000000, 0xf9f66655, 0xf51a5fd7, 0xf16bbd84, 0xeee0d9ac, 0xed67a922, 0xece70de6, 0xed405897, 0xee50e505, 0xeff3be30, 0xf203370f, 0xf45a6741, 0xf6d67d53, 0xf957db66, 0xfbc2f647, 0xfe00f2b9,
+        0x00000000, 0x01b37218, 0x0313a0c6, 0x041d930d, 0x04d28057, 0x053731b0, 0x05534dff, 0x05309bfd, 0x04da440d, 0x045c1aee, 0x03c1fcdd, 0x03173ef5, 0x02663ae8, 0x01b7f736, 0x0113ec79, 0x007fe6a9,
+        0x00000000, 0xff96b229, 0xff44f99f, 0xff0a86be, 0xfee5f803, 0xfed518fd, 0xfed521fd, 0xfee2f4fd, 0xfefb54f8, 0xff1b159b, 0xff3f4203, 0xff6539e0, 0xff8ac502, 0xffae1ddd, 0xffcdf3f9, 0xffe96798,
+        0x00000000, 0x00119de6, 0x001e6b7e, 0x0026cb7a, 0x002b4830, 0x002c83d6, 0x002b2a82, 0x0027e67a, 0x002356f9, 0x001e098e, 0x001875e4, 0x0012fbbe, 0x000de2d1, 0x00095c10, 0x00058414, 0x00026636,
+        0x00000000, 0xfffe44a9, 0xfffd206d, 0xfffc7b7f, 0xfffc3c8f, 0xfffc4ac2, 0xfffc8f2b, 0xfffcf5c4, 0xfffd6df3, 0xfffdeab2, 0xfffe6275, 0xfffececf, 0xffff2c07, 0xffff788c, 0xffffb471, 0xffffe0f2,
+        0x00000000, 0x000013e6, 0x00001f03, 0x00002396, 0x00002399, 0x000020b6, 0x00001c3c, 0x00001722, 0x00001216, 0x00000d81, 0x0000099c, 0x0000067c, 0x00000419, 0x0000025f, 0x00000131, 0x00000070,
+        0x00000000, 0xffffffc7, 0xffffffb3, 0xffffffb3, 0xffffffbe, 0xffffffcd, 0xffffffdb, 0xffffffe7, 0xfffffff0, 0xfffffff7, 0xfffffffb, 0xfffffffe, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
+        0x00000000 // this one is needed for lerping the last coefficient
+};
+
+/*
+ * These coefficients are optimized for 48KHz -> 44.1KHz (stop-band at 22.050KHz)
+ * It's possible to use the above coefficient for any down-sampling
+ * at the expense of a slower processing loop (we can interpolate
+ * these coefficient from the above by "Stretching" them in time).
+ */
+const int32_t AudioResamplerSinc::mFirCoefsDown[] = {
+        0x7fffffff, 0x7f55e46d, 0x7d5b4c60, 0x7a1b4b98, 0x75a7fb14, 0x7019f0bd, 0x698f875a, 0x622bfd59, 0x5a167256, 0x5178cc54, 0x487e8e6c, 0x3f53aae8, 0x36235ad4, 0x2d17047b, 0x245539ab, 0x1c00d540,
+        0x14383e57, 0x0d14d5ca, 0x06aa910b, 0x0107c38b, 0xfc351654, 0xf835abae, 0xf5076b45, 0xf2a37202, 0xf0fe9faa, 0xf00a3bbd, 0xefb4aa81, 0xefea2b05, 0xf0959716, 0xf1a11e83, 0xf2f6f7a0, 0xf481fff4,
+        0xf62e48ce, 0xf7e98ca5, 0xf9a38b4c, 0xfb4e4bfa, 0xfcde456f, 0xfe4a6d30, 0xff8c2fdf, 0x009f5555, 0x0181d393, 0x0233940f, 0x02b62f06, 0x030ca07d, 0x033afa62, 0x03461725, 0x03334f83, 0x030835fa,
+        0x02ca59cc, 0x027f12d1, 0x022b570d, 0x01d39a49, 0x017bb78f, 0x0126e414, 0x00d7aaaf, 0x008feec7, 0x0050f584, 0x001b73e3, 0xffefa063, 0xffcd46ed, 0xffb3ddcd, 0xffa29aaa, 0xff988691, 0xff949066,
+        0xff959d24, 0xff9a959e, 0xffa27195, 0xffac4011, 0xffb72d2b, 0xffc28569, 0xffcdb706, 0xffd85171, 0xffe20364, 0xffea97e9, 0xfff1f2b2, 0xfff80c06, 0xfffcec92, 0x0000a955, 0x00035fd8, 0x000532cf,
+        0x00064735, 0x0006c1f9, 0x0006c62d, 0x000673ba, 0x0005e68f, 0x00053630, 0x000475a3, 0x0003b397, 0x0002fac1, 0x00025257, 0x0001be9e, 0x0001417a, 0x0000dafd, 0x000089eb, 0x00004c28, 0x00001f1d,
+        0x00000000, 0xffffec10, 0xffffe0be, 0xffffdbc5, 0xffffdb39, 0xffffdd8b, 0xffffe182, 0xffffe638, 0xffffeb0a, 0xffffef8f, 0xfffff38b, 0xfffff6e3, 0xfffff993, 0xfffffba6, 0xfffffd30, 0xfffffe4a,
+        0xffffff09, 0xffffff85, 0xffffffd1, 0xfffffffb, 0x0000000f, 0x00000016, 0x00000015, 0x00000012, 0x0000000d, 0x00000009, 0x00000006, 0x00000003, 0x00000002, 0x00000001, 0x00000000, 0x00000000,
+        0x00000000 // this one is needed for lerping the last coefficient
+};
+
+// ----------------------------------------------------------------------------
+
+static inline
+int32_t mulRL(int left, int32_t in, uint32_t vRL)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    if (left) {
+        asm( "smultb %[out], %[in], %[vRL] \n"
+             : [out]"=r"(out)
+             : [in]"%r"(in), [vRL]"r"(vRL)
+             : );
+    } else {
+        asm( "smultt %[out], %[in], %[vRL] \n"
+             : [out]"=r"(out)
+             : [in]"%r"(in), [vRL]"r"(vRL)
+             : );
+    }
+    return out;
+#else
+    if (left) {
+        return int16_t(in>>16) * int16_t(vRL&0xFFFF);
+    } else {
+        return int16_t(in>>16) * int16_t(vRL>>16);
+    }
+#endif
+}
+
+static inline
+int32_t mulAdd(int16_t in, int32_t v, int32_t a)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    asm( "smlawb %[out], %[v], %[in], %[a] \n"
+         : [out]"=r"(out)
+         : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
+         : );
+    return out;
+#else
+    return a + in * (v>>16);
+    // improved precision
+    // return a + in * (v>>16) + ((in * (v & 0xffff)) >> 16);
+#endif
+}
+
+static inline
+int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    int32_t out;
+    if (left) {
+        asm( "smlawb %[out], %[v], %[inRL], %[a] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
+             : );
+    } else {
+        asm( "smlawt %[out], %[v], %[inRL], %[a] \n"
+             : [out]"=r"(out)
+             : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
+             : );
+    }
+    return out;
+#else
+    if (left) {
+        return a + (int16_t(inRL&0xFFFF) * (v>>16));
+        //improved precision
+        // return a + (int16_t(inRL&0xFFFF) * (v>>16)) + ((int16_t(inRL&0xFFFF) * (v & 0xffff)) >> 16);
+    } else {
+        return a + (int16_t(inRL>>16) * (v>>16));
+    }
+#endif
+}
+
+// ----------------------------------------------------------------------------
+
+AudioResamplerSinc::AudioResamplerSinc(int bitDepth,
+        int inChannelCount, int32_t sampleRate)
+    : AudioResampler(bitDepth, inChannelCount, sampleRate),
+    mState(0)
+{
+    /*
+     * Layout of the state buffer for 32 tap:
+     *
+     * "present" sample            beginning of 2nd buffer
+     *                 v                v
+     *  0              01               2              23              3
+     *  0              F0               0              F0              F
+     * [pppppppppppppppInnnnnnnnnnnnnnnnpppppppppppppppInnnnnnnnnnnnnnnn]
+     *                 ^               ^ head
+     *
+     * p = past samples, convoluted with the (p)ositive side of sinc()
+     * n = future samples, convoluted with the (n)egative side of sinc()
+     * r = extra space for implementing the ring buffer
+     *
+     */
+
+    const size_t numCoefs = 2*halfNumCoefs;
+    const size_t stateSize = numCoefs * inChannelCount * 2;
+    mState = new int16_t[stateSize];
+    memset(mState, 0, sizeof(int16_t)*stateSize);
+    mImpulse = mState + (halfNumCoefs-1)*inChannelCount;
+    mRingFull = mImpulse + (numCoefs+1)*inChannelCount;
+}
+
+AudioResamplerSinc::~AudioResamplerSinc()
+{
+    delete [] mState;
+}
+
+void AudioResamplerSinc::init() {
+}
+
+void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider)
+{
+    mFirCoefs = (mInSampleRate <= mSampleRate) ? mFirCoefsUp : mFirCoefsDown;
+
+    // select the appropriate resampler
+    switch (mChannelCount) {
+    case 1:
+        resample<1>(out, outFrameCount, provider);
+        break;
+    case 2:
+        resample<2>(out, outFrameCount, provider);
+        break;
+    }
+}
+
+
+template<int CHANNELS>
+void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
+        AudioBufferProvider* provider)
+{
+    int16_t* impulse = mImpulse;
+    uint32_t vRL = mVolumeRL;
+    size_t inputIndex = mInputIndex;
+    uint32_t phaseFraction = mPhaseFraction;
+    uint32_t phaseIncrement = mPhaseIncrement;
+    size_t outputIndex = 0;
+    size_t outputSampleCount = outFrameCount * 2;
+    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
+
+    AudioBufferProvider::Buffer& buffer(mBuffer);
+    while (outputIndex < outputSampleCount) {
+        // buffer is empty, fetch a new one
+        while (buffer.frameCount == 0) {
+            buffer.frameCount = inFrameCount;
+            provider->getNextBuffer(&buffer);
+            if (buffer.raw == NULL) {
+                goto resample_exit;
+            }
+            const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
+            if (phaseIndex == 1) {
+                // read one frame
+                read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
+            } else if (phaseIndex == 2) {
+                // read 2 frames
+                read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
+                inputIndex++;
+                if (inputIndex >= mBuffer.frameCount) {
+                    inputIndex -= mBuffer.frameCount;
+                    provider->releaseBuffer(&buffer);
+                } else {
+                    read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
+                }
+           }
+        }
+        int16_t *in = buffer.i16;
+        const size_t frameCount = buffer.frameCount;
+
+        // Always read-in the first samples from the input buffer
+        int16_t* head = impulse + halfNumCoefs*CHANNELS;
+        head[0] = in[inputIndex*CHANNELS + 0];
+        if (CHANNELS == 2)
+            head[1] = in[inputIndex*CHANNELS + 1];
+
+        // handle boundary case
+        int32_t l, r;
+        while (outputIndex < outputSampleCount) {
+            filterCoefficient<CHANNELS>(l, r, phaseFraction, impulse);
+            out[outputIndex++] += 2 * mulRL(1, l, vRL);
+            out[outputIndex++] += 2 * mulRL(0, r, vRL);
+
+            phaseFraction += phaseIncrement;
+            const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
+            if (phaseIndex == 1) {
+                inputIndex++;
+                if (inputIndex >= frameCount)
+                    break;  // need a new buffer
+                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
+            } else if(phaseIndex == 2) {    // maximum value
+                inputIndex++;
+                if (inputIndex >= frameCount)
+                    break;  // 0 frame available, 2 frames needed
+                // read first frame
+                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
+                inputIndex++;
+                if (inputIndex >= frameCount)
+                    break;  // 0 frame available, 1 frame needed
+                // read second frame
+                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
+            }
+        }
+
+        // if done with buffer, save samples
+        if (inputIndex >= frameCount) {
+            inputIndex -= frameCount;
+            provider->releaseBuffer(&buffer);
+        }
+    }
+
+resample_exit:
+    mImpulse = impulse;
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+template<int CHANNELS>
+/***
+* read()
+*
+* This function reads only one frame from input buffer and writes it in
+* state buffer
+*
+**/
+void AudioResamplerSinc::read(
+        int16_t*& impulse, uint32_t& phaseFraction,
+        int16_t const* in, size_t inputIndex)
+{
+    const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
+    impulse += CHANNELS;
+    phaseFraction -= 1LU<<kNumPhaseBits;
+    if (impulse >= mRingFull) {
+        const size_t stateSize = (halfNumCoefs*2)*CHANNELS;
+        memcpy(mState, mState+stateSize, sizeof(int16_t)*stateSize);
+        impulse -= stateSize;
+    }
+    int16_t* head = impulse + halfNumCoefs*CHANNELS;
+    head[0] = in[inputIndex*CHANNELS + 0];
+    if (CHANNELS == 2)
+        head[1] = in[inputIndex*CHANNELS + 1];
+}
+
+template<int CHANNELS>
+void AudioResamplerSinc::filterCoefficient(
+        int32_t& l, int32_t& r, uint32_t phase, int16_t const *samples)
+{
+    // compute the index of the coefficient on the positive side and
+    // negative side
+    uint32_t indexP = (phase & cMask) >> cShift;
+    uint16_t lerpP  = (phase & pMask) >> pShift;
+    uint32_t indexN = (-phase & cMask) >> cShift;
+    uint16_t lerpN  = (-phase & pMask) >> pShift;
+    if ((indexP == 0) && (lerpP == 0)) {
+        indexN = cMask >> cShift;
+        lerpN = pMask >> pShift;
+    }
+
+    l = 0;
+    r = 0;
+    int32_t const* coefs = mFirCoefs;
+    int16_t const *sP = samples;
+    int16_t const *sN = samples+CHANNELS;
+    for (unsigned int i=0 ; i<halfNumCoefs/4 ; i++) {
+        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
+        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
+        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
+        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
+        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
+        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
+        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
+        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
+        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
+        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
+        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
+        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
+    }
+}
+
+template<int CHANNELS>
+void AudioResamplerSinc::interpolate(
+        int32_t& l, int32_t& r,
+        int32_t const* coefs, int16_t lerp, int16_t const* samples)
+{
+    int32_t c0 = coefs[0];
+    int32_t c1 = coefs[1];
+    int32_t sinc = mulAdd(lerp, (c1-c0)<<1, c0);
+    if (CHANNELS == 2) {
+        uint32_t rl = *reinterpret_cast<uint32_t const*>(samples);
+        l = mulAddRL(1, rl, sinc, l);
+        r = mulAddRL(0, rl, sinc, r);
+    } else {
+        r = l = mulAdd(samples[0], sinc, l);
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/libs/audioflinger/AudioResamplerSinc.h b/libs/audioflinger/AudioResamplerSinc.h
new file mode 100644
index 0000000..e6cb90b
--- /dev/null
+++ b/libs/audioflinger/AudioResamplerSinc.h
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_AUDIO_RESAMPLER_SINC_H
+#define ANDROID_AUDIO_RESAMPLER_SINC_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+
+#include "AudioResampler.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class AudioResamplerSinc : public AudioResampler {
+public:
+    AudioResamplerSinc(int bitDepth, int inChannelCount, int32_t sampleRate);
+
+    ~AudioResamplerSinc();
+
+    virtual void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+private:
+    void init();
+
+    template<int CHANNELS>
+    void resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider);
+
+    template<int CHANNELS>
+    inline void filterCoefficient(
+            int32_t& l, int32_t& r, uint32_t phase, int16_t const *samples);
+
+    template<int CHANNELS>
+    inline void interpolate(
+            int32_t& l, int32_t& r,
+            int32_t const* coefs, int16_t lerp, int16_t const* samples);
+
+    template<int CHANNELS>
+    inline void read(int16_t*& impulse, uint32_t& phaseFraction,
+            int16_t const* in, size_t inputIndex);
+
+    int16_t *mState;
+    int16_t *mImpulse;
+    int16_t *mRingFull;
+
+    int32_t const * mFirCoefs;
+    static const int32_t mFirCoefsDown[];
+    static const int32_t mFirCoefsUp[];
+
+    // ----------------------------------------------------------------------------
+    static const int32_t RESAMPLE_FIR_NUM_COEF       = 8;
+    static const int32_t RESAMPLE_FIR_LERP_INT_BITS  = 4;
+
+    // we have 16 coefs samples per zero-crossing
+    static const int coefsBits = RESAMPLE_FIR_LERP_INT_BITS;        // 4
+    static const int cShift = kNumPhaseBits - coefsBits;            // 26
+    static const uint32_t cMask  = ((1<<coefsBits)-1) << cShift;    // 0xf<<26 = 3c00 0000
+
+    // and we use 15 bits to interpolate between these samples
+    // this cannot change because the mul below rely on it.
+    static const int pLerpBits = 15;
+    static const int pShift = kNumPhaseBits - coefsBits - pLerpBits;    // 11
+    static const uint32_t pMask  = ((1<<pLerpBits)-1) << pShift;    // 0x7fff << 11
+
+    // number of zero-crossing on each side
+    static const unsigned int halfNumCoefs = RESAMPLE_FIR_NUM_COEF;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif /*ANDROID_AUDIO_RESAMPLER_SINC_H*/
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
new file mode 100644
index 0000000..496e271
--- /dev/null
+++ b/libs/surfaceflinger/Android.mk
@@ -0,0 +1,49 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    clz.cpp.arm \
+    DisplayHardware/DisplayHardware.cpp \
+    DisplayHardware/DisplayHardwareBase.cpp \
+    GPUHardware/GPUHardware.cpp \
+    BootAnimation.cpp \
+    BlurFilter.cpp.arm \
+    CPUGauge.cpp \
+    Layer.cpp \
+    LayerBase.cpp \
+    LayerBuffer.cpp \
+    LayerBlur.cpp \
+    LayerBitmap.cpp \
+    LayerDim.cpp \
+    LayerOrientationAnim.cpp \
+    OrientationAnimation.cpp \
+    SurfaceFlinger.cpp \
+    Tokenizer.cpp \
+    Transform.cpp \
+    VRamHeap.cpp
+
+
+# need "-lrt" on Linux simulator to pick up clock_gettime
+ifeq ($(TARGET_SIMULATOR),true)
+	ifeq ($(HOST_OS),linux)
+		LOCAL_LDLIBS += -lrt
+	endif
+endif
+
+LOCAL_SHARED_LIBRARIES := \
+	libhardware \
+	libutils \
+	libcutils \
+	libui \
+	libcorecg \
+	libsgl \
+	libpixelflinger \
+	libEGL \
+	libGLESv1_CM
+
+LOCAL_C_INCLUDES := \
+	$(call include-path-for, corecg graphics)
+
+LOCAL_MODULE:= libsurfaceflinger
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/surfaceflinger/Barrier.h b/libs/surfaceflinger/Barrier.h
new file mode 100644
index 0000000..e2bcf6a
--- /dev/null
+++ b/libs/surfaceflinger/Barrier.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_BARRIER_H
+#define ANDROID_BARRIER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class Barrier
+{
+public:
+    inline Barrier() : state(CLOSED) { }
+    inline ~Barrier() { }
+    void open() {
+        // gcc memory barrier, this makes sure all memory writes
+        // have been issued by gcc. On an SMP system we'd need a real
+        // h/w barrier.
+        asm volatile ("":::"memory");
+        Mutex::Autolock _l(lock);
+        state = OPENED;
+        cv.broadcast();
+    }
+    void close() {
+        Mutex::Autolock _l(lock);
+        state = CLOSED;
+    }
+    void wait() const {
+        Mutex::Autolock _l(lock);
+        while (state == CLOSED) {
+            cv.wait(lock);
+        }
+    }
+private:
+    enum { OPENED, CLOSED };
+    mutable     Mutex       lock;
+    mutable     Condition   cv;
+    volatile    int         state;
+};
+
+}; // namespace android
+
+#endif // ANDROID_BARRIER_H
diff --git a/libs/surfaceflinger/BlurFilter.cpp b/libs/surfaceflinger/BlurFilter.cpp
new file mode 100644
index 0000000..5dc0ba0
--- /dev/null
+++ b/libs/surfaceflinger/BlurFilter.cpp
@@ -0,0 +1,326 @@
+/* 
+**
+** 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.
+*/
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <utils/Errors.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "clz.h"
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+namespace android {
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+inline uint32_t BLUR_RGBA_TO_HOST(uint32_t v) {
+    return v;
+}
+inline uint32_t BLUR_HOST_TO_RGBA(uint32_t v) {
+    return v;
+}
+#else
+inline uint32_t BLUR_RGBA_TO_HOST(uint32_t v) {
+    return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
+}
+inline uint32_t BLUR_HOST_TO_RGBA(uint32_t v) {
+    return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
+}
+#endif
+
+const int BLUR_DITHER_BITS = 6;  // dither weights stored on 6 bits
+const int BLUR_DITHER_ORDER_SHIFT= 3;
+const int BLUR_DITHER_ORDER      = (1<<BLUR_DITHER_ORDER_SHIFT);
+const int BLUR_DITHER_SIZE       = BLUR_DITHER_ORDER * BLUR_DITHER_ORDER;
+const int BLUR_DITHER_MASK       = BLUR_DITHER_ORDER-1;
+
+static const uint8_t gDitherMatrix[BLUR_DITHER_SIZE] = {
+     0, 32,  8, 40,  2, 34, 10, 42,
+    48, 16, 56, 24, 50, 18, 58, 26,
+    12, 44,  4, 36, 14, 46,  6, 38,
+    60, 28, 52, 20, 62, 30, 54, 22,
+     3, 35, 11, 43,  1, 33,  9, 41,
+    51, 19, 59, 27, 49, 17, 57, 25,
+    15, 47,  7, 39, 13, 45,  5, 37,
+    63, 31, 55, 23, 61, 29, 53, 21
+};
+
+
+template <int FACTOR = 0>
+struct BlurColor565
+{
+    typedef uint16_t type;
+    int r, g, b;    
+    inline BlurColor565() { }
+    inline BlurColor565(uint16_t v) {
+        r = v >> 11;
+        g = (v >> 5) & 0x3E;
+        b = v & 0x1F;
+    }
+    inline void clear() { r=g=b=0; }
+    inline uint16_t to(int shift, int last, int dither) const {
+        int R = r;
+        int G = g;
+        int B = b;
+        if  (UNLIKELY(last)) {
+            if (FACTOR>0) {
+                int L = (R+G+B)>>1;
+                R += (((L>>1) - R) * FACTOR) >> 8;
+                G += (((L   ) - G) * FACTOR) >> 8;
+                B += (((L>>1) - B) * FACTOR) >> 8;
+            }
+            R += (dither << shift) >> BLUR_DITHER_BITS;
+            G += (dither << shift) >> BLUR_DITHER_BITS;
+            B += (dither << shift) >> BLUR_DITHER_BITS;
+        }
+        R >>= shift;
+        G >>= shift;
+        B >>= shift;
+        return (R<<11) | (G<<5) | B;
+    }    
+    inline BlurColor565& operator += (const BlurColor565& rhs) {
+        r += rhs.r;
+        g += rhs.g;
+        b += rhs.b;
+        return *this;
+    }
+    inline BlurColor565& operator -= (const BlurColor565& rhs) {
+        r -= rhs.r;
+        g -= rhs.g;
+        b -= rhs.b;
+        return *this;
+    }
+};
+
+struct BlurGray565
+{
+    typedef uint16_t type;
+    int l;    
+    inline BlurGray565() { }
+    inline BlurGray565(uint16_t v) {
+        int r = v >> 11;
+        int g = (v >> 5) & 0x3F;
+        int b = v & 0x1F;
+        l = (r + g + b + 1)>>1;
+    }
+    inline void clear() { l=0; }
+    inline uint16_t to(int shift, int last, int dither) const {
+        int L = l;
+        if  (UNLIKELY(last)) {
+            L += (dither << shift) >> BLUR_DITHER_BITS;
+        }
+        L >>= shift;
+        return ((L>>1)<<11) | (L<<5) | (L>>1);
+    }
+    inline BlurGray565& operator += (const BlurGray565& rhs) {
+        l += rhs.l;
+        return *this;
+    }
+    inline BlurGray565& operator -= (const BlurGray565& rhs) {
+        l -= rhs.l;
+        return *this;
+    }
+};
+
+struct BlurGray8888
+{
+    typedef uint32_t type;
+    int l, a;    
+    inline BlurGray8888() { }
+    inline BlurGray8888(uint32_t v) {
+        v = BLUR_RGBA_TO_HOST(v);
+        int r = v & 0xFF;
+        int g = (v >>  8) & 0xFF;
+        int b = (v >> 16) & 0xFF;
+        a = v >> 24;
+        l = r + g + g + b;
+    }    
+    inline void clear() { l=a=0; }
+    inline uint32_t to(int shift, int last, int dither) const {
+        int L = l;
+        int A = a;
+        if  (UNLIKELY(last)) {
+            L += (dither << (shift+2)) >> BLUR_DITHER_BITS;
+            A += (dither << shift) >> BLUR_DITHER_BITS;
+        }
+        L >>= (shift+2);
+        A >>= shift;
+        return BLUR_HOST_TO_RGBA((A<<24) | (L<<16) | (L<<8) | L);
+    }
+    inline BlurGray8888& operator += (const BlurGray8888& rhs) {
+        l += rhs.l;
+        a += rhs.a;
+        return *this;
+    }
+    inline BlurGray8888& operator -= (const BlurGray8888& rhs) {
+        l -= rhs.l;
+        a -= rhs.a;
+        return *this;
+    }
+};
+
+
+template<typename PIXEL>
+static status_t blurFilter(
+        GGLSurface const* dst,
+        GGLSurface const* src,
+        int kernelSizeUser,
+        int repeat)
+{
+    typedef typename PIXEL::type TYPE;
+
+    const int shift             = 31 - clz(kernelSizeUser);
+    const int areaShift         = shift*2;
+    const int kernelSize        = 1<<shift;
+    const int kernelHalfSize    = kernelSize/2;
+    const int mask              = kernelSize-1;
+    const int w                 = src->width;
+    const int h                 = src->height;
+    const uint8_t* ditherMatrix = gDitherMatrix;
+
+    // we need a temporary buffer to store one line of blurred columns
+    // as well as kernelSize lines of source pixels organized as a ring buffer.
+    void* const temporary_buffer = malloc(
+            (w + kernelSize) * sizeof(PIXEL) +
+            (src->stride * kernelSize) * sizeof(TYPE));
+    if (!temporary_buffer)
+        return NO_MEMORY;
+
+    PIXEL* const sums = (PIXEL*)temporary_buffer;
+    TYPE* const scratch = (TYPE*)(sums + w + kernelSize);
+
+    // Apply the blur 'repeat' times, this is used to approximate
+    // gaussian blurs. 3 times gives good results.
+    for (int k=0 ; k<repeat ; k++) {
+
+        // Clear the columns sums for this round
+        memset(sums, 0, (w + kernelSize) * sizeof(PIXEL));
+        TYPE* head;
+        TYPE pixel;
+        PIXEL current;
+
+        // Since we're going to override the source data we need
+        // to copy it in a temporary buffer. Only kernelSize lines are
+        // required. But since we start in the center of the kernel,
+        // we only copy half of the data, and fill the rest with zeros
+        // (assuming black/transparent pixels).
+        memcpy( scratch + src->stride*kernelHalfSize,
+                src->data,
+                src->stride*kernelHalfSize*sizeof(TYPE));
+
+        // sum half of each column, because we assume the first half is
+        // zeros (black/transparent).
+        for (int y=0 ; y<kernelHalfSize ; y++) {
+            head = (TYPE*)src->data + y*src->stride;
+            for (int x=0 ; x<w ; x++)
+                sums[x] += PIXEL( *head++ );
+        }
+
+        for (int y=0 ; y<h ; y++) {
+            TYPE* fb = (TYPE*)dst->data + y*dst->stride;
+
+            // compute the dither matrix line
+            uint8_t const * ditherY = ditherMatrix
+                    + (y & BLUR_DITHER_MASK)*BLUR_DITHER_ORDER;
+
+            // Horizontal blur pass on the columns sums
+            int count, dither, x=0;
+            PIXEL const * out= sums;
+            PIXEL const * in = sums;
+            current.clear();
+
+            count = kernelHalfSize;
+            do {
+                current += *in;
+                in++;
+            } while (--count);
+            
+            count = kernelHalfSize;
+            do {
+                current += *in;
+                dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
+                *fb++ = current.to(areaShift, k==repeat-1, dither);
+                in++;
+            } while (--count);
+
+            count = w-kernelSize;
+            do {
+                current += *in;
+                current -= *out;
+                dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
+                *fb++ = current.to(areaShift, k==repeat-1, dither);
+                in++, out++;
+            } while (--count);
+
+            count = kernelHalfSize;
+            do {
+                current -= *out;
+                dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
+                *fb++ = current.to(areaShift, k==repeat-1, dither);
+                out++;
+            } while (--count);
+
+            // vertical blur pass, subtract the oldest line from each columns
+            // and add a new line. Subtract or add zeros at the top
+            // and bottom edges.
+            TYPE* const tail = scratch + (y & mask) * src->stride;
+            if (y >= kernelHalfSize) {
+                for (int x=0 ; x<w ; x++)
+                    sums[x] -= PIXEL( tail[x] );
+            }
+            if (y < h-kernelSize) {
+                memcpy( tail,
+                        (TYPE*)src->data + (y+kernelHalfSize)*src->stride,
+                        src->stride*sizeof(TYPE));
+                for (int x=0 ; x<w ; x++)
+                    sums[x] += PIXEL( tail[x] );
+            }
+        }
+
+        // The subsequent passes are always done in-place.
+        src = dst;
+    }
+    
+    free(temporary_buffer);
+
+    return NO_ERROR;
+}
+
+template status_t blurFilter< BlurColor565<0x80> >(
+        GGLSurface const* dst,
+        GGLSurface const* src,
+        int kernelSizeUser,
+        int repeat);
+
+status_t blurFilter(
+        GGLSurface const* image,
+        int kernelSizeUser,
+        int repeat)
+{
+    return blurFilter< BlurColor565<0x80> >(image, image, kernelSizeUser, repeat);
+}
+
+} // namespace android
+
+//err = blur< BlurColor565<0x80> >(dst, src, kernelSizeUser, repeat);
+//err = blur<BlurGray565>(dst, src, kernelSizeUser, repeat);
+//err = blur<BlurGray8888>(dst, src, kernelSizeUser, repeat);
diff --git a/libs/surfaceflinger/BlurFilter.h b/libs/surfaceflinger/BlurFilter.h
new file mode 100644
index 0000000..294db43
--- /dev/null
+++ b/libs/surfaceflinger/BlurFilter.h
@@ -0,0 +1,35 @@
+/* 
+**
+** 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.
+*/
+
+#ifndef ANDROID_BLUR_FILTER_H
+#define ANDROID_BLUR_FILTER_H
+
+#include <stdint.h>
+#include <utils/Errors.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+namespace android {
+
+status_t blurFilter(
+        GGLSurface const* image,
+        int kernelSizeUser,
+        int repeat);
+
+} // namespace android
+
+#endif // ANDROID_BLUR_FILTER_H
diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp
new file mode 100644
index 0000000..2b30336
--- /dev/null
+++ b/libs/surfaceflinger/BootAnimation.cpp
@@ -0,0 +1,403 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "BootAnimation"
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <math.h>
+#include <fcntl.h>
+#include <utils/misc.h>
+
+#include <utils/threads.h>
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/AssetManager.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+#include <ui/DisplayInfo.h>
+#include <ui/ISurfaceComposer.h>
+#include <ui/ISurfaceFlingerClient.h>
+#include <ui/EGLNativeWindowSurface.h>
+
+#include <core/SkBitmap.h>
+#include <images/SkImageDecoder.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <EGL/eglext.h>
+
+#include "BootAnimation.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+BootAnimation::BootAnimation(const sp<ISurfaceComposer>& composer) :
+    Thread(false) {
+    mSession = SurfaceComposerClient::clientForConnection(
+            composer->createConnection()->asBinder());
+}
+
+BootAnimation::~BootAnimation() {
+}
+
+void BootAnimation::onFirstRef() {
+    run("BootAnimation", PRIORITY_DISPLAY);
+}
+
+const sp<SurfaceComposerClient>& BootAnimation::session() const {
+    return mSession;
+}
+
+status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
+        const char* name) {
+    Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
+    if (!asset)
+        return NO_INIT;
+    SkBitmap bitmap;
+    SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
+            &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
+    asset->close();
+    delete asset;
+
+    // ensure we can call getPixels(). No need to call unlock, since the
+    // bitmap will go out of scope when we return from this method.
+    bitmap.lockPixels();
+
+    const int w = bitmap.width();
+    const int h = bitmap.height();
+    const void* p = bitmap.getPixels();
+
+    GLint crop[4] = { 0, h, w, -h };
+    texture->w = w;
+    texture->h = h;
+
+    glGenTextures(1, &texture->name);
+    glBindTexture(GL_TEXTURE_2D, texture->name);
+
+    switch (bitmap.getConfig()) {
+        case SkBitmap::kA8_Config:
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA,
+                    GL_UNSIGNED_BYTE, p);
+            break;
+        case SkBitmap::kARGB_4444_Config:
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
+                    GL_UNSIGNED_SHORT_4_4_4_4, p);
+            break;
+        case SkBitmap::kARGB_8888_Config:
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
+                    GL_UNSIGNED_BYTE, p);
+            break;
+        case SkBitmap::kRGB_565_Config:
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB,
+                    GL_UNSIGNED_SHORT_5_6_5, p);
+            break;
+        default:
+            break;
+    }
+
+    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    return NO_ERROR;
+}
+
+status_t BootAnimation::readyToRun() {
+    mAssets.addDefaultAssets();
+
+    DisplayInfo dinfo;
+    status_t status = session()->getDisplayInfo(0, &dinfo);
+    if (status)
+        return -1;
+
+    // create the native surface
+    sp<Surface> s = session()->createSurface(getpid(), 0, dinfo.w, dinfo.h,
+            PIXEL_FORMAT_RGB_565);
+    session()->openTransaction();
+    s->setLayer(0x40000000);
+    session()->closeTransaction();
+
+    // initialize opengl and egl
+    const EGLint attribs[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6,
+            EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 0, EGL_NONE };
+    EGLint w, h, dummy;
+    EGLint numConfigs;
+    EGLConfig config;
+    EGLSurface surface;
+    EGLContext context;
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglChooseConfig(display, attribs, &config, 1, &numConfigs);
+
+    mNativeWindowSurface = new EGLNativeWindowSurface(s);
+    surface = eglCreateWindowSurface(display, config, 
+            mNativeWindowSurface.get(), NULL);
+
+    context = eglCreateContext(display, config, NULL, NULL);
+    eglQuerySurface(display, surface, EGL_WIDTH, &w);
+    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
+    eglMakeCurrent(display, surface, surface, context);
+    mDisplay = display;
+    mContext = context;
+    mSurface = surface;
+    mWidth = w;
+    mHeight = h;
+    mFlingerSurface = s;
+
+    // initialize GL
+    glShadeModel(GL_FLAT);
+    glEnable(GL_DITHER);
+    glEnable(GL_TEXTURE_2D);
+    glEnable(GL_SCISSOR_TEST);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+    return NO_ERROR;
+}
+
+void BootAnimation::requestExit() {
+    mBarrier.open();
+    Thread::requestExit();
+}
+
+bool BootAnimation::threadLoop() {
+    bool r = android();
+    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    eglDestroyContext(mDisplay, mContext);
+    eglDestroySurface(mDisplay, mSurface);
+    mNativeWindowSurface.clear();
+    return r;
+}
+
+bool BootAnimation::android() {
+    initTexture(&mAndroid[0], mAssets, "images/android_320x480.png");
+    initTexture(&mAndroid[1], mAssets, "images/boot_robot.png");
+    initTexture(&mAndroid[2], mAssets, "images/boot_robot_glow.png");
+
+    // erase screen
+    glDisable(GL_SCISSOR_TEST);
+    glBindTexture(GL_TEXTURE_2D, mAndroid[0].name);
+
+    // clear screen
+    glClear(GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(mDisplay, mSurface);
+
+    // wait ~1s
+    usleep(800000);
+
+    // fade in
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    const int steps = 8;
+    for (int i = 1; i < steps; i++) {
+        float fade = i / float(steps);
+        glColor4f(1, 1, 1, fade * fade);
+        glClear(GL_COLOR_BUFFER_BIT);
+        glDrawTexiOES(0, 0, 0, mAndroid[0].w, mAndroid[0].h);
+        eglSwapBuffers(mDisplay, mSurface);
+    }
+
+    // draw last frame
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    glDisable(GL_BLEND);
+    glDrawTexiOES(0, 0, 0, mAndroid[0].w, mAndroid[0].h);
+    eglSwapBuffers(mDisplay, mSurface);
+
+    // update rect for the robot
+    const int x = mWidth - mAndroid[1].w - 33;
+    const int y = (mHeight - mAndroid[1].h) / 2 - 1;
+    const Rect updateRect(x, y, x + mAndroid[1].w, y + mAndroid[1].h);
+
+    // draw and update only what we need
+    mNativeWindowSurface->setSwapRectangle(updateRect.left,
+            updateRect.top, updateRect.width(), updateRect.height());
+
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(updateRect.left, mHeight - updateRect.bottom, updateRect.width(),
+            updateRect.height());
+
+    const nsecs_t startTime = systemTime();
+    do {
+        // glow speed and shape
+        nsecs_t time = systemTime() - startTime;
+        float t = ((4.0f / (360.0f * us2ns(16667))) * time);
+        t = t - floorf(t);
+        const float fade = 0.5f + 0.5f * sinf(t * 2 * M_PI);
+
+        // fade the glow in and out
+        glDisable(GL_BLEND);
+        glBindTexture(GL_TEXTURE_2D, mAndroid[2].name);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+        glColor4f(fade, fade, fade, fade);
+        glDrawTexiOES(updateRect.left, mHeight - updateRect.bottom, 0,
+                updateRect.width(), updateRect.height());
+
+        // draw the robot
+        glEnable(GL_BLEND);
+        glBindTexture(GL_TEXTURE_2D, mAndroid[1].name);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        glDrawTexiOES(updateRect.left, mHeight - updateRect.bottom, 0,
+                updateRect.width(), updateRect.height());
+
+        // make sure sleep a lot to not take too much CPU away from 
+        // the boot process. With this "glow" animation there is no
+        // visible difference. 
+        usleep(16667 * 4);
+
+        eglSwapBuffers(mDisplay, mSurface);
+    } while (!exitPending());
+
+    glDeleteTextures(1, &mAndroid[0].name);
+    glDeleteTextures(1, &mAndroid[1].name);
+    glDeleteTextures(1, &mAndroid[2].name);
+    return false;
+}
+
+bool BootAnimation::cylon() {
+    // initialize the textures...
+    initTexture(&mLeftTrail, mAssets, "images/cylon_left.png");
+    initTexture(&mRightTrail, mAssets, "images/cylon_right.png");
+    initTexture(&mBrightSpot, mAssets, "images/cylon_dot.png");
+
+    int w = mWidth;
+    int h = mHeight;
+
+    const Point c(w / 2, h / 2);
+    const GLint amplitude = 60;
+    const int scx = c.x - amplitude - mBrightSpot.w / 2;
+    const int scy = c.y - mBrightSpot.h / 2;
+    const int scw = amplitude * 2 + mBrightSpot.w;
+    const int sch = mBrightSpot.h;
+    const Rect updateRect(scx, h - scy - sch, scx + scw, h - scy);
+
+    // erase screen
+    glDisable(GL_SCISSOR_TEST);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    eglSwapBuffers(mDisplay, mSurface);
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    mNativeWindowSurface->setSwapRectangle(updateRect.left,
+            updateRect.top, updateRect.width(), updateRect.height());
+
+    glEnable(GL_SCISSOR_TEST);
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+    // clear the screen to white
+    Point p;
+    float t = 0;
+    float alpha = 1.0f;
+    const nsecs_t startTime = systemTime();
+    nsecs_t fadeTime = 0;
+
+    do {
+        // Set scissor in interesting area
+        glScissor(scx, scy, scw, sch);
+
+        // erase screen
+        glClear(GL_COLOR_BUFFER_BIT);
+
+        // compute wave
+        const float a = (t * 2 * M_PI) - M_PI / 2;
+        const float sn = sinf(a);
+        const float cs = cosf(a);
+        GLint x = GLint(amplitude * sn);
+        float derivative = cs;
+
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+        if (derivative > 0) {
+            // vanishing trail...
+            p.x = (-amplitude + c.x) - mBrightSpot.w / 2;
+            p.y = c.y - mLeftTrail.h / 2;
+            float fade = 2.0f * (0.5f - t);
+            //fade *= fade;
+            glColor4f(fade, fade, fade, fade);
+            glBindTexture(GL_TEXTURE_2D, mLeftTrail.name);
+            glDrawTexiOES(p.x, p.y, 0, mLeftTrail.w, mLeftTrail.h);
+
+            // trail...
+            p.x = (x + c.x) - (mRightTrail.w + mBrightSpot.w / 2) + 16;
+            p.y = c.y - mRightTrail.h / 2;
+            fade = t < 0.25f ? t * 4.0f : 1.0f;
+            fade *= fade;
+            glColor4f(fade, fade, fade, fade);
+            glBindTexture(GL_TEXTURE_2D, mRightTrail.name);
+            glDrawTexiOES(p.x, p.y, 0, mRightTrail.w, mRightTrail.h);
+        } else {
+            // vanishing trail..
+            p.x = (amplitude + c.x) - (mRightTrail.w + mBrightSpot.w / 2) + 16;
+            p.y = c.y - mRightTrail.h / 2;
+            float fade = 2.0f * (0.5f - (t - 0.5f));
+            //fade *= fade;
+            glColor4f(fade, fade, fade, fade);
+            glBindTexture(GL_TEXTURE_2D, mRightTrail.name);
+            glDrawTexiOES(p.x, p.y, 0, mRightTrail.w, mRightTrail.h);
+
+            // trail...
+            p.x = (x + c.x) - mBrightSpot.w / 2;
+            p.y = c.y - mLeftTrail.h / 2;
+            fade = t < 0.5f + 0.25f ? (t - 0.5f) * 4.0f : 1.0f;
+            fade *= fade;
+            glColor4f(fade, fade, fade, fade);
+            glBindTexture(GL_TEXTURE_2D, mLeftTrail.name);
+            glDrawTexiOES(p.x, p.y, 0, mLeftTrail.w, mLeftTrail.h);
+        }
+
+        const Point p(x + c.x - mBrightSpot.w / 2, c.y - mBrightSpot.h / 2);
+        glBindTexture(GL_TEXTURE_2D, mBrightSpot.name);
+        glColor4f(1, 0.5, 0.5, 1);
+        glDrawTexiOES(p.x, p.y, 0, mBrightSpot.w, mBrightSpot.h);
+
+        // update animation
+        nsecs_t time = systemTime() - startTime;
+        t = ((4.0f / (360.0f * us2ns(16667))) * time);
+        t = t - floorf(t);
+
+        eglSwapBuffers(mDisplay, mSurface);
+
+        if (exitPending()) {
+            if (fadeTime == 0) {
+                fadeTime = time;
+            }
+            time -= fadeTime;
+            alpha = 1.0f - ((float(time) * 6.0f) / float(s2ns(1)));
+
+            session()->openTransaction();
+            mFlingerSurface->setAlpha(alpha * alpha);
+            session()->closeTransaction();
+        }
+    } while (alpha > 0);
+
+    // cleanup
+    glFinish();
+    glDeleteTextures(1, &mLeftTrail.name);
+    glDeleteTextures(1, &mRightTrail.name);
+    glDeleteTextures(1, &mBrightSpot.name);
+    return false;
+}
+
+// ---------------------------------------------------------------------------
+
+}
+; // namespace android
diff --git a/libs/surfaceflinger/BootAnimation.h b/libs/surfaceflinger/BootAnimation.h
new file mode 100644
index 0000000..b20cea0
--- /dev/null
+++ b/libs/surfaceflinger/BootAnimation.h
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_BOOTANIMATION_H
+#define ANDROID_BOOTANIMATION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+#include <utils/AssetManager.h>
+
+#include <ui/ISurfaceComposer.h>
+#include <ui/SurfaceComposerClient.h>
+
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+
+#include "Barrier.h"
+
+class SkBitmap;
+
+namespace android {
+
+class AssetManager;
+class EGLNativeWindowSurface;
+
+// ---------------------------------------------------------------------------
+
+class BootAnimation : public Thread
+{
+public:
+                BootAnimation(const sp<ISurfaceComposer>& composer);
+    virtual     ~BootAnimation();
+
+    const sp<SurfaceComposerClient>& session() const;
+    virtual void        requestExit();
+
+private:
+    virtual bool        threadLoop();
+    virtual status_t    readyToRun();
+    virtual void        onFirstRef();
+
+    struct Texture {
+        GLint   w;
+        GLint   h;
+        GLuint  name;
+    };
+
+    status_t initTexture(Texture* texture, AssetManager& asset, const char* name);
+    bool android();
+    bool cylon();
+
+    sp<SurfaceComposerClient>       mSession;
+    AssetManager mAssets;
+    Texture mLeftTrail;
+    Texture mRightTrail;
+    Texture mBrightSpot;
+    Texture mAndroid[3];
+    int     mWidth;
+    int     mHeight;
+    EGLDisplay  mDisplay;
+    EGLDisplay  mContext;
+    EGLDisplay  mSurface;
+    sp<Surface> mFlingerSurface;
+    sp<EGLNativeWindowSurface> mNativeWindowSurface;
+    Barrier mBarrier;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_BOOTANIMATION_H
diff --git a/libs/surfaceflinger/CPUGauge.cpp b/libs/surfaceflinger/CPUGauge.cpp
new file mode 100644
index 0000000..74a9270
--- /dev/null
+++ b/libs/surfaceflinger/CPUGauge.cpp
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "CPUGauge"
+
+#include <stdint.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <math.h>
+
+#include <utils/threads.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+#include <ui/DisplayInfo.h>
+#include <ui/ISurfaceComposer.h>
+#include <ui/ISurfaceFlingerClient.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "CPUGauge.h"
+
+namespace android {
+
+CPUGauge::CPUGauge( const sp<ISurfaceComposer>& composer,
+                    nsecs_t interval,
+                    int clock,
+                    int refclock)
+    :   Thread(false), 
+        mInterval(interval), mClock(clock), mRefClock(refclock),
+        mReferenceTime(0),
+        mReferenceWorkingTime(0), mCpuUsage(0),
+        mRefIdleTime(0), mIdleTime(0)
+{
+    mFd = fopen("/proc/stat", "r");
+    setvbuf(mFd, NULL, _IONBF, 0);
+
+    mSession = SurfaceComposerClient::clientForConnection(
+        composer->createConnection()->asBinder());
+}
+
+CPUGauge::~CPUGauge()
+{
+    fclose(mFd);
+}
+
+const sp<SurfaceComposerClient>& CPUGauge::session() const 
+{
+    return mSession;
+}
+
+void CPUGauge::onFirstRef()
+{
+    run("CPU Gauge");
+}
+
+status_t CPUGauge::readyToRun()
+{
+    LOGI("Starting CPU gauge...");
+    return NO_ERROR;
+}
+
+bool CPUGauge::threadLoop()
+{
+    DisplayInfo dinfo;
+    session()->getDisplayInfo(0, &dinfo);
+    sp<Surface> s(session()->createSurface(getpid(), 0, dinfo.w, 4, PIXEL_FORMAT_OPAQUE));
+    session()->openTransaction();
+    s->setLayer(INT_MAX);
+    session()->closeTransaction();
+    
+    static const GGLfixed colors[4][4] = {
+            { 0x00000, 0x10000, 0x00000, 0x10000 },
+            { 0x10000, 0x10000, 0x00000, 0x10000 },
+            { 0x10000, 0x00000, 0x00000, 0x10000 },
+            { 0x00000, 0x00000, 0x00000, 0x10000 },
+        };
+
+    GGLContext* gl;
+    gglInit(&gl);
+    gl->activeTexture(gl, 0);
+    gl->disable(gl, GGL_TEXTURE_2D);
+    gl->disable(gl, GGL_BLEND);
+
+    const int w = dinfo.w;
+
+    while(!exitPending())
+    {
+        mLock.lock();
+            const float cpuUsage = this->cpuUsage();
+            const float totalCpuUsage = 1.0f - idle();
+        mLock.unlock();
+
+        Surface::SurfaceInfo info;
+        s->lock(&info);
+            GGLSurface fb;
+                fb.version = sizeof(GGLSurface);
+                fb.width   = info.w;
+                fb.height  = info.h;
+                fb.stride  = info.w;
+                fb.format  = info.format;
+                fb.data = (GGLubyte*)info.bits;
+
+            gl->colorBuffer(gl, &fb);
+            gl->color4xv(gl, colors[3]);
+            gl->recti(gl, 0, 0, w, 4);
+            gl->color4xv(gl, colors[2]); // red
+            gl->recti(gl, 0, 0, int(totalCpuUsage*w), 2);
+            gl->color4xv(gl, colors[0]); // green
+            gl->recti(gl, 0, 2, int(cpuUsage*w), 4);
+        
+        s->unlockAndPost(); 
+
+        usleep(ns2us(mInterval));
+    }
+
+    gglUninit(gl);
+    return false;
+}
+
+void CPUGauge::sample()
+{
+    if (mLock.tryLock() == NO_ERROR) {
+        const nsecs_t now = systemTime(mRefClock);
+        const nsecs_t referenceTime = now-mReferenceTime;
+        if (referenceTime >= mInterval) {
+            const float reftime = 1.0f / referenceTime;
+            const nsecs_t nowWorkingTime = systemTime(mClock);
+            
+            char buf[256];
+            fgets(buf, 256, mFd);
+            rewind(mFd);
+            char *str = buf+5;
+            char const * const usermode = strsep(&str, " ");  (void)usermode;
+            char const * const usernice = strsep(&str, " ");  (void)usernice;
+            char const * const systemmode = strsep(&str, " ");(void)systemmode;
+            char const * const idle = strsep(&str, " ");
+            const nsecs_t nowIdleTime = atoi(idle) * 10000000LL;
+            mIdleTime = float(nowIdleTime - mRefIdleTime) * reftime;
+            mRefIdleTime = nowIdleTime;
+            
+            const nsecs_t workingTime = nowWorkingTime - mReferenceWorkingTime;
+            const float newCpuUsage = float(workingTime) * reftime;
+            if (mCpuUsage != newCpuUsage) {        
+                mCpuUsage = newCpuUsage;
+                mReferenceWorkingTime = nowWorkingTime;
+                mReferenceTime = now;
+            }
+        }
+        mLock.unlock();
+    }
+}
+
+
+}; // namespace android
diff --git a/libs/surfaceflinger/CPUGauge.h b/libs/surfaceflinger/CPUGauge.h
new file mode 100644
index 0000000..5bb53c0
--- /dev/null
+++ b/libs/surfaceflinger/CPUGauge.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_CPUGAUGE_H
+#define ANDROID_CPUGAUGE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Timers.h>
+
+#include <ui/SurfaceComposerClient.h>
+
+namespace android {
+
+class CPUGauge : public Thread
+{
+public:
+    CPUGauge(   const sp<ISurfaceComposer>& composer,
+                nsecs_t interval=s2ns(1),
+                int clock=SYSTEM_TIME_THREAD,
+                int refclock=SYSTEM_TIME_MONOTONIC);
+                
+    ~CPUGauge();
+
+    const sp<SurfaceComposerClient>& session() const;
+
+    void sample();
+ 
+    inline float cpuUsage() const { return mCpuUsage; }
+    inline float idle() const { return mIdleTime; }
+
+private:
+    virtual void        onFirstRef();
+    virtual status_t    readyToRun();
+    virtual bool        threadLoop();
+
+    Mutex mLock;
+
+    sp<SurfaceComposerClient> mSession;
+
+    const nsecs_t mInterval;
+    const int mClock;
+    const int mRefClock;
+
+    nsecs_t mReferenceTime;
+    nsecs_t mReferenceWorkingTime;
+    float mCpuUsage;
+    nsecs_t mRefIdleTime;
+    float mIdleTime;
+    FILE*   mFd;
+};
+
+
+}; // namespace android
+
+#endif // ANDROID_CPUGAUGE_H
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
new file mode 100644
index 0000000..f14d7e9
--- /dev/null
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -0,0 +1,353 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include <cutils/properties.h>
+
+#include <utils/Log.h>
+
+#include <ui/EGLDisplaySurface.h>
+
+#include <GLES/gl.h>
+#include <EGL/eglext.h>
+
+
+#include "DisplayHardware/DisplayHardware.h"
+
+#include <hardware/copybit.h>
+#include <hardware/overlay.h>
+
+using namespace android;
+
+static __attribute__((noinline))
+const char *egl_strerror(EGLint err)
+{
+    switch (err){
+        case EGL_SUCCESS:           return "EGL_SUCCESS";
+        case EGL_NOT_INITIALIZED:   return "EGL_NOT_INITIALIZED";
+        case EGL_BAD_ACCESS:        return "EGL_BAD_ACCESS";
+        case EGL_BAD_ALLOC:         return "EGL_BAD_ALLOC";
+        case EGL_BAD_ATTRIBUTE:     return "EGL_BAD_ATTRIBUTE";
+        case EGL_BAD_CONFIG:        return "EGL_BAD_CONFIG";
+        case EGL_BAD_CONTEXT:       return "EGL_BAD_CONTEXT";
+        case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
+        case EGL_BAD_DISPLAY:       return "EGL_BAD_DISPLAY";
+        case EGL_BAD_MATCH:         return "EGL_BAD_MATCH";
+        case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
+        case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
+        case EGL_BAD_PARAMETER:     return "EGL_BAD_PARAMETER";
+        case EGL_BAD_SURFACE:       return "EGL_BAD_SURFACE";
+        case EGL_CONTEXT_LOST:      return "EGL_CONTEXT_LOST";
+        default: return "UNKNOWN";
+    }
+}
+
+static __attribute__((noinline))
+void checkGLErrors()
+{
+    GLenum error = glGetError();
+    if (error != GL_NO_ERROR)
+        LOGE("GL error 0x%04x", int(error));
+}
+
+static __attribute__((noinline))
+void checkEGLErrors(const char* token)
+{
+    EGLint error = eglGetError();
+    // GLESonGL seems to be returning 0 when there is no errors?
+    if (error && error != EGL_SUCCESS)
+        LOGE("%s error 0x%04x (%s)",
+                token, int(error), egl_strerror(error));
+}
+
+
+/*
+ * Initialize the display to the specified values.
+ *
+ */
+
+DisplayHardware::DisplayHardware(
+        const sp<SurfaceFlinger>& flinger,
+        uint32_t dpy)
+    : DisplayHardwareBase(flinger, dpy)
+{
+    init(dpy);
+}
+
+DisplayHardware::~DisplayHardware()
+{
+    fini();
+}
+
+float DisplayHardware::getDpiX() const          { return mDpiX; }
+float DisplayHardware::getDpiY() const          { return mDpiY; }
+float DisplayHardware::getDensity() const       { return mDensity; }
+float DisplayHardware::getRefreshRate() const   { return mRefreshRate; }
+int DisplayHardware::getWidth() const           { return mWidth; }
+int DisplayHardware::getHeight() const          { return mHeight; }
+PixelFormat DisplayHardware::getFormat() const  { return mFormat; }
+
+void DisplayHardware::init(uint32_t dpy)
+{
+    // initialize EGL
+    const EGLint attribs[] = {
+            EGL_RED_SIZE,       5,
+            EGL_GREEN_SIZE,     6,
+            EGL_BLUE_SIZE,      5,
+            EGL_DEPTH_SIZE,     0,
+            EGL_NONE
+    };
+    EGLint w, h, dummy;
+    EGLint numConfigs, n;
+    EGLConfig config;
+    EGLSurface surface;
+    EGLContext context;
+    mFlags = 0;
+
+    // TODO: all the extensions below should be queried through
+    // eglGetProcAddress().
+
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglInitialize(display, NULL, NULL);
+    eglGetConfigs(display, NULL, 0, &numConfigs);
+    eglChooseConfig(display, attribs, &config, 1, &n);
+
+    /*
+     * Gather EGL extensions
+     */
+
+    const char* const egl_extensions = eglQueryString(
+            display, EGL_EXTENSIONS);
+    
+    LOGI("EGL informations:");
+    LOGI("# of configs : %d", numConfigs);
+    LOGI("vendor    : %s", eglQueryString(display, EGL_VENDOR));
+    LOGI("version   : %s", eglQueryString(display, EGL_VERSION));
+    LOGI("extensions: %s", egl_extensions);
+    LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
+
+    // TODO: get this from the devfb driver (probably should be HAL module)
+    mFlags |= SWAP_RECTANGLE_EXTENSION;
+    
+    // TODO: get the real "update_on_demand" behavior (probably should be HAL module)
+    mFlags |= UPDATE_ON_DEMAND;
+
+    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
+        if (dummy == EGL_SLOW_CONFIG)
+            mFlags |= SLOW_CONFIG;
+    }
+
+    /*
+     * Create our main surface
+     */
+
+    mDisplaySurface = new EGLDisplaySurface();
+
+    surface = eglCreateWindowSurface(display, config, mDisplaySurface.get(), NULL);
+    //checkEGLErrors("eglCreateDisplaySurfaceANDROID");
+
+    if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
+        if (dummy == EGL_BUFFER_PRESERVED) {
+            mFlags |= BUFFER_PRESERVED;
+        }
+    }
+    
+    GLint value = EGL_UNKNOWN;
+    eglQuerySurface(display, surface, EGL_HORIZONTAL_RESOLUTION, &value);
+    if (value == EGL_UNKNOWN) {
+        mDpiX = 160.0f;
+    } else {
+        mDpiX = 25.4f * float(value)/EGL_DISPLAY_SCALING;
+    }
+    value = EGL_UNKNOWN;
+    eglQuerySurface(display, surface, EGL_VERTICAL_RESOLUTION, &value);
+    if (value == EGL_UNKNOWN) {
+        mDpiY = 160.0f;
+    } else {
+        mDpiY = 25.4f * float(value)/EGL_DISPLAY_SCALING;
+    }
+    mRefreshRate = 60.f;    // TODO: get the real refresh rate 
+    
+    
+    char property[PROPERTY_VALUE_MAX];
+    if (property_get("ro.sf.lcd_density", property, NULL) <= 0) {
+        LOGW("ro.sf.lcd_density not defined, using 160 dpi by default.");
+        strcpy(property, "160");
+    }
+    mDensity = atoi(property) * (1.0f/160.0f);
+
+
+    /*
+     * Create our OpenGL ES context
+     */
+    
+    context = eglCreateContext(display, config, NULL, NULL);
+    //checkEGLErrors("eglCreateContext");
+    
+    eglQuerySurface(display, surface, EGL_WIDTH, &mWidth);
+    eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight);
+    
+    
+    /*
+     * Gather OpenGL ES extensions
+     */
+
+    eglMakeCurrent(display, surface, surface, context);
+    const char* const  gl_extensions = (const char*)glGetString(GL_EXTENSIONS);
+    LOGI("OpenGL informations:");
+    LOGI("vendor    : %s", glGetString(GL_VENDOR));
+    LOGI("renderer  : %s", glGetString(GL_RENDERER));
+    LOGI("version   : %s", glGetString(GL_VERSION));
+    LOGI("extensions: %s", gl_extensions);
+
+    if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two")) {
+        mFlags |= NPOT_EXTENSION;
+    }
+    if (strstr(gl_extensions, "GL_OES_draw_texture")) {
+        mFlags |= DRAW_TEXTURE_EXTENSION;
+    }
+    if (strstr(gl_extensions, "GL_ANDROID_direct_texture")) {
+        mFlags |= DIRECT_TEXTURE;
+    }
+
+    // Unbind the context from this thread
+    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+    mDisplay = display;
+    mConfig  = config;
+    mSurface = surface;
+    mContext = context;
+    mFormat  = GGL_PIXEL_FORMAT_RGB_565;
+    
+    hw_module_t const* module;
+
+    mBlitEngine = NULL;
+    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
+        copybit_open(module, &mBlitEngine);
+    }
+
+    mOverlayEngine = NULL;
+    if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
+        overlay_control_open(module, &mOverlayEngine);
+    }
+}
+
+/*
+ * Clean up.  Throw out our local state.
+ *
+ * (It's entirely possible we'll never get here, since this is meant
+ * for real hardware, which doesn't restart.)
+ */
+
+void DisplayHardware::fini()
+{
+    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    eglTerminate(mDisplay);
+    copybit_close(mBlitEngine);
+    overlay_control_close(mOverlayEngine);
+}
+
+void DisplayHardware::releaseScreen() const
+{
+    DisplayHardwareBase::releaseScreen();
+}
+
+void DisplayHardware::acquireScreen() const
+{
+    DisplayHardwareBase::acquireScreen();
+}
+
+void DisplayHardware::getDisplaySurface(copybit_image_t* img) const
+{
+    img->w      = mDisplaySurface->stride;
+    img->h      = mDisplaySurface->height;
+    img->format = mDisplaySurface->format;
+    img->offset = mDisplaySurface->offset;
+    img->base   = (void*)mDisplaySurface->base;
+    img->fd     = mDisplaySurface->fd;
+}
+
+void DisplayHardware::getDisplaySurface(GGLSurface* fb) const
+{
+    fb->version= sizeof(GGLSurface);
+    fb->width  = mDisplaySurface->width;
+    fb->height = mDisplaySurface->height;
+    fb->stride = mDisplaySurface->stride;
+    fb->format = mDisplaySurface->format;
+    fb->data   = (GGLubyte*)mDisplaySurface->base + mDisplaySurface->offset;
+}
+
+uint32_t DisplayHardware::getPageFlipCount() const {
+    return mDisplaySurface->getPageFlipCount();
+}
+
+/*
+ * "Flip" the front and back buffers.
+ */
+
+void DisplayHardware::flip(const Region& dirty) const
+{
+    checkGLErrors();
+
+    EGLDisplay dpy = mDisplay;
+    EGLSurface surface = mSurface;
+
+    Region newDirty(dirty);
+    newDirty.andSelf(Rect(mWidth, mHeight));
+
+    if (mFlags & BUFFER_PRESERVED) {
+        const Region copyback(mDirty.subtract(newDirty));
+        mDirty = newDirty;
+        mDisplaySurface->copyFrontToBack(copyback);
+    } 
+
+    if (mFlags & SWAP_RECTANGLE_EXTENSION) {
+        const Rect& b(newDirty.bounds());
+        mDisplaySurface->setSwapRectangle(
+                b.left, b.top, b.width(), b.height());
+    }
+
+    eglSwapBuffers(dpy, surface);
+    checkEGLErrors("eglSwapBuffers");
+
+    // for debugging
+    //glClearColor(1,0,0,0);
+    //glClear(GL_COLOR_BUFFER_BIT);
+}
+
+uint32_t DisplayHardware::getFlags() const
+{
+    return mFlags;
+}
+
+void DisplayHardware::makeCurrent() const
+{
+    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
+}
+
+void DisplayHardware::copyFrontToImage(const copybit_image_t& front) const {
+    mDisplaySurface->copyFrontToImage(front);
+}
+
+void DisplayHardware::copyBackToImage(const copybit_image_t& front) const {
+    mDisplaySurface->copyBackToImage(front);
+}
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
new file mode 100644
index 0000000..550a4d1
--- /dev/null
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_DISPLAY_HARDWARE_H
+#define ANDROID_DISPLAY_HARDWARE_H
+
+#include <stdlib.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/Region.h>
+
+#include <EGL/egl.h>
+
+#include "DisplayHardware/DisplayHardwareBase.h"
+
+struct overlay_control_device_t;
+struct copybit_device_t;
+struct copybit_image_t;
+struct copybit_t;
+
+namespace android {
+
+class EGLDisplaySurface;
+
+class DisplayHardware : public DisplayHardwareBase
+{
+public:
+    enum {
+        DIRECT_TEXTURE          = 0x00000002,
+        SWAP_RECTANGLE_EXTENSION= 0x00000004,
+        COPY_BITS_EXTENSION     = 0x00000008,
+        NPOT_EXTENSION          = 0x00000100,
+        DRAW_TEXTURE_EXTENSION  = 0x00000200,
+        BUFFER_PRESERVED        = 0x00010000,
+        UPDATE_ON_DEMAND        = 0x00020000,   // video driver feature
+        SLOW_CONFIG             = 0x00040000,   // software
+    };
+
+    DisplayHardware(
+            const sp<SurfaceFlinger>& flinger,
+            uint32_t displayIndex);
+
+    ~DisplayHardware();
+
+    void releaseScreen() const;
+    void acquireScreen() const;
+
+    // Flip the front and back buffers if the back buffer is "dirty".  Might
+    // be instantaneous, might involve copying the frame buffer around.
+    void flip(const Region& dirty) const;
+
+    float       getDpiX() const;
+    float       getDpiY() const;
+    float       getRefreshRate() const;
+    float       getDensity() const;
+    int         getWidth() const;
+    int         getHeight() const;
+    PixelFormat getFormat() const;
+    uint32_t    getFlags() const;
+    void        makeCurrent() const;
+
+    uint32_t getPageFlipCount() const;
+    void getDisplaySurface(copybit_image_t* img) const;
+    void getDisplaySurface(GGLSurface* fb) const;
+    EGLDisplay getEGLDisplay() const { return mDisplay; }
+    copybit_device_t* getBlitEngine() const { return mBlitEngine; }
+    overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
+    
+    void copyFrontToImage(const copybit_image_t& front) const;
+    void copyBackToImage(const copybit_image_t& front) const;
+       
+    Rect bounds() const {
+        return Rect(mWidth, mHeight);
+    }
+
+private:
+    void init(uint32_t displayIndex) __attribute__((noinline));
+    void fini() __attribute__((noinline));
+
+    EGLDisplay      mDisplay;
+    EGLSurface      mSurface;
+    EGLContext      mContext;
+    EGLConfig       mConfig;
+    float           mDpiX;
+    float           mDpiY;
+    float           mRefreshRate;
+    float           mDensity;
+    int             mWidth;
+    int             mHeight;
+    PixelFormat     mFormat;
+    uint32_t        mFlags;
+    mutable Region  mDirty;
+    sp<EGLDisplaySurface> mDisplaySurface;
+    copybit_device_t*     mBlitEngine;
+    overlay_control_device_t* mOverlayEngine;
+};
+
+}; // namespace android
+
+#endif // ANDROID_DISPLAY_HARDWARE_H
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
new file mode 100644
index 0000000..f75e5c2
--- /dev/null
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
@@ -0,0 +1,403 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+
+#include <linux/unistd.h>
+
+#include <utils/Log.h>
+
+#include "DisplayHardware/DisplayHardwareBase.h"
+#include "SurfaceFlinger.h"
+
+// ----------------------------------------------------------------------------
+// the sim build doesn't have gettid
+
+#ifndef HAVE_GETTID
+# define gettid getpid
+#endif
+
+// ----------------------------------------------------------------------------
+namespace android {
+
+static char const * kSleepFileName = "/sys/power/wait_for_fb_sleep";
+static char const * kWakeFileName = "/sys/power/wait_for_fb_wake";
+static char const * const kOldSleepFileName = "/sys/android_power/wait_for_fb_sleep";
+static char const * const kOldWakeFileName = "/sys/android_power/wait_for_fb_wake";
+
+// This dir exists if the framebuffer console is present, either built into
+// the kernel or loaded as a module.
+static char const * const kFbconSysDir = "/sys/class/graphics/fbcon";
+
+// ----------------------------------------------------------------------------
+
+DisplayHardwareBase::DisplayEventThreadBase::DisplayEventThreadBase(
+        const sp<SurfaceFlinger>& flinger)
+    : Thread(false), mFlinger(flinger) {
+}
+
+DisplayHardwareBase::DisplayEventThreadBase::~DisplayEventThreadBase() {
+}
+
+// ----------------------------------------------------------------------------
+
+DisplayHardwareBase::DisplayEventThread::DisplayEventThread(
+        const sp<SurfaceFlinger>& flinger)
+    : DisplayEventThreadBase(flinger)
+{
+}
+
+DisplayHardwareBase::DisplayEventThread::~DisplayEventThread()
+{
+}
+
+bool DisplayHardwareBase::DisplayEventThread::threadLoop()
+{
+    int err = 0;
+    char buf;
+    int fd;
+
+    fd = open(kSleepFileName, O_RDONLY, 0);
+    do {
+      err = read(fd, &buf, 1);
+    } while (err < 0 && errno == EINTR);
+    close(fd);
+    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno));
+    if (err >= 0) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        LOGD("About to give-up screen, flinger = %p", flinger.get());
+        if (flinger != 0) {
+            mBarrier.close();
+            flinger->screenReleased(0);
+            mBarrier.wait();
+        }
+    }
+    fd = open(kWakeFileName, O_RDONLY, 0);
+    do {
+      err = read(fd, &buf, 1);
+    } while (err < 0 && errno == EINTR);
+    close(fd);
+    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno));
+    if (err >= 0) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        LOGD("Screen about to return, flinger = %p", flinger.get());
+        if (flinger != 0)
+            flinger->screenAcquired(0);
+    }
+    return true;
+}
+
+status_t DisplayHardwareBase::DisplayEventThread::releaseScreen() const
+{
+    mBarrier.open();
+    return NO_ERROR;
+}
+
+status_t DisplayHardwareBase::DisplayEventThread::readyToRun()
+{
+    if (access(kSleepFileName, R_OK) || access(kWakeFileName, R_OK)) {
+        if (access(kOldSleepFileName, R_OK) || access(kOldWakeFileName, R_OK)) {
+            LOGE("Couldn't open %s or %s", kSleepFileName, kWakeFileName);
+            return NO_INIT;
+        }
+        kSleepFileName = kOldSleepFileName;
+        kWakeFileName = kOldWakeFileName;
+    }
+    return NO_ERROR;
+}
+
+status_t DisplayHardwareBase::DisplayEventThread::initCheck() const
+{
+    return (((access(kSleepFileName, R_OK) == 0 &&
+            access(kWakeFileName, R_OK) == 0) ||
+            (access(kOldSleepFileName, R_OK) == 0 &&
+            access(kOldWakeFileName, R_OK) == 0)) &&
+            access(kFbconSysDir, F_OK) != 0) ? NO_ERROR : NO_INIT;
+}
+
+// ----------------------------------------------------------------------------
+
+pid_t DisplayHardwareBase::ConsoleManagerThread::sSignalCatcherPid = 0;
+
+DisplayHardwareBase::ConsoleManagerThread::ConsoleManagerThread(
+        const sp<SurfaceFlinger>& flinger)
+    : DisplayEventThreadBase(flinger), consoleFd(-1)
+{   
+    sSignalCatcherPid = 0;
+
+    // create a new console
+    char const * const ttydev = "/dev/tty0";
+    int fd = open(ttydev, O_RDWR | O_SYNC);
+    if (fd<0) {
+        LOGE("Can't open %s", ttydev);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    // to make sure that we are in text mode
+    int res = ioctl(fd, KDSETMODE, (void*) KD_TEXT);
+    if (res<0) {
+        LOGE("ioctl(%d, KDSETMODE, ...) failed, res %d (%s)",
+                fd, res, strerror(errno));
+    }
+    
+    // get the current console
+    struct vt_stat vs;
+    res = ioctl(fd, VT_GETSTATE, &vs);
+    if (res<0) {
+        LOGE("ioctl(%d, VT_GETSTATE, ...) failed, res %d (%s)",
+                fd, res, strerror(errno));
+        this->consoleFd = -errno;
+        return;
+    }
+
+    // switch to console 7 (which is what X normaly uses)
+    int vtnum = 7;
+    do {
+        res = ioctl(fd, VT_ACTIVATE, (void*)vtnum);
+    } while(res < 0 && errno == EINTR);
+    if (res<0) {
+        LOGE("ioctl(%d, VT_ACTIVATE, ...) failed, %d (%s) for %d",
+                fd, errno, strerror(errno), vtnum);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    do {
+        res = ioctl(fd, VT_WAITACTIVE, (void*)vtnum);
+    } while(res < 0 && errno == EINTR);
+    if (res<0) {
+        LOGE("ioctl(%d, VT_WAITACTIVE, ...) failed, %d %d %s for %d",
+                fd, res, errno, strerror(errno), vtnum);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    // open the new console
+    close(fd);
+    fd = open(ttydev, O_RDWR | O_SYNC);
+    if (fd<0) {
+        LOGE("Can't open new console %s", ttydev);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    /* disable console line buffer, echo, ... */
+    struct termios ttyarg;
+    ioctl(fd, TCGETS , &ttyarg);
+    ttyarg.c_iflag = 0;
+    ttyarg.c_lflag = 0;
+    ioctl(fd, TCSETS , &ttyarg);
+
+    // set up signals so we're notified when the console changes
+    // we can't use SIGUSR1 because it's used by the java-vm
+    vm.mode = VT_PROCESS;
+    vm.waitv = 0;
+    vm.relsig = SIGUSR2;
+    vm.acqsig = SIGUNUSED;
+    vm.frsig = 0;
+
+    struct sigaction act;
+    sigemptyset(&act.sa_mask);
+    act.sa_handler = sigHandler;
+    act.sa_flags = 0;
+    sigaction(vm.relsig, &act, NULL);
+
+    sigemptyset(&act.sa_mask);
+    act.sa_handler = sigHandler;
+    act.sa_flags = 0;
+    sigaction(vm.acqsig, &act, NULL);
+
+    sigset_t mask;
+    sigemptyset(&mask);
+    sigaddset(&mask, vm.relsig);
+    sigaddset(&mask, vm.acqsig);
+    sigprocmask(SIG_BLOCK, &mask, NULL);
+
+    // switch to graphic mode
+    res = ioctl(fd, KDSETMODE, (void*)KD_GRAPHICS);
+    LOGW_IF(res<0,
+            "ioctl(%d, KDSETMODE, KD_GRAPHICS) failed, res %d", fd, res);
+
+    this->prev_vt_num = vs.v_active;
+    this->vt_num = vtnum;
+    this->consoleFd = fd;
+}
+
+DisplayHardwareBase::ConsoleManagerThread::~ConsoleManagerThread()
+{   
+    if (this->consoleFd >= 0) {
+        int fd = this->consoleFd;
+        int prev_vt_num = this->prev_vt_num;
+        int res;
+        ioctl(fd, KDSETMODE, (void*)KD_TEXT);
+        do {
+            res = ioctl(fd, VT_ACTIVATE, (void*)prev_vt_num);
+        } while(res < 0 && errno == EINTR);
+        do {
+            res = ioctl(fd, VT_WAITACTIVE, (void*)prev_vt_num);
+        } while(res < 0 && errno == EINTR);
+        close(fd);    
+        char const * const ttydev = "/dev/tty0";
+        fd = open(ttydev, O_RDWR | O_SYNC);
+        ioctl(fd, VT_DISALLOCATE, 0);
+        close(fd);
+    }
+}
+
+status_t DisplayHardwareBase::ConsoleManagerThread::readyToRun()
+{
+    if (this->consoleFd >= 0) {
+        sSignalCatcherPid = gettid();
+        
+        sigset_t mask;
+        sigemptyset(&mask);
+        sigaddset(&mask, vm.relsig);
+        sigaddset(&mask, vm.acqsig);
+        sigprocmask(SIG_BLOCK, &mask, NULL);
+
+        int res = ioctl(this->consoleFd, VT_SETMODE, &vm);
+        if (res<0) {
+            LOGE("ioctl(%d, VT_SETMODE, ...) failed, %d (%s)",
+                    this->consoleFd, errno, strerror(errno));
+        }
+        return NO_ERROR;
+    }
+    return this->consoleFd;
+}
+
+void DisplayHardwareBase::ConsoleManagerThread::requestExit()
+{
+    Thread::requestExit();
+    if (sSignalCatcherPid != 0) {
+        // wake the thread up
+        kill(sSignalCatcherPid, SIGINT);
+        // wait for it...
+    }
+}
+
+void DisplayHardwareBase::ConsoleManagerThread::sigHandler(int sig)
+{
+    // resend the signal to our signal catcher thread
+    LOGW("received signal %d in thread %d, resending to %d",
+            sig, gettid(), sSignalCatcherPid);
+
+    // we absolutely need the delays below because without them
+    // our main thread never gets a chance to handle the signal.
+    usleep(10000);
+    kill(sSignalCatcherPid, sig);
+    usleep(10000);
+}
+
+status_t DisplayHardwareBase::ConsoleManagerThread::releaseScreen() const
+{
+    int fd = this->consoleFd;
+    int err = ioctl(fd, VT_RELDISP, (void*)1);
+    LOGE_IF(err<0, "ioctl(%d, VT_RELDISP, 1) failed %d (%s)",
+        fd, errno, strerror(errno));
+    return (err<0) ? (-errno) : status_t(NO_ERROR);
+}
+
+bool DisplayHardwareBase::ConsoleManagerThread::threadLoop()
+{
+    sigset_t mask;
+    sigemptyset(&mask);
+    sigaddset(&mask, vm.relsig);
+    sigaddset(&mask, vm.acqsig);
+
+    int sig = 0;
+    sigwait(&mask, &sig);
+
+    if (sig == vm.relsig) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        //LOGD("About to give-up screen, flinger = %p", flinger.get());
+        if (flinger != 0)
+            flinger->screenReleased(0);
+    } else if (sig == vm.acqsig) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        //LOGD("Screen about to return, flinger = %p", flinger.get());
+        if (flinger != 0) 
+            flinger->screenAcquired(0);
+    }
+    
+    return true;
+}
+
+status_t DisplayHardwareBase::ConsoleManagerThread::initCheck() const
+{
+    return consoleFd >= 0 ? NO_ERROR : NO_INIT;
+}
+
+// ----------------------------------------------------------------------------
+
+DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger,
+        uint32_t displayIndex) 
+    : mCanDraw(true)
+{
+    mDisplayEventThread = new DisplayEventThread(flinger);
+    if (mDisplayEventThread->initCheck() != NO_ERROR) {
+        // fall-back on the console
+        mDisplayEventThread = new ConsoleManagerThread(flinger);
+    }
+}
+
+DisplayHardwareBase::~DisplayHardwareBase()
+{
+    // request exit
+    mDisplayEventThread->requestExitAndWait();
+}
+
+
+bool DisplayHardwareBase::canDraw() const
+{
+    return mCanDraw;
+}
+
+void DisplayHardwareBase::releaseScreen() const
+{
+    status_t err = mDisplayEventThread->releaseScreen();
+    if (err >= 0) {
+        //LOGD("screen given-up");
+        mCanDraw = false;
+    }
+}
+
+void DisplayHardwareBase::acquireScreen() const
+{
+    status_t err = mDisplayEventThread->acquireScreen();
+    if (err >= 0) {
+        //LOGD("screen returned");
+        mCanDraw = true;
+    }
+}
+
+}; // namespace android
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
new file mode 100644
index 0000000..8369bb8
--- /dev/null
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_DISPLAY_HARDWARE_BASE_H
+#define ANDROID_DISPLAY_HARDWARE_BASE_H
+
+#include <stdint.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
+#include "Barrier.h"
+
+namespace android {
+
+class SurfaceFlinger; 
+
+class DisplayHardwareBase
+{
+public:
+                DisplayHardwareBase(
+                        const sp<SurfaceFlinger>& flinger,
+                        uint32_t displayIndex);
+
+                ~DisplayHardwareBase();
+
+    // console managment
+    void releaseScreen() const;
+    void acquireScreen() const;
+    bool canDraw() const;
+
+private:
+    class DisplayEventThreadBase : public Thread {
+    protected:
+        wp<SurfaceFlinger> mFlinger;
+    public:
+        DisplayEventThreadBase(const sp<SurfaceFlinger>& flinger);
+        virtual ~DisplayEventThreadBase();
+        virtual void onFirstRef() {
+            run("DisplayEventThread", PRIORITY_URGENT_DISPLAY);
+        }
+        virtual status_t acquireScreen() const { return NO_ERROR; };
+        virtual status_t releaseScreen() const { return NO_ERROR; };
+        virtual status_t initCheck() const = 0;
+    };
+
+    class DisplayEventThread : public DisplayEventThreadBase 
+    {
+        mutable Barrier mBarrier;
+    public:
+                DisplayEventThread(const sp<SurfaceFlinger>& flinger);
+        virtual ~DisplayEventThread();
+        virtual bool threadLoop();
+        virtual status_t readyToRun();
+        virtual status_t releaseScreen() const;
+        virtual status_t initCheck() const;
+    };
+
+    class ConsoleManagerThread : public DisplayEventThreadBase 
+    {
+        int consoleFd;
+        int vt_num;
+        int prev_vt_num;
+        vt_mode vm;
+        static void sigHandler(int sig);
+        static pid_t sSignalCatcherPid;
+    public:
+                ConsoleManagerThread(const sp<SurfaceFlinger>& flinger);
+        virtual ~ConsoleManagerThread();
+        virtual bool threadLoop();
+        virtual status_t readyToRun();
+        virtual void requestExit();
+        virtual status_t releaseScreen() const;
+        virtual status_t initCheck() const;
+    };
+
+    sp<DisplayEventThreadBase>  mDisplayEventThread;
+    mutable int                 mCanDraw;
+};
+
+}; // namespace android
+
+#endif // ANDROID_DISPLAY_HARDWARE_BASE_H
diff --git a/libs/surfaceflinger/GPUHardware/GPUHardware.cpp b/libs/surfaceflinger/GPUHardware/GPUHardware.cpp
new file mode 100644
index 0000000..eb75f99
--- /dev/null
+++ b/libs/surfaceflinger/GPUHardware/GPUHardware.cpp
@@ -0,0 +1,581 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <utils/IBinder.h>
+#include <utils/MemoryDealer.h>
+#include <utils/MemoryBase.h>
+#include <utils/MemoryHeapPmem.h>
+#include <utils/MemoryHeapBase.h>
+#include <utils/IPCThreadState.h>
+#include <utils/StopWatch.h>
+
+#include <ui/ISurfaceComposer.h>
+
+#include "VRamHeap.h"
+#include "GPUHardware.h"
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+#include "GPUHardware/GPUHardware.h"
+
+
+/* 
+ * Manage the GPU. This implementation is very specific to the G1.
+ * There are no abstraction here. 
+ * 
+ * All this code will soon go-away and be replaced by a new architecture
+ * for managing graphics accelerators.
+ * 
+ * In the meantime, it is conceptually possible to instantiate a
+ * GPUHardwareInterface for another GPU (see GPUFactory at the bottom
+ * of this file); practically... doubtful.
+ * 
+ */
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class GPUClientHeap;
+class GPUAreaHeap;
+
+class GPUHardware : public GPUHardwareInterface, public IBinder::DeathRecipient
+{
+public:
+    static const int GPU_RESERVED_SIZE;
+    static const int GPUR_SIZE;
+
+            GPUHardware();
+    virtual ~GPUHardware();
+    
+    virtual void revoke(int pid);
+    virtual sp<MemoryDealer> request(int pid);
+    virtual status_t request(int pid, 
+            const sp<IGPUCallback>& callback,
+            ISurfaceComposer::gpu_info_t* gpu);
+
+    virtual status_t friendlyRevoke();
+    virtual void unconditionalRevoke();
+    
+    virtual pid_t getOwner() const { return mOwner; }
+
+    // used for debugging only...
+    virtual sp<SimpleBestFitAllocator> getAllocator() const;
+
+private:
+    
+    
+    enum {
+        NO_OWNER = -1,
+    };
+        
+    struct GPUArea {
+        sp<GPUAreaHeap>     heap;
+        sp<MemoryHeapPmem>  clientHeap;
+        sp<IMemory> map();
+    };
+    
+    struct Client {
+        pid_t       pid;
+        GPUArea     smi;
+        GPUArea     ebi;
+        GPUArea     reg;
+        void createClientHeaps();
+        void revokeAllHeaps();
+    };
+    
+    Client& getClientLocked(pid_t pid);
+    status_t requestLocked(int pid);
+    void releaseLocked();
+    void takeBackGPULocked();
+    void registerCallbackLocked(const sp<IGPUCallback>& callback,
+            Client& client);
+
+    virtual void binderDied(const wp<IBinder>& who);
+
+    mutable Mutex           mLock;
+    sp<GPUAreaHeap>         mSMIHeap;
+    sp<GPUAreaHeap>         mEBIHeap;
+    sp<GPUAreaHeap>         mREGHeap;
+
+    KeyedVector<pid_t, Client> mClients;
+    DefaultKeyedVector< wp<IBinder>, pid_t > mRegisteredClients;
+    
+    pid_t                   mOwner;
+
+    sp<MemoryDealer>        mCurrentAllocator;
+    sp<IGPUCallback>        mCallback;
+    
+    sp<SimpleBestFitAllocator>  mAllocator;
+
+    Condition               mCondition;
+};
+
+// size reserved for GPU surfaces
+// 1200 KB fits exactly:
+//  - two 320*480 16-bits double-buffered surfaces
+//  - one 320*480 32-bits double-buffered surface
+//  - one 320*240 16-bits double-buffered, 4x anti-aliased surface
+const int GPUHardware::GPU_RESERVED_SIZE  = 1200 * 1024;
+const int GPUHardware::GPUR_SIZE          = 1 * 1024 * 1024;
+
+// ---------------------------------------------------------------------------
+
+/* 
+ * GPUHandle is a special IMemory given to the client. It represents their
+ * handle to the GPU. Once they give it up, they loose GPU access, or if
+ * they explicitly revoke their access through the binder code 1000.
+ * In both cases, this triggers a callback to revoke()
+ * first, and then actually powers down the chip.
+ * 
+ * In the case of a misbehaving app, GPUHardware can ask for an immediate
+ * release of the GPU to the target process which should answer by calling
+ * code 1000 on GPUHandle. If it doesn't in a timely manner, the GPU will
+ * be revoked from under their feet.
+ * 
+ * We should never hold a strong reference on GPUHandle. In practice this
+ * shouldn't be a big issue though because clients should use code 1000 and
+ * not rely on the dtor being called.
+ * 
+ */
+
+class GPUClientHeap : public MemoryHeapPmem
+{
+public:
+    GPUClientHeap(const wp<GPUHardware>& gpu, 
+            const sp<MemoryHeapBase>& heap)
+        :  MemoryHeapPmem(heap), mGPU(gpu) { }
+protected:
+    wp<GPUHardware> mGPU;
+};
+
+class GPUAreaHeap : public MemoryHeapBase
+{
+public:
+    GPUAreaHeap(const wp<GPUHardware>& gpu,
+            const char* const vram, size_t size=0, size_t reserved=0)
+    : MemoryHeapBase(vram, size), mGPU(gpu) { 
+        if (base() != MAP_FAILED) {
+            if (reserved == 0)
+                reserved = virtualSize();
+            mAllocator = new SimpleBestFitAllocator(reserved);
+        }
+    }
+    virtual sp<MemoryHeapPmem> createClientHeap() {
+        sp<MemoryHeapBase> parentHeap(this);
+        return new GPUClientHeap(mGPU, parentHeap);
+    }
+    virtual const sp<SimpleBestFitAllocator>& getAllocator() const {
+        return mAllocator; 
+    }
+private:
+    sp<SimpleBestFitAllocator>  mAllocator;
+protected:
+    wp<GPUHardware> mGPU;
+};
+
+class GPURegisterHeap : public GPUAreaHeap
+{
+public:
+    GPURegisterHeap(const sp<GPUHardware>& gpu)
+        : GPUAreaHeap(gpu, "/dev/hw3d", GPUHardware::GPUR_SIZE) { }
+    virtual sp<MemoryHeapPmem> createClientHeap() {
+        sp<MemoryHeapBase> parentHeap(this);
+        return new MemoryHeapRegs(mGPU, parentHeap);
+    }
+private:
+    class MemoryHeapRegs : public GPUClientHeap  {
+    public:
+        MemoryHeapRegs(const wp<GPUHardware>& gpu, 
+             const sp<MemoryHeapBase>& heap)
+            : GPUClientHeap(gpu, heap) { }
+        sp<MemoryHeapPmem::MemoryPmem> createMemory(size_t offset, size_t size);
+        virtual void revoke();
+    private:
+        class GPUHandle : public MemoryHeapPmem::MemoryPmem {
+        public:
+            GPUHandle(const sp<GPUHardware>& gpu,
+                    const sp<MemoryHeapPmem>& heap)
+                : MemoryHeapPmem::MemoryPmem(heap), 
+                  mGPU(gpu), mOwner(gpu->getOwner()) { }
+            virtual ~GPUHandle();
+            virtual sp<IMemoryHeap> getMemory(
+                    ssize_t* offset, size_t* size) const;
+            virtual void revoke() { };
+            virtual status_t onTransact(
+                    uint32_t code, const Parcel& data, 
+                    Parcel* reply, uint32_t flags);
+        private:
+            void revokeNotification();
+            wp<GPUHardware> mGPU;
+            pid_t mOwner;
+        };
+    };
+};
+
+GPURegisterHeap::MemoryHeapRegs::GPUHandle::~GPUHandle() { 
+    //LOGD("GPUHandle %p released, revoking GPU", this);
+    revokeNotification(); 
+}
+void GPURegisterHeap::MemoryHeapRegs::GPUHandle::revokeNotification()  {
+    sp<GPUHardware> hw(mGPU.promote());
+    if (hw != 0) {
+        hw->revoke(mOwner);
+    }
+}
+sp<IMemoryHeap> GPURegisterHeap::MemoryHeapRegs::GPUHandle::getMemory(
+        ssize_t* offset, size_t* size) const
+{
+    sp<MemoryHeapPmem> heap = getHeap();
+    if (offset) *offset = 0;
+    if (size)   *size = heap !=0 ? heap->virtualSize() : 0;
+    return heap;
+}
+status_t GPURegisterHeap::MemoryHeapRegs::GPUHandle::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    status_t err = BnMemory::onTransact(code, data, reply, flags);
+    if (err == UNKNOWN_TRANSACTION && code == 1000) {
+        int callingPid = IPCThreadState::self()->getCallingPid();
+        //LOGD("pid %d voluntarily revoking gpu", callingPid);
+        if (callingPid == mOwner) {
+            revokeNotification();
+            // we've revoked the GPU, don't do it again later when we
+            // are destroyed.
+            mGPU.clear();
+        } else {
+            LOGW("%d revoking someone else's gpu? (owner=%d)",
+                    callingPid, mOwner);            
+        }
+        err = NO_ERROR;
+    }
+    return err;
+}
+
+// ---------------------------------------------------------------------------
+
+
+sp<MemoryHeapPmem::MemoryPmem> GPURegisterHeap::MemoryHeapRegs::createMemory(
+        size_t offset, size_t size)
+{
+    sp<GPUHandle> memory;
+    sp<GPUHardware> gpu = mGPU.promote();
+    if (heapID()>0 && gpu!=0) {
+#if HAVE_ANDROID_OS
+        /* this is where the GPU is powered on and the registers are mapped
+         * in the client */
+        //LOGD("ioctl(HW3D_GRANT_GPU)");
+        int err = ioctl(heapID(), HW3D_GRANT_GPU, base());
+        if (err) {
+            // it can happen if the master heap has been closed already
+            // in which case the GPU already is revoked (app crash for
+            // instance).
+            LOGW("HW3D_GRANT_GPU failed (%s), mFD=%d, base=%p",
+                    strerror(errno), heapID(), base());
+        }
+        memory = new GPUHandle(gpu, this);
+#endif
+    }
+    return memory;
+}
+
+void GPURegisterHeap::MemoryHeapRegs::revoke() 
+{
+    MemoryHeapPmem::revoke();
+#if HAVE_ANDROID_OS
+    if (heapID() > 0) {
+        //LOGD("ioctl(HW3D_REVOKE_GPU)");
+        int err = ioctl(heapID(), HW3D_REVOKE_GPU, base());
+        LOGE_IF(err, "HW3D_REVOKE_GPU failed (%s), mFD=%d, base=%p",
+                strerror(errno), heapID(), base());
+    }
+#endif
+}
+
+/*****************************************************************************/
+
+GPUHardware::GPUHardware()
+    : mOwner(NO_OWNER)
+{
+}
+
+GPUHardware::~GPUHardware()
+{
+}
+
+status_t GPUHardware::requestLocked(int pid)
+{
+    const int self_pid = getpid();
+    if (pid == self_pid) {
+        // can't use GPU from surfaceflinger's process
+        return PERMISSION_DENIED;
+    }
+
+    if (mOwner != pid) {
+        if (mREGHeap != 0) {
+            if (mOwner != NO_OWNER) {
+                // someone already has the gpu.
+                takeBackGPULocked();
+                releaseLocked();
+            }
+        } else {
+            // first time, initialize the stuff.
+            if (mSMIHeap == 0)
+                mSMIHeap = new GPUAreaHeap(this, "/dev/pmem_gpu0");
+            if (mEBIHeap == 0)
+                mEBIHeap = new GPUAreaHeap(this, 
+                        "/dev/pmem_gpu1", 0, GPU_RESERVED_SIZE);
+            mREGHeap = new GPURegisterHeap(this);
+            mAllocator = mEBIHeap->getAllocator();
+            if (mAllocator == NULL) {
+                // something went terribly wrong.
+                mSMIHeap.clear();
+                mEBIHeap.clear();
+                mREGHeap.clear();
+                return INVALID_OPERATION;
+            }
+        }
+        Client& client = getClientLocked(pid);
+        mCurrentAllocator = new MemoryDealer(client.ebi.clientHeap, mAllocator);
+        mOwner = pid;
+    }
+    return NO_ERROR;
+}
+
+sp<MemoryDealer> GPUHardware::request(int pid)
+{
+    sp<MemoryDealer> dealer;
+    Mutex::Autolock _l(mLock);
+    Client* client;
+    LOGD("pid %d requesting gpu surface (current owner = %d)", pid, mOwner);
+    if (requestLocked(pid) == NO_ERROR) {
+        dealer = mCurrentAllocator;
+        LOGD_IF(dealer!=0, "gpu surface granted to pid %d", mOwner);
+    }
+    return dealer;
+}
+
+status_t GPUHardware::request(int pid, const sp<IGPUCallback>& callback,
+        ISurfaceComposer::gpu_info_t* gpu)
+{
+    if (callback == 0)
+        return BAD_VALUE;
+
+    sp<IMemory> gpuHandle;
+    LOGD("pid %d requesting gpu core (owner = %d)", pid, mOwner);
+    Mutex::Autolock _l(mLock);
+    status_t err = requestLocked(pid);
+    if (err == NO_ERROR) {
+        // it's guaranteed to be there, be construction
+        Client& client = mClients.editValueFor(pid);
+        registerCallbackLocked(callback, client);
+        gpu->count = 2;
+        gpu->regions[0].region = client.smi.map();
+        gpu->regions[1].region = client.ebi.map();
+        gpu->regs              = client.reg.map();
+        gpu->regions[0].reserved = 0;
+        gpu->regions[1].reserved = GPU_RESERVED_SIZE;
+        if (gpu->regs != 0) {
+            //LOGD("gpu core granted to pid %d, handle base=%p",
+            //        mOwner, gpu->regs->pointer());
+        }
+        mCallback = callback;
+    } else {
+        LOGW("couldn't grant gpu core to pid %d", pid);
+    }
+    return err;
+}
+
+void GPUHardware::revoke(int pid)
+{
+    Mutex::Autolock _l(mLock);
+    if (mOwner > 0) {
+        if (pid != mOwner) {
+            LOGW("GPU owned by %d, revoke from %d", mOwner, pid);
+            return;
+        }
+        //LOGD("revoke pid=%d, owner=%d", pid, mOwner);
+        // mOwner could be <0 if the same process acquired the GPU
+        // several times without releasing it first.
+        mCondition.signal();
+        releaseLocked();
+    }
+}
+
+status_t GPUHardware::friendlyRevoke()
+{
+    Mutex::Autolock _l(mLock);
+    //LOGD("friendlyRevoke owner=%d", mOwner);
+    takeBackGPULocked();
+    releaseLocked();
+    return NO_ERROR;
+}
+
+void GPUHardware::takeBackGPULocked()
+{
+    sp<IGPUCallback> callback = mCallback;
+    mCallback.clear();
+    if (callback != 0) {
+        callback->gpuLost(); // one-way
+        mCondition.waitRelative(mLock, ms2ns(250));
+    }
+}
+
+void GPUHardware::releaseLocked()
+{
+    //LOGD("revoking gpu from pid %d", mOwner);
+    if (mOwner != NO_OWNER) {
+        // this may fail because the client might have died, and have
+        // been removed from the list.
+        ssize_t index = mClients.indexOfKey(mOwner);
+        if (index >= 0) {
+            Client& client(mClients.editValueAt(index));
+            client.revokeAllHeaps();
+        }
+        mOwner = NO_OWNER;
+        mCurrentAllocator.clear();
+        mCallback.clear();
+    }
+}
+
+GPUHardware::Client& GPUHardware::getClientLocked(pid_t pid)
+{
+    ssize_t index = mClients.indexOfKey(pid);
+    if (index < 0) {
+        Client client;
+        client.pid = pid;
+        client.smi.heap = mSMIHeap;
+        client.ebi.heap = mEBIHeap;
+        client.reg.heap = mREGHeap;
+        index = mClients.add(pid, client);
+    }
+    Client& client(mClients.editValueAt(index));
+    client.createClientHeaps();
+    return client;
+}
+
+// ----------------------------------------------------------------------------
+// for debugging / testing ...
+
+sp<SimpleBestFitAllocator> GPUHardware::getAllocator() const {
+    Mutex::Autolock _l(mLock);
+    return mAllocator;
+}
+
+void GPUHardware::unconditionalRevoke()
+{
+    Mutex::Autolock _l(mLock);
+    releaseLocked();
+}
+
+// ---------------------------------------------------------------------------
+
+sp<IMemory> GPUHardware::GPUArea::map() {
+    sp<IMemory> memory;
+    if (clientHeap != 0 && heap != 0) {
+        memory = clientHeap->mapMemory(0, heap->virtualSize());
+    }
+    return memory;
+}
+
+void GPUHardware::Client::createClientHeaps() 
+{
+    if (smi.clientHeap == 0)
+        smi.clientHeap = smi.heap->createClientHeap();
+    if (ebi.clientHeap == 0)
+        ebi.clientHeap = ebi.heap->createClientHeap();
+    if (reg.clientHeap == 0)
+        reg.clientHeap = reg.heap->createClientHeap();
+}
+
+void GPUHardware::Client::revokeAllHeaps() 
+{
+    if (smi.clientHeap != 0)
+        smi.clientHeap->revoke();
+    if (ebi.clientHeap != 0)
+        ebi.clientHeap->revoke();
+    if (reg.clientHeap != 0)
+        reg.clientHeap->revoke();
+}
+
+void GPUHardware::registerCallbackLocked(const sp<IGPUCallback>& callback,
+        Client& client)
+{
+    sp<IBinder> binder = callback->asBinder();
+    if (mRegisteredClients.add(binder, client.pid) >= 0) {
+        binder->linkToDeath(this);
+    }
+}
+
+void GPUHardware::binderDied(const wp<IBinder>& who)
+{
+    Mutex::Autolock _l(mLock);
+    pid_t pid = mRegisteredClients.valueFor(who);
+    if (pid != 0) {
+        ssize_t index = mClients.indexOfKey(pid);
+        if (index >= 0) {
+            //LOGD("*** removing client at %d", index);
+            Client& client(mClients.editValueAt(index));
+            client.revokeAllHeaps(); // not really needed in theory
+            mClients.removeItemsAt(index);
+            if (mClients.size() == 0) {
+                //LOGD("*** was last client closing everything");
+                mCallback.clear();
+                mAllocator.clear();
+                mCurrentAllocator.clear();
+                mSMIHeap.clear();
+                mREGHeap.clear();
+                
+                // NOTE: we cannot clear the EBI heap because surfaceflinger
+                // itself may be using it, since this is where surfaces
+                // are allocated. if we're in the middle of compositing 
+                // a surface (even if its process just died), we cannot
+                // rip the heap under our feet.
+                
+                mOwner = NO_OWNER;
+            }
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+sp<GPUHardwareInterface> GPUFactory::getGPU()
+{
+    return new GPUHardware();
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/libs/surfaceflinger/GPUHardware/GPUHardware.h b/libs/surfaceflinger/GPUHardware/GPUHardware.h
new file mode 100644
index 0000000..3354528
--- /dev/null
+++ b/libs/surfaceflinger/GPUHardware/GPUHardware.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_GPU_HARDWARE_H
+#define ANDROID_GPU_HARDWARE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <utils/KeyedVector.h>
+
+#include <ui/ISurfaceComposer.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class IGPUCallback;
+
+class GPUHardwareInterface : public virtual RefBase
+{
+public:
+    virtual void                revoke(int pid) = 0;
+    virtual sp<MemoryDealer>    request(int pid) = 0;
+    virtual status_t            request(int pid, const sp<IGPUCallback>& callback,
+            ISurfaceComposer::gpu_info_t* gpu) = 0;
+
+    virtual status_t            friendlyRevoke() = 0;
+    
+    // used for debugging only...
+    virtual sp<SimpleBestFitAllocator> getAllocator() const  = 0;
+    virtual pid_t getOwner() const = 0;
+    virtual void unconditionalRevoke() = 0;
+};
+
+// ---------------------------------------------------------------------------
+
+class GPUFactory
+{    
+public:
+    // the gpu factory
+    static sp<GPUHardwareInterface> getGPU();
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GPU_HARDWARE_H
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
new file mode 100644
index 0000000..f65d669
--- /dev/null
+++ b/libs/surfaceflinger/Layer.cpp
@@ -0,0 +1,568 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/properties.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/StopWatch.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/EGLDisplaySurface.h>
+
+#include "clz.h"
+#include "Layer.h"
+#include "LayerBitmap.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+
+#define DEBUG_RESIZE    0
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+const uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4;
+const char* const Layer::typeID = "Layer";
+
+// ---------------------------------------------------------------------------
+
+Layer::Layer(SurfaceFlinger* flinger, DisplayID display, Client* c, int32_t i)
+    :   LayerBaseClient(flinger, display, c, i),
+        mSecure(false),
+        mFrontBufferIndex(1),
+        mNeedsBlending(true),
+        mResizeTransactionDone(false),
+        mTextureName(-1U), mTextureWidth(0), mTextureHeight(0)
+{
+    // no OpenGL operation is possible here, since we might not be
+    // in the OpenGL thread.
+}
+
+Layer::~Layer()
+{
+    client->free(clientIndex());
+    // this should always be called from the OpenGL thread
+    if (mTextureName != -1U) {
+        //glDeleteTextures(1, &mTextureName);
+        deletedTextures.add(mTextureName);
+    }
+}
+
+void Layer::initStates(uint32_t w, uint32_t h, uint32_t flags)
+{
+    LayerBase::initStates(w,h,flags);
+
+    if (flags & ISurfaceComposer::eDestroyBackbuffer)
+        lcblk->flags |= eNoCopyBack;
+}
+
+sp<LayerBaseClient::Surface> Layer::getSurface() const
+{
+    return mSurface;
+}
+
+status_t Layer::setBuffers( Client* client,
+                            uint32_t w, uint32_t h,
+                            PixelFormat format, uint32_t flags)
+{
+    PixelFormatInfo info;
+    status_t err = getPixelFormatInfo(format, &info);
+    if (err) return err;
+
+    // TODO: if eHardware is explicitly requested, we should fail
+    // on systems where we can't allocate memory that can be used with
+    // DMA engines for instance.
+    
+    // FIXME: we always ask for hardware for now (this should come from copybit)
+    flags |= ISurfaceComposer::eHardware;
+
+    const uint32_t memory_flags = flags & 
+            (ISurfaceComposer::eGPU | 
+             ISurfaceComposer::eHardware | 
+             ISurfaceComposer::eSecure);
+    
+    // pixel-alignment. the final alignment may be bigger because
+    // we always force a 4-byte aligned bpr.
+    uint32_t alignment = 1;
+
+    if (flags & ISurfaceComposer::eGPU) {
+        // FIXME: this value should come from the h/w
+        alignment = 8; 
+        // FIXME: this is msm7201A specific, as its GPU only supports
+        // BGRA_8888.
+        if (format == PIXEL_FORMAT_RGBA_8888) {
+            format = PIXEL_FORMAT_BGRA_8888;
+        }
+    }
+
+    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
+    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
+    sp<MemoryDealer> allocators[2];
+    for (int i=0 ; i<2 ; i++) {
+        allocators[i] = client->createAllocator(memory_flags);
+        if (allocators[i] == 0)
+            return NO_MEMORY;
+        mBuffers[i].init(allocators[i]);
+        int err = mBuffers[i].setBits(w, h, alignment, format, LayerBitmap::SECURE_BITS);
+        if (err != NO_ERROR)
+            return err;
+        mBuffers[i].clear(); // clear the bits for security
+        mBuffers[i].getInfo(lcblk->surface + i);
+    }
+
+    mSurface = new Surface(clientIndex(),
+            allocators[0]->getMemoryHeap(),
+            allocators[1]->getMemoryHeap(),
+            mIdentity);
+
+    return NO_ERROR;
+}
+
+void Layer::reloadTexture(const Region& dirty)
+{
+    if (UNLIKELY(mTextureName == -1U)) {
+        // create the texture name the first time
+        // can't do that in the ctor, because it runs in another thread.
+        mTextureName = createTexture();
+    }
+    const GGLSurface& t(frontBuffer().surface());
+    loadTexture(dirty, mTextureName, t, mTextureWidth, mTextureHeight);
+}
+
+
+void Layer::onDraw(const Region& clip) const
+{
+    if (UNLIKELY(mTextureName == -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;
+    }
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const LayerBitmap& front(frontBuffer());
+    const GGLSurface& t(front.surface());
+
+    status_t err = NO_ERROR;
+    const int can_use_copybit = canUseCopybit();
+    if (can_use_copybit)  {
+        // StopWatch watch("copybit");
+        const State& s(drawingState());
+
+        copybit_image_t dst;
+        hw.getDisplaySurface(&dst);
+        const copybit_rect_t& drect
+            = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
+
+        copybit_image_t src;
+        front.getBitmapSurface(&src);
+        copybit_rect_t srect = { 0, 0, t.width, t.height };
+
+        copybit_device_t* copybit = mFlinger->getBlitEngine();
+        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, getOrientation());
+        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
+        copybit->set_parameter(copybit, COPYBIT_DITHER,
+                s.flags & ISurfaceComposer::eLayerDither ?
+                        COPYBIT_ENABLE : COPYBIT_DISABLE);
+
+        region_iterator it(clip);
+        err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+    }
+
+    if (!can_use_copybit || err) {
+        drawWithOpenGL(clip, mTextureName, t);
+    }
+}
+
+status_t Layer::reallocateBuffer(int32_t index, uint32_t w, uint32_t h)
+{
+    LOGD_IF(DEBUG_RESIZE,
+                "reallocateBuffer (layer=%p), "
+                "requested (%dx%d), "
+                "index=%d, (%dx%d), (%dx%d)",
+                this,
+                int(w), int(h),
+                int(index),
+                int(mBuffers[0].width()), int(mBuffers[0].height()),
+                int(mBuffers[1].width()), int(mBuffers[1].height()));
+
+    status_t err = mBuffers[index].resize(w, h);
+    if (err == NO_ERROR) {
+        mBuffers[index].getInfo(lcblk->surface + index);
+    } else {
+        LOGE("resizing buffer %d to (%u,%u) failed [%08x] %s",
+            index, w, h, err, strerror(err));
+        // XXX: what to do, what to do? We could try to free some
+        // hidden surfaces, instead of killing this one?
+    }
+    return err;
+}
+
+uint32_t Layer::doTransaction(uint32_t flags)
+{
+    const Layer::State& front(drawingState());
+    const Layer::State& temp(currentState());
+
+    // the test front.{w|h} != temp.{w|h} is not enough because it is possible
+    // that the size changed back to its previous value before the buffer
+    // was resized (in the eLocked case below), in which case, we still
+    // need to execute the code below so the clients have a chance to be
+    // release. resze() deals with the fact that the size can be the same.
+
+    /*
+     *  Various states we could be in...
+
+         resize = state & eResizeRequested;
+         if (backbufferChanged) {
+             if (resize == 0) {
+                 // ERROR, the resized buffer doesn't have its resize flag set
+             } else if (resize == mask) {
+                 // ERROR one of the buffer has already been resized
+             } else if (resize == mask ^ eResizeRequested) {
+                 // ERROR, the resized buffer doesn't have its resize flag set
+             } else if (resize == eResizeRequested) {
+                 // OK, Normal case, proceed with resize
+             }
+         } else {
+             if (resize == 0) {
+                 // OK, nothing special, do nothing
+             } else if (resize == mask) {
+                 // restarted transaction, do nothing
+             } else if (resize == mask ^ eResizeRequested) {
+                 // restarted transaction, do nothing
+             } else if (resize == eResizeRequested) {
+                 // OK, size reset to previous value, proceed with resize
+             }
+         }
+     */
+
+    // Index of the back buffer
+    const bool backbufferChanged = (front.w != temp.w) || (front.h != temp.h);
+    const uint32_t state = lcblk->swapState;
+    const int32_t clientBackBufferIndex = layer_cblk_t::backBuffer(state);
+    const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0;
+    uint32_t resizeFlags = state & eResizeRequested;
+
+    if (UNLIKELY(backbufferChanged && (resizeFlags != eResizeRequested))) {
+        LOGE(   "backbuffer size changed, but both resize flags are not set! "
+                "(layer=%p), state=%08x, requested (%dx%d), drawing (%d,%d), "
+                "index=%d, (%dx%d), (%dx%d)",
+                this,  state,
+                int(temp.w), int(temp.h),
+                int(drawingState().w), int(drawingState().h),
+                int(clientBackBufferIndex),
+                int(mBuffers[0].width()), int(mBuffers[0].height()),
+                int(mBuffers[1].width()), int(mBuffers[1].height()));
+        // if we get there we're pretty screwed. the only reasonable
+        // thing to do is to pretend we should do the resize since
+        // backbufferChanged is set (this also will give a chance to
+        // client to get unblocked)
+        resizeFlags = eResizeRequested;
+    }
+
+    if (resizeFlags == eResizeRequested)  {
+        // NOTE: asserting that clientBackBufferIndex!=mFrontBufferIndex
+        // here, would be wrong and misleading because by this point
+        // mFrontBufferIndex has not been updated yet.
+
+        LOGD_IF(DEBUG_RESIZE,
+                    "resize (layer=%p), state=%08x, "
+                    "requested (%dx%d), "
+                    "drawing (%d,%d), "
+                    "index=%d, (%dx%d), (%dx%d)",
+                    this,  state,
+                    int(temp.w), int(temp.h),
+                    int(drawingState().w), int(drawingState().h),
+                    int(clientBackBufferIndex),
+                    int(mBuffers[0].width()), int(mBuffers[0].height()),
+                    int(mBuffers[1].width()), int(mBuffers[1].height()));
+
+        if (state & eLocked) {
+            // if the buffer is locked, we can't resize anything because
+            // - the backbuffer is currently in use by the user
+            // - the front buffer is being shown
+            // We just act as if the transaction didn't happen and we
+            // reschedule it later...
+            flags |= eRestartTransaction;
+        } else {
+            // This buffer needs to be resized
+            status_t err =
+                resize(clientBackBufferIndex, temp.w, temp.h, "transaction");
+            if (err == NO_ERROR) {
+                const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0;
+                android_atomic_and(~mask, &(lcblk->swapState));
+                // since a buffer became available, we can let the client go...
+                mFlinger->scheduleBroadcast(client);
+                mResizeTransactionDone = true;
+
+                // we're being resized and there is a freeze display request,
+                // acquire a freeze lock, so that the screen stays put
+                // until we've redrawn at the new size; this is to avoid
+                // glitches upon orientation changes.
+                if (mFlinger->hasFreezeRequest()) {
+                    // if the surface is hidden, don't try to acquire the
+                    // freeze lock, since hidden surfaces may never redraw
+                    if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
+                        mFreezeLock = mFlinger->getFreezeLock();
+                    }
+                }
+            }
+        }
+    }
+    
+    if (temp.sequence != front.sequence) {
+        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
+            // this surface is now hidden, so it shouldn't hold a freeze lock
+            // (it may never redraw, which is fine if it is hidden)
+            mFreezeLock.clear();
+        }
+    }
+        
+    return LayerBase::doTransaction(flags);
+}
+
+status_t Layer::resize(
+        int32_t clientBackBufferIndex,
+        uint32_t width, uint32_t height,
+        const char* what)
+{
+    /*
+     * handle resize (backbuffer and frontbuffer reallocation)
+     */
+
+    const LayerBitmap& clientBackBuffer(mBuffers[clientBackBufferIndex]);
+
+    // if the new (transaction) size is != from the the backbuffer
+    // then we need to reallocate the backbuffer
+    bool backbufferChanged = (clientBackBuffer.width()  != width) ||
+                             (clientBackBuffer.height() != height);
+
+    LOGD_IF(!backbufferChanged,
+            "(%s) eResizeRequested (layer=%p), but size not changed: "
+            "requested (%dx%d), drawing (%d,%d), current (%d,%d),"
+            "state=%08lx, index=%d, (%dx%d), (%dx%d)",
+            what, this,
+            int(width), int(height),
+            int(drawingState().w), int(drawingState().h),
+            int(currentState().w), int(currentState().h),
+            long(lcblk->swapState),
+            int(clientBackBufferIndex),
+            int(mBuffers[0].width()), int(mBuffers[0].height()),
+            int(mBuffers[1].width()), int(mBuffers[1].height()));
+
+    // this can happen when changing the size back and forth quickly
+    status_t err = NO_ERROR;
+    if (backbufferChanged) {
+        err = reallocateBuffer(clientBackBufferIndex, width, height);
+    }
+    if (UNLIKELY(err != NO_ERROR)) {
+        // couldn't reallocate the surface
+        android_atomic_write(eInvalidSurface, &lcblk->swapState);
+        memset(lcblk->surface+clientBackBufferIndex, 0, sizeof(surface_info_t));
+    }
+    return err;
+}
+
+void Layer::setSizeChanged(uint32_t w, uint32_t h)
+{
+    LOGD_IF(DEBUG_RESIZE,
+            "setSizeChanged w=%d, h=%d (old: w=%d, h=%d)",
+            w, h, mCurrentState.w, mCurrentState.h);
+    android_atomic_or(eResizeRequested, &(lcblk->swapState));
+}
+
+// ----------------------------------------------------------------------------
+// pageflip handling...
+// ----------------------------------------------------------------------------
+
+void Layer::lockPageFlip(bool& recomputeVisibleRegions)
+{
+    uint32_t state = android_atomic_or(eBusy, &(lcblk->swapState));
+    // preemptively block the client, because he might set
+    // eFlipRequested at any time and want to use this buffer
+    // for the next frame. This will be unset below if it
+    // turns out we didn't need it.
+
+    uint32_t mask = eInvalidSurface | eFlipRequested | eResizeRequested;
+    if (!(state & mask))
+        return;
+
+    if (UNLIKELY(state & eInvalidSurface)) {
+        // if eInvalidSurface is set, this means the surface
+        // became invalid during a transaction (NO_MEMORY for instance)
+        mFlinger->scheduleBroadcast(client);
+        return;
+    }
+
+    if (UNLIKELY(state & eFlipRequested)) {
+        uint32_t oldState;
+        mPostedDirtyRegion = post(&oldState, recomputeVisibleRegions);
+        if (oldState & eNextFlipPending) {
+            // Process another round (we know at least a buffer
+            // is ready for that client).
+            mFlinger->signalEvent();
+        }
+    }
+}
+
+Region Layer::post(uint32_t* previousSate, bool& recomputeVisibleRegions)
+{
+    // atomically swap buffers and (re)set eFlipRequested
+    int32_t oldValue, newValue;
+    layer_cblk_t * const lcblk = this->lcblk;
+    do {
+        oldValue = lcblk->swapState;
+            // get the current value
+
+        LOG_ASSERT(oldValue&eFlipRequested,
+            "eFlipRequested not set, yet we're flipping! (state=0x%08lx)",
+            long(oldValue));
+
+        newValue = (oldValue ^ eIndex);
+            // swap buffers
+
+        newValue &= ~(eFlipRequested | eNextFlipPending);
+            // clear eFlipRequested and eNextFlipPending
+
+        if (oldValue & eNextFlipPending)
+            newValue |= eFlipRequested;
+            // if eNextFlipPending is set (second buffer already has something
+            // in it) we need to reset eFlipRequested because the client
+            // might never do it
+
+    } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState)));
+    *previousSate = oldValue;
+
+    const int32_t index = (newValue & eIndex) ^ 1;
+    mFrontBufferIndex = index;
+
+    // ... post the new front-buffer
+    Region dirty(lcblk->region + index);
+    dirty.andSelf(frontBuffer().bounds());
+
+    //LOGI("Did post oldValue=%08lx, newValue=%08lx, mFrontBufferIndex=%u\n",
+    //    oldValue, newValue, mFrontBufferIndex);
+    //dirty.dump("dirty");
+
+    if (UNLIKELY(oldValue & eResizeRequested)) {
+
+        LOGD_IF(DEBUG_RESIZE,
+                     "post (layer=%p), state=%08x, "
+                     "index=%d, (%dx%d), (%dx%d)",
+                     this,  newValue,
+                     int(1-index),
+                     int(mBuffers[0].width()), int(mBuffers[0].height()),
+                     int(mBuffers[1].width()), int(mBuffers[1].height()));
+
+        // here, we just posted the surface and we have resolved
+        // the front/back buffer indices. The client is blocked, so
+        // it cannot start using the new backbuffer.
+
+        // If the backbuffer was resized in THIS round, we actually cannot
+        // resize the frontbuffer because it has *just* been drawn (and we
+        // would have nothing to draw). In this case we just skip the resize
+        // it'll happen after the next page flip or during the next
+        // transaction.
+
+        const uint32_t mask = (1-index) ? eResizeBuffer1 : eResizeBuffer0;
+        if (mResizeTransactionDone && (newValue & mask)) {
+            // Resize the layer's second buffer only if the transaction
+            // happened. It may not have happened yet if eResizeRequested
+            // was set immediately after the "transactionRequested" test,
+            // in which case the drawing state's size would be wrong.
+            mFreezeLock.clear();
+            const Layer::State& s(drawingState());
+            if (resize(1-index, s.w, s.h, "post") == NO_ERROR) {
+                do {
+                    oldValue = lcblk->swapState;
+                    if ((oldValue & eResizeRequested) == eResizeRequested) {
+                        // ugh, another resize was requested since we processed
+                        // the first buffer, don't free the client, and let
+                        // the next transaction handle everything.
+                        break;
+                    }
+                    newValue = oldValue & ~mask;
+                } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState)));
+            }
+            mResizeTransactionDone = false;
+            recomputeVisibleRegions = true;
+            this->contentDirty = true;
+        }
+    }
+
+    reloadTexture(dirty);
+
+    return dirty;
+}
+
+Point Layer::getPhysicalSize() const
+{
+    const LayerBitmap& front(frontBuffer());
+    return Point(front.width(), front.height());
+}
+
+void Layer::unlockPageFlip(
+        const Transform& planeTransform, Region& outDirtyRegion)
+{
+    Region dirtyRegion(mPostedDirtyRegion);
+    if (!dirtyRegion.isEmpty()) {
+        mPostedDirtyRegion.clear();
+        // The dirty region is given in the layer's coordinate space
+        // transform the dirty region by the surface's transformation
+        // and the global transformation.
+        const Layer::State& s(drawingState());
+        const Transform tr(planeTransform * s.transform);
+        dirtyRegion = tr.transform(dirtyRegion);
+
+        // At this point, the dirty region is in screen space.
+        // Make sure it's constrained by the visible region (which
+        // is in screen space as well).
+        dirtyRegion.andSelf(visibleRegionScreen);
+        outDirtyRegion.orSelf(dirtyRegion);
+
+        // client could be blocked, so signal them so they get a
+        // chance to reevaluate their condition.
+        mFlinger->scheduleBroadcast(client);
+    }
+}
+
+void Layer::finishPageFlip()
+{
+    if (LIKELY(!(lcblk->swapState & eInvalidSurface))) {
+        LOGE_IF(!(lcblk->swapState & eBusy),
+                "layer %p wasn't locked!", this);
+        android_atomic_and(~eBusy, &(lcblk->swapState));
+    }
+    mFlinger->scheduleBroadcast(client);
+}
+
+
+// ---------------------------------------------------------------------------
+
+
+}; // namespace android
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
new file mode 100644
index 0000000..2867f2b
--- /dev/null
+++ b/libs/surfaceflinger/Layer.h
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_LAYER_H
+#define ANDROID_LAYER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <ui/PixelFormat.h>
+
+#include <private/ui/SharedState.h>
+#include <private/ui/LayerState.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "LayerBitmap.h"
+#include "LayerBase.h"
+#include "Transform.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class Client;
+class LayerBitmap;
+class MemoryDealer;
+class FreezeLock;
+
+// ---------------------------------------------------------------------------
+
+class Layer : public LayerBaseClient
+{
+public:    
+    static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+
+                 Layer(SurfaceFlinger* flinger, DisplayID display,
+                         Client* c, int32_t i);
+
+        virtual ~Layer();
+
+    inline PixelFormat pixelFormat() const {
+        return frontBuffer().pixelFormat();
+    }
+
+    status_t setBuffers(    Client* client,
+                            uint32_t w, uint32_t h,
+                            PixelFormat format, uint32_t flags=0);
+
+    virtual void onDraw(const Region& clip) const;
+    virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
+    virtual void setSizeChanged(uint32_t w, uint32_t h);
+    virtual uint32_t doTransaction(uint32_t transactionFlags);
+    virtual Point getPhysicalSize() const;
+    virtual void lockPageFlip(bool& recomputeVisibleRegions);
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+    virtual void finishPageFlip();
+    virtual bool needsBlending() const      { return mNeedsBlending; }
+    virtual bool isSecure() const           { return mSecure; }
+    virtual GLuint getTextureName() const   { return mTextureName; }
+    virtual sp<Surface> getSurface() const;
+
+    const LayerBitmap& getBuffer(int i) const { return mBuffers[i]; }
+          LayerBitmap& getBuffer(int i)       { return mBuffers[i]; }
+
+    // only for debugging
+    const sp<FreezeLock>&  getFreezeLock() const { return mFreezeLock; }
+
+private:
+    inline const LayerBitmap&
+            frontBuffer() const { return getBuffer(mFrontBufferIndex); }
+    inline LayerBitmap&
+            frontBuffer()       { return getBuffer(mFrontBufferIndex); }
+    inline const LayerBitmap&
+            backBuffer() const  { return getBuffer(1-mFrontBufferIndex); }
+    inline LayerBitmap&
+            backBuffer()        { return getBuffer(1-mFrontBufferIndex); }
+
+    void reloadTexture(const Region& dirty);
+
+    status_t resize(int32_t index, uint32_t w, uint32_t h, const char* what);
+    Region post(uint32_t* oldState, bool& recomputeVisibleRegions);
+    status_t reallocateBuffer(int32_t index, uint32_t w, uint32_t h);
+
+    sp<Surface>             mSurface;
+
+            bool            mSecure;
+            LayerBitmap     mBuffers[2];
+            int32_t         mFrontBufferIndex;
+            bool            mNeedsBlending;
+            bool            mResizeTransactionDone;
+            Region          mPostedDirtyRegion;
+            sp<FreezeLock>  mFreezeLock;
+            
+            GLuint          mTextureName;
+            GLuint          mTextureWidth;
+            GLuint          mTextureHeight;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_H
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
new file mode 100644
index 0000000..0cf53f7
--- /dev/null
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -0,0 +1,740 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <hardware/hardware.h>
+
+#include "clz.h"
+#include "LayerBase.h"
+#include "LayerBlur.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+
+// We don't honor the premultiplied alpha flags, which means that
+// premultiplied surface may be composed using a non-premultiplied
+// equation. We do this because it may be a lot faster on some hardware
+// The correct value is HONOR_PREMULTIPLIED_ALPHA = 1
+#define HONOR_PREMULTIPLIED_ALPHA   0
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerBase::typeInfo = 1;
+const char* const LayerBase::typeID = "LayerBase";
+
+const uint32_t LayerBaseClient::typeInfo = LayerBase::typeInfo | 2;
+const char* const LayerBaseClient::typeID = "LayerBaseClient";
+
+// ---------------------------------------------------------------------------
+
+Vector<GLuint> LayerBase::deletedTextures; 
+
+int32_t LayerBase::sIdentity = 0;
+
+LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
+    : dpy(display), contentDirty(false),
+      mFlinger(flinger),
+      mTransformed(false),
+      mOrientation(0),
+      mCanUseCopyBit(false),
+      mTransactionFlags(0),
+      mPremultipliedAlpha(true),
+      mIdentity(uint32_t(android_atomic_inc(&sIdentity))),
+      mInvalidate(0)
+{
+    const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
+    mFlags = hw.getFlags();
+}
+
+LayerBase::~LayerBase()
+{
+}
+
+const GraphicPlane& LayerBase::graphicPlane(int dpy) const
+{ 
+    return mFlinger->graphicPlane(dpy);
+}
+
+GraphicPlane& LayerBase::graphicPlane(int dpy)
+{
+    return mFlinger->graphicPlane(dpy); 
+}
+
+void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
+{
+    uint32_t layerFlags = 0;
+    if (flags & ISurfaceComposer::eHidden)
+        layerFlags = ISurfaceComposer::eLayerHidden;
+
+    if (flags & ISurfaceComposer::eNonPremultiplied)
+        mPremultipliedAlpha = false;
+
+    mCurrentState.z         = 0;
+    mCurrentState.w         = w;
+    mCurrentState.h         = h;
+    mCurrentState.alpha     = 0xFF;
+    mCurrentState.flags     = layerFlags;
+    mCurrentState.sequence  = 0;
+    mCurrentState.transform.set(0, 0);
+
+    // drawing state & current state are identical
+    mDrawingState = mCurrentState;
+}
+
+void LayerBase::commitTransaction(bool skipSize) {
+    const uint32_t w = mDrawingState.w;
+    const uint32_t h = mDrawingState.h;
+    mDrawingState = mCurrentState;
+    if (skipSize) {
+        mDrawingState.w = w;
+        mDrawingState.h = h;
+    }
+}
+void LayerBase::forceVisibilityTransaction() {
+    // this can be called without SurfaceFlinger.mStateLock, but if we
+    // can atomically increment the sequence number, it doesn't matter.
+    android_atomic_inc(&mCurrentState.sequence);
+    requestTransaction();
+}
+bool LayerBase::requestTransaction() {
+    int32_t old = setTransactionFlags(eTransactionNeeded);
+    return ((old & eTransactionNeeded) == 0);
+}
+uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
+    return android_atomic_and(~flags, &mTransactionFlags) & flags;
+}
+uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
+    return android_atomic_or(flags, &mTransactionFlags);
+}
+
+void LayerBase::setSizeChanged(uint32_t w, uint32_t h) {
+}
+
+bool LayerBase::setPosition(int32_t x, int32_t y) {
+    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.transform.set(x, y);
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setLayer(uint32_t z) {
+    if (mCurrentState.z == z)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.z = z;
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setSize(uint32_t w, uint32_t h) {
+    if (mCurrentState.w == w && mCurrentState.h == h)
+        return false;
+    setSizeChanged(w, h);
+    mCurrentState.w = w;
+    mCurrentState.h = h;
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setAlpha(uint8_t alpha) {
+    if (mCurrentState.alpha == alpha)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.alpha = alpha;
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
+    // TODO: check the matrix has changed
+    mCurrentState.sequence++;
+    mCurrentState.transform.set(
+            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setTransparentRegionHint(const Region& transparent) {
+    // TODO: check the region has changed
+    mCurrentState.sequence++;
+    mCurrentState.transparentRegion = transparent;
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
+    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
+    if (mCurrentState.flags == newFlags)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.flags = newFlags;
+    requestTransaction();
+    return true;
+}
+
+Rect LayerBase::visibleBounds() const
+{
+    return mTransformedBounds;
+}      
+
+void LayerBase::setVisibleRegion(const Region& visibleRegion) {
+    // always called from main thread
+    visibleRegionScreen = visibleRegion;
+}
+
+void LayerBase::setCoveredRegion(const Region& coveredRegion) {
+    // always called from main thread
+    coveredRegionScreen = coveredRegion;
+}
+
+uint32_t LayerBase::doTransaction(uint32_t flags)
+{
+    const Layer::State& front(drawingState());
+    const Layer::State& temp(currentState());
+
+    if (temp.sequence != front.sequence) {
+        // invalidate and recompute the visible regions if needed
+        flags |= eVisibleRegion;
+        this->contentDirty = true;
+    }
+    
+    // Commit the transaction
+    commitTransaction(flags & eRestartTransaction);
+    return flags;
+}
+
+Point LayerBase::getPhysicalSize() const
+{
+    const Layer::State& front(drawingState());
+    return Point(front.w, front.h);
+}
+
+void LayerBase::validateVisibility(const Transform& planeTransform)
+{
+    const Layer::State& s(drawingState());
+    const Transform tr(planeTransform * s.transform);
+    const bool transformed = tr.transformed();
+   
+    const Point size(getPhysicalSize());
+    uint32_t w = size.x;
+    uint32_t h = size.y;    
+    tr.transform(mVertices[0], 0, 0);
+    tr.transform(mVertices[1], 0, h);
+    tr.transform(mVertices[2], w, h);
+    tr.transform(mVertices[3], w, 0);
+    if (UNLIKELY(transformed)) {
+        // NOTE: here we could also punt if we have too many rectangles
+        // in the transparent region
+        if (tr.preserveRects()) {
+            // transform the transparent region
+            transparentRegionScreen = tr.transform(s.transparentRegion);
+        } else {
+            // transformation too complex, can't do the transparent region
+            // optimization.
+            transparentRegionScreen.clear();
+        }
+    } else {
+        transparentRegionScreen = s.transparentRegion;
+    }
+
+    // cache a few things...
+    mOrientation = tr.getOrientation();
+    mTransformedBounds = tr.makeBounds(w, h);
+    mTransformed = transformed;
+    mLeft = tr.tx();
+    mTop  = tr.ty();
+
+    // see if we can/should use 2D h/w with the new configuration
+    mCanUseCopyBit = false;
+    copybit_device_t* copybit = mFlinger->getBlitEngine();
+    if (copybit) { 
+        const int step = copybit->get(copybit, COPYBIT_ROTATION_STEP_DEG);
+        const int scaleBits = copybit->get(copybit, COPYBIT_SCALING_FRAC_BITS);
+        mCanUseCopyBit = true;
+        if ((mOrientation < 0) && (step > 1)) {
+            // arbitrary orientations not supported
+            mCanUseCopyBit = false;
+        } else if ((mOrientation > 0) && (step > 90)) {
+            // 90 deg rotations not supported
+            mCanUseCopyBit = false;
+        } else if ((tr.getType() & SkMatrix::kScale_Mask) && (scaleBits < 12)) { 
+            // arbitrary scaling not supported
+            mCanUseCopyBit = false;
+        }
+#if HONOR_PREMULTIPLIED_ALPHA 
+        else if (needsBlending() && mPremultipliedAlpha) {
+            // pre-multiplied alpha not supported
+            mCanUseCopyBit = false;
+        }
+#endif
+        else {
+            // here, we determined we can use copybit
+            if (tr.getType() & SkMatrix::kScale_Mask) {
+                // and we have scaling
+                if (!transparentRegionScreen.isRect()) {
+                    // we punt because blending is cheap (h/w) and the region is
+                    // complex, which may causes artifacts when copying
+                    // scaled content
+                    transparentRegionScreen.clear();
+                }
+            }
+        }
+    }
+}
+
+void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
+{
+}
+
+void LayerBase::unlockPageFlip(
+        const Transform& planeTransform, Region& outDirtyRegion)
+{
+    if ((android_atomic_and(~1, &mInvalidate)&1) == 1) {
+        outDirtyRegion.orSelf(visibleRegionScreen);
+    }
+}
+
+void LayerBase::finishPageFlip()
+{
+}
+
+void LayerBase::invalidate()
+{
+    if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
+        mFlinger->signalEvent();
+    }
+}
+
+void LayerBase::drawRegion(const Region& reg) const
+{
+    Region::iterator iterator(reg);
+    if (iterator) {
+        Rect r;
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+        const int32_t fbWidth  = hw.getWidth();
+        const int32_t fbHeight = hw.getHeight();
+        const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, 
+                { fbWidth, fbHeight }, { 0, fbHeight }  };
+        glVertexPointer(2, GL_SHORT, 0, vertices);
+        while (iterator.iterate(&r)) {
+            const GLint sy = fbHeight - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+        }
+    }
+}
+
+void LayerBase::draw(const Region& inClip) const
+{
+    // invalidate the region we'll update
+    Region clip(inClip);  // copy-on-write, so no-op most of the time
+
+    // Remove the transparent area from the clipping region
+    const State& s = drawingState();
+    if (LIKELY(!s.transparentRegion.isEmpty())) {
+        clip.subtract(transparentRegionScreen);
+        if (clip.isEmpty()) {
+            // usually this won't happen because this should be taken care of
+            // by SurfaceFlinger::computeVisibleRegions()
+            return;
+        }        
+    }
+
+    // reset GL state
+    glEnable(GL_SCISSOR_TEST);
+
+    onDraw(clip);
+
+    /*
+    glDisable(GL_TEXTURE_2D);
+    glDisable(GL_DITHER);
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+    glColor4x(0, 0x8000, 0, 0x10000);
+    drawRegion(transparentRegionScreen);
+    glDisable(GL_BLEND);
+    */
+}
+
+GLuint LayerBase::createTexture() const
+{
+    GLuint textureName = -1;
+    glGenTextures(1, &textureName);
+    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);
+    }
+    return textureName;
+}
+
+void LayerBase::clearWithOpenGL(const Region& clip) const
+{
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const uint32_t fbHeight = hw.getHeight();
+    glColor4x(0,0,0,0);
+    glDisable(GL_TEXTURE_2D);
+    glDisable(GL_BLEND);
+    glDisable(GL_DITHER);
+    Rect r;
+    Region::iterator iterator(clip);
+    if (iterator) {
+        glEnable(GL_SCISSOR_TEST);
+        glVertexPointer(2, GL_FIXED, 0, mVertices);
+        while (iterator.iterate(&r)) {
+            const GLint sy = fbHeight - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+        }
+    }
+}
+
+void LayerBase::drawWithOpenGL(const Region& clip,
+        GLint textureName, const GGLSurface& t, int transform) const
+{
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const uint32_t fbHeight = hw.getHeight();
+    const State& s(drawingState());
+
+    // bind our texture
+    validateTexture(textureName);
+    glEnable(GL_TEXTURE_2D);
+
+    // Dithering...
+    if (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 
+        // premultiplied alpha.
+        
+        // If the texture doesn't have an alpha channel we can
+        // use REPLACE and switch to non premultiplied alpha
+        // blending (SRCA/ONE_MINUS_SRCA).
+        
+        GLenum env, src;
+        if (needsBlending()) {
+            env = GL_MODULATE;
+            src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
+        } else {
+            env = GL_REPLACE;
+            src = GL_SRC_ALPHA;
+        }
+        const GGLfixed alpha = (s.alpha << 16)/255;
+        glColor4x(alpha, alpha, alpha, alpha);
+        glEnable(GL_BLEND);
+        glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env);
+    } else {
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
+        if (needsBlending()) {
+            GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
+            glEnable(GL_BLEND);
+            glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
+        } else {
+            glDisable(GL_BLEND);
+        }
+    }
+
+    if (UNLIKELY(transformed()
+            || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) 
+    {
+        //StopWatch watch("GL transformed");
+        Region::iterator iterator(clip);
+        if (iterator) {
+            // 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();
+            
+            if (transform == HAL_TRANSFORM_ROT_90) {
+                glTranslatef(0, 1, 0);
+                glRotatef(-90, 0, 0, 1);
+            }
+
+            if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
+                // find the smallest power-of-two that will accommodate our surface
+                GLuint tw = 1 << (31 - clz(t.width));
+                GLuint th = 1 << (31 - clz(t.height));
+                if (tw < t.width)  tw <<= 1;
+                if (th < t.height) th <<= 1;
+                // this divide should be relatively fast because it's
+                // a power-of-two (optimized path in libgcc)
+                GLfloat ws = GLfloat(t.width) /tw;
+                GLfloat hs = GLfloat(t.height)/th;
+                glScalef(ws, hs, 1.0f);
+            }
+
+            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+            glVertexPointer(2, GL_FIXED, 0, mVertices);
+            glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+
+            Rect r;
+            while (iterator.iterate(&r)) {
+                const GLint sy = fbHeight - (r.top + r.height());
+                glScissor(r.left, sy, r.width(), r.height());
+                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+            }
+
+            if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
+                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+            }
+            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+        }
+    } else {
+        Region::iterator iterator(clip);
+        if (iterator) {
+            Rect r;
+            GLint crop[4] = { 0, t.height, t.width, -t.height };
+            glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
+            int x = tx();
+            int y = ty();
+            y = fbHeight - (y + t.height);
+            while (iterator.iterate(&r)) {
+                const GLint sy = fbHeight - (r.top + r.height());
+                glScissor(r.left, sy, r.width(), r.height());
+                glDrawTexiOES(x, y, 0, t.width, t.height);
+            }
+        }
+    }
+}
+
+void LayerBase::validateTexture(GLint textureName) const
+{
+    glBindTexture(GL_TEXTURE_2D, textureName);
+    // TODO: reload the texture if needed
+    // this is currently done in loadTexture() below
+}
+
+void LayerBase::loadTexture(const Region& dirty,
+        GLint textureName, const GGLSurface& t,
+        GLuint& textureWidth, GLuint& textureHeight) const
+{
+    // TODO: defer the actual texture reload until LayerBase::validateTexture
+    // is called.
+
+    uint32_t flags = mFlags;
+    glBindTexture(GL_TEXTURE_2D, textureName);
+
+    GLuint tw = t.width;
+    GLuint th = t.height;
+
+    /*
+     * In OpenGL ES we can't specify a stride with glTexImage2D (however,
+     * GL_UNPACK_ALIGNMENT is 4, which in essence allows a limited form of
+     * stride).
+     * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
+     * need to do something reasonable (here creating a bigger texture).
+     * 
+     * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT);
+     * 
+     * This situation doesn't happen often, but some h/w have a limitation
+     * for their framebuffer (eg: must be multiple of 8 pixels), and
+     * we need to take that into account when using these buffers as
+     * textures.
+     *
+     * This should never be a problem with POT textures
+     */
+
+    tw += (((t.stride - tw) * bytesPerPixel(t.format)) / 4);
+
+    /*
+     * round to POT if needed 
+     */
+    
+    GLuint texture_w = tw;
+    GLuint texture_h = th;
+    if (!(flags & DisplayHardware::NPOT_EXTENSION)) {
+        // find the smallest power-of-two that will accommodate our surface
+        texture_w = 1 << (31 - clz(t.width));
+        texture_h = 1 << (31 - clz(t.height));
+        if (texture_w < t.width)  texture_w <<= 1;
+        if (texture_h < t.height) texture_h <<= 1;
+        if (texture_w != tw || texture_h != th) {
+            // we can't use DIRECT_TEXTURE since we changed the size
+            // of the texture
+            flags &= ~DisplayHardware::DIRECT_TEXTURE;
+        }
+    }
+
+    if (flags & DisplayHardware::DIRECT_TEXTURE) {
+        // here we're guaranteed that texture_{w|h} == t{w|h}
+        if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
+                    GL_RGB, tw, th, 0,
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, t.data);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
+                    GL_RGBA, tw, th, 0,
+                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, t.data);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
+            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
+                    GL_RGBA, tw, th, 0,
+                    GL_RGBA, GL_UNSIGNED_BYTE, t.data);
+        } else if (t.format == GGL_PIXEL_FORMAT_BGRA_8888) {
+            // TODO: add GL_BGRA extension
+        } else {
+            // oops, we don't handle this format, try the regular path
+            goto regular;
+        }
+        textureWidth = tw;
+        textureHeight = th;
+    } else {
+regular:
+        Rect bounds(dirty.bounds());
+        GLvoid* data = 0;
+        if (texture_w!=textureWidth || texture_h!=textureHeight) {
+            // texture size changed, we need to create a new one
+
+            if (!textureWidth || !textureHeight) {
+                // this is the first time, load the whole texture
+                if (texture_w==tw && texture_h==th) {
+                    // we can do it one pass
+                    data = t.data;
+                } else {
+                    // we have to create the texture first because it
+                    // doesn't match the size of the buffer
+                    bounds.set(Rect(tw, th));
+                }
+            }
+            
+            if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+                glTexImage2D(GL_TEXTURE_2D, 0,
+                        GL_RGB, texture_w, texture_h, 0,
+                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
+            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+                glTexImage2D(GL_TEXTURE_2D, 0,
+                        GL_RGBA, texture_w, texture_h, 0,
+                        GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
+            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
+                glTexImage2D(GL_TEXTURE_2D, 0,
+                        GL_RGBA, texture_w, texture_h, 0,
+                        GL_RGBA, GL_UNSIGNED_BYTE, data);
+            } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
+                        t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
+                // just show the Y plane of YUV buffers
+                data = t.data;
+                glTexImage2D(GL_TEXTURE_2D, 0,
+                        GL_LUMINANCE, texture_w, texture_h, 0,
+                        GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
+            } else {
+                // oops, we don't handle this format!
+                LOGE("layer %p, texture=%d, using format %d, which is not "
+                     "supported by the GL", this, textureName, t.format);
+                textureName = -1;
+            }
+            textureWidth = texture_w;
+            textureHeight = texture_h;
+        }
+        if (!data && textureName>=0) {
+            if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+                glTexSubImage2D(GL_TEXTURE_2D, 0,
+                        0, bounds.top, t.width, bounds.height(),
+                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
+                        t.data + bounds.top*t.width*2);
+            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+                glTexSubImage2D(GL_TEXTURE_2D, 0,
+                        0, bounds.top, t.width, bounds.height(),
+                        GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
+                        t.data + bounds.top*t.width*2);
+            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
+                glTexSubImage2D(GL_TEXTURE_2D, 0,
+                        0, bounds.top, t.width, bounds.height(),
+                        GL_RGBA, GL_UNSIGNED_BYTE,
+                        t.data + bounds.top*t.width*4);
+            }
+        }
+    }
+}
+
+bool LayerBase::canUseCopybit() const
+{
+    return mCanUseCopyBit;
+}
+
+// ---------------------------------------------------------------------------
+
+LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
+        Client* c, int32_t i)
+    : LayerBase(flinger, display), client(c),
+      lcblk( c ? &(c->ctrlblk->layers[i]) : 0 ),
+      mIndex(i)
+{
+    if (client) {
+        client->bindLayer(this, i);
+
+        // Initialize this layer's control block
+        memset(this->lcblk, 0, sizeof(layer_cblk_t));
+        this->lcblk->identity = mIdentity;
+        Region::writeEmpty(&(this->lcblk->region[0]), sizeof(flat_region_t));
+        Region::writeEmpty(&(this->lcblk->region[1]), sizeof(flat_region_t));
+    }
+}
+
+LayerBaseClient::~LayerBaseClient()
+{
+    if (client) {
+        client->free(mIndex);
+    }
+}
+
+int32_t LayerBaseClient::serverIndex() const {
+    if (client) {
+        return (client->cid<<16)|mIndex;
+    }
+    return 0xFFFF0000 | mIndex;
+}
+
+sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() const
+{
+    return new Surface(clientIndex(), mIdentity);
+}
+
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
new file mode 100644
index 0000000..a020f44
--- /dev/null
+++ b/libs/surfaceflinger/LayerBase.h
@@ -0,0 +1,356 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_LAYER_BASE_H
+#define ANDROID_LAYER_BASE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <private/ui/LayerState.h>
+
+#include <ui/Region.h>
+#include <ui/Overlay.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "Transform.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class SurfaceFlinger;
+class DisplayHardware;
+class GraphicPlane;
+class Client;
+
+// ---------------------------------------------------------------------------
+
+class LayerBase
+{
+    // poor man's dynamic_cast below
+    template<typename T>
+    struct getTypeInfoOfAnyType {
+        static uint32_t get() { return T::typeInfo; }
+    };
+
+    template<typename T>
+    struct getTypeInfoOfAnyType<T*> {
+        static uint32_t get() { return getTypeInfoOfAnyType<T>::get(); }
+    };
+
+public:
+    static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+    
+    template<typename T>
+    static T dynamicCast(LayerBase* base) {
+        uint32_t mostDerivedInfo = base->getTypeInfo();
+        uint32_t castToInfo = getTypeInfoOfAnyType<T>::get();
+        if ((mostDerivedInfo & castToInfo) == castToInfo)
+            return static_cast<T>(base);
+        return 0;
+    }
+
+    
+    static Vector<GLuint> deletedTextures; 
+
+    LayerBase(SurfaceFlinger* flinger, DisplayID display);
+    virtual ~LayerBase();
+    
+    DisplayID           dpy;
+    mutable bool        contentDirty;
+            Region      visibleRegionScreen;
+            Region      transparentRegionScreen;
+            Region      coveredRegionScreen;
+            
+            struct State {
+                uint32_t        w;
+                uint32_t        h;
+                uint32_t        z;
+                uint8_t         alpha;
+                uint8_t         flags;
+                uint8_t         reserved[2];
+                int32_t         sequence;   // changes when visible regions can change
+                uint32_t        tint;
+                Transform       transform;
+                Region          transparentRegion;
+            };
+
+            // modify current state
+            bool setPosition(int32_t x, int32_t y);
+            bool setLayer(uint32_t z);
+            bool setSize(uint32_t w, uint32_t h);
+            bool setAlpha(uint8_t alpha);
+            bool setMatrix(const layer_state_t::matrix22_t& matrix);
+            bool setTransparentRegionHint(const Region& opaque);
+            bool setFlags(uint8_t flags, uint8_t mask);
+            
+            void commitTransaction(bool skipSize);
+            bool requestTransaction();
+            void forceVisibilityTransaction();
+            
+            uint32_t getTransactionFlags(uint32_t flags);
+            uint32_t setTransactionFlags(uint32_t flags);
+            
+            Rect visibleBounds() const;
+            void drawRegion(const Region& reg) const;
+
+            void invalidate();
+            
+    /**
+     * draw - performs some global clipping optimizations
+     * and calls onDraw().
+     * Typically this method is not overridden, instead implement onDraw()
+     * to perform the actual drawing.  
+     */
+    virtual void draw(const Region& clip) const;
+    
+    /**
+     * onDraw - draws the surface.
+     */
+    virtual void onDraw(const Region& clip) const = 0;
+    
+    /**
+     * initStates - called just after construction
+     */
+    virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
+    
+    /**
+     * setSizeChanged - called when the *current* state's size is changed.
+     */
+    virtual void setSizeChanged(uint32_t w, uint32_t h);
+    
+    /**
+     * doTransaction - process the transaction. This is a good place to figure
+     * out which attributes of the surface have changed.
+     */
+    virtual uint32_t doTransaction(uint32_t transactionFlags);
+    
+    /**
+     * setVisibleRegion - called to set the new visible region. This gives
+     * a chance to update the new visible region or record the fact it changed.
+     */
+    virtual void setVisibleRegion(const Region& visibleRegion);
+    
+    /**
+     * setCoveredRegion - called when the covered region changes. The covered
+     * region correspond to any area of the surface that is covered 
+     * (transparently or not) by another surface.
+     */
+    virtual void setCoveredRegion(const Region& coveredRegion);
+    
+    /**
+     * getPhysicalSize - returns the physical size of the drawing state of
+     * the surface. If the surface is backed by a bitmap, this is the size of
+     * the bitmap (as opposed to the size of the drawing state).
+     */
+    virtual Point getPhysicalSize() const;
+
+    /**
+     * validateVisibility - cache a bunch of things
+     */
+    virtual void validateVisibility(const Transform& globalTransform);
+
+    /**
+     * lockPageFlip - called each time the screen is redrawn and returns whether
+     * the visible regions need to be recomputed (this is a fairly heavy
+     * operation, so this should be set only if needed). Typically this is used
+     * to figure out if the content or size of a surface has changed.
+     */
+    virtual void lockPageFlip(bool& recomputeVisibleRegions);
+    
+    /**
+     * unlockPageFlip - called each time the screen is redrawn. updates the
+     * final dirty region wrt the planeTransform.
+     * At this point, all visible regions, surface position and size, etc... are
+     * correct.
+     */
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+    
+    /**
+     * finishPageFlip - called after all surfaces have drawn.
+     */
+    virtual void finishPageFlip();
+    
+    /**
+     * needsBlending - true if this surface needs blending
+     */
+    virtual bool needsBlending() const  { return false; }
+
+    /**
+     * transformed -- true is this surface needs a to be transformed
+     */
+    virtual bool transformed() const    { return mTransformed; }
+
+    /**
+     * isSecure - true if this surface is secure, that is if it prevents
+     * screenshots or vns servers.
+     */
+    virtual bool isSecure() const       { return false; }
+
+            enum { // flags for doTransaction()
+                eVisibleRegion      = 0x00000002,
+                eRestartTransaction = 0x00000008
+            };
+
+
+    inline  const State&    drawingState() const    { return mDrawingState; }
+    inline  const State&    currentState() const    { return mCurrentState; }
+    inline  State&          currentState()          { return mCurrentState; }
+
+    static int compareCurrentStateZ(LayerBase*const* layerA, LayerBase*const* layerB) {
+        return layerA[0]->currentState().z - layerB[0]->currentState().z;
+    }
+
+    int32_t  getOrientation() const { return mOrientation; }
+    int  tx() const             { return mLeft; }
+    int  ty() const             { return mTop; }
+    
+protected:
+    const GraphicPlane& graphicPlane(int dpy) const;
+          GraphicPlane& graphicPlane(int dpy);
+
+          GLuint createTexture() const;
+    
+          void drawWithOpenGL(const Region& clip,
+                  GLint textureName,
+                  const GGLSurface& surface,
+                  int transform = 0) const;
+
+          void clearWithOpenGL(const Region& clip) const;
+
+          void loadTexture(const Region& dirty,
+                  GLint textureName, const GGLSurface& t,
+                  GLuint& textureWidth, GLuint& textureHeight) const;
+
+          bool canUseCopybit() const;
+          
+                SurfaceFlinger* mFlinger;
+                uint32_t        mFlags;
+
+                // cached during validateVisibility()
+                bool            mTransformed;
+                int32_t         mOrientation;
+                GLfixed         mVertices[4][2];
+                Rect            mTransformedBounds;
+                bool            mCanUseCopyBit;
+                int             mLeft;
+                int             mTop;
+            
+                // these are protected by an external lock
+                State           mCurrentState;
+                State           mDrawingState;
+    volatile    int32_t         mTransactionFlags;
+
+                // don't change, don't need a lock
+                bool            mPremultipliedAlpha;
+
+                // only read
+    const       uint32_t        mIdentity;
+     
+                // atomic
+    volatile    int32_t         mInvalidate;
+                
+
+private:
+                void validateTexture(GLint textureName) const;
+    static      int32_t         sIdentity;
+};
+
+
+// ---------------------------------------------------------------------------
+
+class LayerBaseClient : public LayerBase
+{
+public:
+    class Surface;
+   static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+
+    LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 
+            Client* client, int32_t i);
+    virtual ~LayerBaseClient();
+
+
+    Client*             const client;
+    layer_cblk_t*       const lcblk;
+
+    inline  int32_t     clientIndex() const { return mIndex; }
+            int32_t     serverIndex() const;
+
+    virtual sp<Surface> getSurface() const;
+   
+            uint32_t    getIdentity() const { return mIdentity; }
+
+    class Surface : public BnSurface 
+    {
+    public:
+        Surface(SurfaceID id, int identity) { 
+            mParams.token = id;
+            mParams.identity = identity;
+        }
+        Surface(SurfaceID id, 
+                const sp<IMemoryHeap>& heap0,
+                const sp<IMemoryHeap>& heap1,
+                int identity)
+        {
+            mParams.token = id;
+            mParams.identity = identity;
+            mParams.heap[0] = heap0;
+            mParams.heap[1] = heap1;
+        }
+        virtual ~Surface() {
+            // TODO: We now have a point here were we can clean-up the
+            // client's mess.
+            // This is also where surface id should be recycled.
+            //LOGD("Surface %d, heaps={%p, %p} destroyed",
+            //        mId, mHeap[0].get(), mHeap[1].get());
+        }
+
+        virtual void getSurfaceData(
+                ISurfaceFlingerClient::surface_data_t* params) const {
+            *params = mParams;
+        }
+
+        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers) 
+                { return INVALID_OPERATION; }
+        virtual void postBuffer(ssize_t offset) { }
+        virtual void unregisterBuffers() { };
+        virtual sp<OverlayRef> createOverlay(
+                uint32_t w, uint32_t h, int32_t format) {
+            return NULL;
+        };
+
+    private:
+        ISurfaceFlingerClient::surface_data_t mParams;
+    };
+
+private:
+    int32_t mIndex;
+
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BASE_H
diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp
new file mode 100644
index 0000000..e844350
--- /dev/null
+++ b/libs/surfaceflinger/LayerBitmap.cpp
@@ -0,0 +1,185 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/memory.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/MemoryDealer.h>
+#include <utils/IMemory.h>
+#include <ui/PixelFormat.h>
+#include <pixelflinger/pixelflinger.h>
+
+#include "LayerBitmap.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+LayerBitmap::LayerBitmap()
+    : mAllocFlags(0), mOffset(0), mSize(-1U), mAlignment(2)
+{
+    memset(&mSurface, 0, sizeof(mSurface));
+}
+
+LayerBitmap::~LayerBitmap()
+{
+    mSurface.data = 0;
+}
+
+status_t LayerBitmap::init(const sp<MemoryDealer>& allocator)
+{
+    if (mAllocator != NULL)
+        return BAD_VALUE;
+    mAllocator = allocator;
+    return NO_ERROR;
+}
+
+status_t LayerBitmap::setBits(uint32_t w, uint32_t h, uint32_t alignment, 
+        PixelFormat format, uint32_t flags)
+{
+    const sp<MemoryDealer>& allocator(mAllocator);
+    if (allocator == NULL)
+        return NO_INIT;
+
+    if (UNLIKELY(w == mSurface.width && h == mSurface.height &&
+            format == mSurface.format))
+    { // same format and size, do nothing.
+        return NO_ERROR;
+    }
+
+    PixelFormatInfo info;
+    getPixelFormatInfo(format, &info);
+
+    uint32_t allocFlags = MemoryDealer::PAGE_ALIGNED;
+    const uint32_t align = 4; // must match GL_UNPACK_ALIGNMENT
+    const uint32_t Bpp = info.bytesPerPixel;
+    uint32_t stride = (w + (alignment-1)) & ~(alignment-1);
+    stride = ((stride * Bpp + (align-1)) & ~(align-1)) / Bpp;
+    size_t size = info.getScanlineSize(stride) * h;
+    if (allocFlags & MemoryDealer::PAGE_ALIGNED) {
+        size_t pagesize = getpagesize();
+        size = (size + (pagesize-1)) & ~(pagesize-1);
+    }
+
+    /* FIXME: we should be able to have a h/v stride because the user of the
+     * surface might have stride limitation (for instance h/w codecs often do)
+     */
+    int32_t vstride = 0;
+
+    mAlignment = alignment;
+    mAllocFlags = allocFlags;
+    mOffset = 0;
+    if (mSize != size) {
+        // would be nice to have a reallocate() api
+        mBitsMemory.clear(); // free-memory
+        mBitsMemory = allocator->allocate(size, allocFlags);
+        mSize = size;
+    } else {
+        // don't erase memory if we didn't have to reallocate
+        flags &= ~SECURE_BITS;
+    }
+    if (mBitsMemory != 0) {
+        mOffset = mBitsMemory->offset();
+        mSurface.data = static_cast<GGLubyte*>(mBitsMemory->pointer());
+        mSurface.version = sizeof(GGLSurface);
+        mSurface.width  = w;
+        mSurface.height = h;
+        mSurface.stride = stride;
+        mSurface.vstride = vstride;
+        mSurface.format = format;
+        if (flags & SECURE_BITS)
+            clear();
+    }
+
+    if (mBitsMemory==0 || mSurface.data==0) {
+        LOGE("not enough memory for layer bitmap size=%u", size);
+        allocator->dump("LayerBitmap");
+        mSurface.data = 0;
+        mSize = -1U;
+        return NO_MEMORY;
+    }
+    return NO_ERROR;
+}
+
+void LayerBitmap::clear()
+{
+    // NOTE: this memset should not be necessary, at least for
+    // opaque surface. However, for security reasons it's better to keep it
+    // (in the case of pmem, it's possible that the memory contains old
+    // data)
+    if (mSurface.data) {
+        memset(mSurface.data, 0, mSize);
+        //if (bytesPerPixel(mSurface.format) == 4) {
+        //    android_memset32((uint32_t*)mSurface.data, 0xFF0000FF, mSize);
+        //} else  {
+        //    android_memset16((uint16_t*)mSurface.data, 0xF800, mSize);
+        //}
+    }
+}
+
+status_t LayerBitmap::getInfo(surface_info_t* info) const
+{
+    if (mSurface.data == 0) {
+        memset(info, 0, sizeof(surface_info_t));
+        info->bits_offset = NO_MEMORY;
+        return NO_MEMORY;
+    }
+    info->w     = uint16_t(width());
+    info->h     = uint16_t(height());
+    info->stride= uint16_t(stride());
+    info->bpr   = uint16_t(stride() * bytesPerPixel(pixelFormat()));
+    info->format= uint8_t(pixelFormat());
+    info->flags = surface_info_t::eBufferDirty;
+    info->bits_offset = ssize_t(mOffset);
+    return NO_ERROR;
+}
+
+status_t LayerBitmap::resize(uint32_t w, uint32_t h)
+{
+    int err = setBits(w, h, mAlignment, pixelFormat(), SECURE_BITS);
+    return err;
+}
+
+size_t LayerBitmap::size() const
+{
+    return mSize;
+}
+
+void LayerBitmap::getBitmapSurface(copybit_image_t* img) const
+{
+    const sp<IMemoryHeap>& mh(getAllocator()->getMemoryHeap());
+    void* sbase = mh->base();
+    const GGLSurface& t(surface());
+    img->w = t.stride  ?: t.width;
+    img->h = t.vstride ?: t.height;
+    img->format = t.format;
+    img->offset = intptr_t(t.data) - intptr_t(sbase);
+    img->base = sbase;
+    img->fd = mh->heapID();
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h
new file mode 100644
index 0000000..9ad64c4
--- /dev/null
+++ b/libs/surfaceflinger/LayerBitmap.h
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_LAYER_BITMAP_H
+#define ANDROID_LAYER_BITMAP_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Atomic.h>
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <private/ui/SharedState.h>
+#include <pixelflinger/pixelflinger.h>
+
+class copybit_image_t;
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class IMemory;
+class MemoryDealer;
+class LayerBitmap;
+
+// ---------------------------------------------------------------------------
+
+class LayerBitmap
+{
+public:
+
+    enum {
+        // erase memory to ensure security when necessary
+        SECURE_BITS = 0x00000001
+    };
+
+                LayerBitmap();
+                ~LayerBitmap();
+    status_t    init(const sp<MemoryDealer>& allocator);
+
+    status_t    setBits(uint32_t w, uint32_t h, uint32_t alignment,
+                        PixelFormat format, uint32_t flags = 0);
+    void        clear();
+
+    status_t    getInfo(surface_info_t* info) const;
+    status_t    resize(uint32_t w, uint32_t h);
+
+    const GGLSurface& surface() const   { return mSurface; }
+    Rect bounds() const                 { return Rect(width(), height()); }
+    uint32_t width() const              { return surface().width; }
+    uint32_t height() const             { return surface().height; }
+    uint32_t stride() const             { return surface().stride; }
+    PixelFormat pixelFormat() const     { return surface().format; }
+    void* serverBits() const            { return surface().data; }
+    size_t size() const;
+    const sp<MemoryDealer>& getAllocator() const { return mAllocator; }
+    void getBitmapSurface(copybit_image_t* img) const;
+
+private:
+    sp<MemoryDealer>        mAllocator;
+    sp<IMemory>             mBitsMemory;
+    uint32_t                mAllocFlags;
+    ssize_t                 mOffset;
+    GGLSurface              mSurface;
+    size_t                  mSize;
+    uint32_t                mAlignment;
+};
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BITMAP_H
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
new file mode 100644
index 0000000..d3e456f
--- /dev/null
+++ b/libs/surfaceflinger/LayerBlur.cpp
@@ -0,0 +1,234 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include "BlurFilter.h"
+#include "LayerBlur.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerBlur::typeInfo = LayerBaseClient::typeInfo | 8;
+const char* const LayerBlur::typeID = "LayerBlur";
+
+// ---------------------------------------------------------------------------
+
+LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
+        Client* client, int32_t i)
+     : LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
+     mRefreshCache(true), mCacheAge(0), mTextureName(-1U)
+{
+}
+
+LayerBlur::~LayerBlur()
+{
+    if (mTextureName != -1U) {
+        //glDeleteTextures(1, &mTextureName);
+        deletedTextures.add(mTextureName);
+    }
+}
+
+void LayerBlur::setVisibleRegion(const Region& visibleRegion)
+{
+    LayerBaseClient::setVisibleRegion(visibleRegion);
+    if (visibleRegionScreen.isEmpty()) {
+        if (mTextureName != -1U) {
+            // We're not visible, free the texture up.
+            glBindTexture(GL_TEXTURE_2D, 0);
+            glDeleteTextures(1, &mTextureName);
+            mTextureName = -1U;
+        }
+    }
+}
+
+uint32_t LayerBlur::doTransaction(uint32_t flags)
+{
+    // we're doing a transaction, refresh the cache!
+    if (!mFlinger->isFrozen()) {
+        mRefreshCache = true;
+        mCacheDirty = true;
+        flags |= eVisibleRegion;
+        this->contentDirty = true;
+    }
+    return LayerBase::doTransaction(flags);    
+}
+
+void LayerBlur::unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion)
+{
+    // this code-path must be as tight as possible, it's called each time
+    // the screen is composited.
+    if (UNLIKELY(!visibleRegionScreen.isEmpty())) {
+        // if anything visible below us is invalidated, the cache becomes dirty
+        if (!mCacheDirty && 
+                !visibleRegionScreen.intersect(outDirtyRegion).isEmpty()) {
+            mCacheDirty = true;
+        }
+        if (mCacheDirty) {
+            if (!mFlinger->isFrozen()) {
+                // update everything below us that is visible
+                outDirtyRegion.orSelf(visibleRegionScreen);
+                nsecs_t now = systemTime();
+                if ((now - mCacheAge) >= ms2ns(500)) {
+                    mCacheAge = now;
+                    mRefreshCache = true;
+                    mCacheDirty = false;
+                } else {
+                    if (!mAutoRefreshPending) {
+                        mFlinger->signalDelayedEvent(ms2ns(500));
+                        mAutoRefreshPending = true;
+                    }
+                }
+            }
+        }
+    }
+    LayerBase::unlockPageFlip(planeTransform, outDirtyRegion);
+}
+
+void LayerBlur::onDraw(const Region& clip) const
+{
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const uint32_t fbHeight = hw.getHeight();
+    int x = mTransformedBounds.left;
+    int y = mTransformedBounds.top;
+    int w = mTransformedBounds.width();
+    int h = mTransformedBounds.height();
+    GLint X = x;
+    GLint Y = fbHeight - (y + h);
+    if (X < 0) {
+        w += X;
+        X = 0;
+    }
+    if (Y < 0) {
+        h += Y;
+        Y = 0;
+    }
+    if (w<0 || h<0) {
+        // we're outside of the framebuffer
+        return;
+    }
+
+    if (mTextureName == -1U) {
+        // create the texture name the first time
+        // can't do that in the ctor, because it runs in another thread.
+        glGenTextures(1, &mTextureName);
+    }
+
+    Region::iterator iterator(clip);
+    if (iterator) {
+        glEnable(GL_TEXTURE_2D);
+        glBindTexture(GL_TEXTURE_2D, mTextureName);
+    
+        if (mRefreshCache) {
+            mRefreshCache = false;
+            mAutoRefreshPending = false;
+            
+            // allocate enough memory for 4-bytes (2 pixels) aligned data
+            const int32_t s = (w + 1) & ~1;
+            uint16_t* const pixels = (uint16_t*)malloc(s*h*2);
+
+            // This reads the frame-buffer, so a h/w GL would have to
+            // finish() its rendering first. we don't want to do that
+            // too often. Read data is 4-bytes aligned.
+            glReadPixels(X, Y, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+            
+            // blur that texture.
+            GGLSurface bl;
+            bl.version = sizeof(GGLSurface);
+            bl.width = w;
+            bl.height = h;
+            bl.stride = s;
+            bl.format = GGL_PIXEL_FORMAT_RGB_565;
+            bl.data = (GGLubyte*)pixels;            
+            blurFilter(&bl, 8, 2);
+            
+            // NOTE: this works only because we have POT. we'd have to round the
+            // texture size up, otherwise.
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+
+            free((void*)pixels);
+        }
+        
+        const State& s = drawingState();
+        if (UNLIKELY(s.alpha < 0xFF)) {
+            const GGLfixed alpha = (s.alpha << 16)/255;
+            glColor4x(0, 0, 0, alpha);
+            glEnable(GL_BLEND);
+            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        } else {
+            glDisable(GL_BLEND);
+        }
+
+        glDisable(GL_DITHER);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+        if (UNLIKELY(transformed()
+                || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) {
+            // This is a very rare scenario.
+            glMatrixMode(GL_TEXTURE);
+            glLoadIdentity();
+            glScalef(1.0f/w, -1.0f/h, 1);
+            glTranslatef(-x, -y, 0);
+            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+            glVertexPointer(2, GL_FIXED, 0, mVertices);
+            glTexCoordPointer(2, GL_FIXED, 0, mVertices);
+            Rect r;
+            while (iterator.iterate(&r)) {
+                const GLint sy = fbHeight - (r.top + r.height());
+                glScissor(r.left, sy, r.width(), r.height());
+                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+            }       
+        } else {
+            Region::iterator iterator(clip);
+            if (iterator) {
+                // NOTE: this is marginally faster with the software gl, because
+                // glReadPixels() reads the fb bottom-to-top, however we'll
+                // skip all the jaccobian computations.
+                Rect r;
+                GLint crop[4] = { 0, 0, w, h };
+                glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
+                y = fbHeight - (y + h);
+                while (iterator.iterate(&r)) {
+                    const GLint sy = fbHeight - (r.top + r.height());
+                    glScissor(r.left, sy, r.width(), r.height());
+                    glDrawTexiOES(x, y, 0, w, h);
+                }
+            }
+        }
+    }
+
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h
new file mode 100644
index 0000000..24b1156
--- /dev/null
+++ b/libs/surfaceflinger/LayerBlur.h
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_LAYER_BLUR_H
+#define ANDROID_LAYER_BLUR_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <private/ui/LayerState.h>
+
+#include <ui/Region.h>
+
+#include "LayerBase.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class LayerBlur : public LayerBaseClient
+{
+public:    
+    static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+    
+                LayerBlur(SurfaceFlinger* flinger, DisplayID display,
+                        Client* client, int32_t i);
+        virtual ~LayerBlur();
+
+    virtual void onDraw(const Region& clip) const;
+    virtual bool needsBlending() const  { return true; }
+    virtual bool isSecure() const       { return false; }
+
+    virtual uint32_t doTransaction(uint32_t flags);
+    virtual void setVisibleRegion(const Region& visibleRegion);
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+
+private:
+            bool    mCacheDirty;
+    mutable bool    mRefreshCache;
+    mutable bool    mAutoRefreshPending;
+            nsecs_t mCacheAge;
+    mutable GLuint  mTextureName;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BLUR_H
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
new file mode 100644
index 0000000..00fab70
--- /dev/null
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -0,0 +1,655 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/StopWatch.h>
+
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/EGLDisplaySurface.h>
+
+#include "LayerBuffer.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerBuffer::typeInfo = LayerBaseClient::typeInfo | 0x20;
+const char* const LayerBuffer::typeID = "LayerBuffer";
+
+// ---------------------------------------------------------------------------
+
+LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
+        Client* client, int32_t i)
+    : LayerBaseClient(flinger, display, client, i),
+      mNeedsBlending(false)
+{
+}
+
+LayerBuffer::~LayerBuffer()
+{
+    sp<SurfaceBuffer> s(getClientSurface());
+    if (s != 0) {
+        s->disown();
+        mClientSurface.clear();
+    }
+}
+
+sp<LayerBuffer::SurfaceBuffer> LayerBuffer::getClientSurface() const
+{
+    Mutex::Autolock _l(mLock);
+    return mClientSurface.promote();
+}
+
+sp<LayerBaseClient::Surface> LayerBuffer::getSurface() const
+{
+    sp<SurfaceBuffer> s;
+    Mutex::Autolock _l(mLock);
+    s = mClientSurface.promote();
+    if (s == 0) {
+        s = new SurfaceBuffer(clientIndex(),
+                const_cast<LayerBuffer *>(this));
+        mClientSurface = s;
+    }
+    return s;
+}
+
+bool LayerBuffer::needsBlending() const {
+    return mNeedsBlending;
+}
+
+void LayerBuffer::setNeedsBlending(bool blending) {
+    mNeedsBlending = blending;
+}
+
+void LayerBuffer::postBuffer(ssize_t offset)
+{
+    sp<Source> source(getSource());
+    if (source != 0)
+        source->postBuffer(offset);
+}
+
+void LayerBuffer::unregisterBuffers()
+{
+    sp<Source> source(clearSource());
+    if (source != 0)
+        source->unregisterBuffers();
+}
+
+uint32_t LayerBuffer::doTransaction(uint32_t flags)
+{
+    sp<Source> source(getSource());
+    if (source != 0)
+        source->onTransaction(flags);
+    return LayerBase::doTransaction(flags);    
+}
+
+void LayerBuffer::unlockPageFlip(const Transform& planeTransform,
+        Region& outDirtyRegion)
+{
+    // this code-path must be as tight as possible, it's called each time
+    // the screen is composited.
+    sp<Source> source(getSource());
+    if (source != 0)
+        source->onVisibilityResolved(planeTransform);
+    LayerBase::unlockPageFlip(planeTransform, outDirtyRegion);    
+}
+
+void LayerBuffer::onDraw(const Region& clip) const
+{
+    sp<Source> source(getSource());
+    if (LIKELY(source != 0)) {
+        source->onDraw(clip);
+    } else {
+        clearWithOpenGL(clip);
+    }
+}
+
+bool LayerBuffer::transformed() const
+{
+    sp<Source> source(getSource());
+    if (LIKELY(source != 0))
+        return source->transformed();
+    return false;
+}
+
+/**
+ * This creates a "buffer" source for this surface
+ */
+status_t LayerBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
+{
+    Mutex::Autolock _l(mLock);
+    if (mSource != 0)
+        return INVALID_OPERATION;
+
+    sp<BufferSource> source = new BufferSource(*this, buffers);
+
+    status_t result = source->getStatus();
+    if (result == NO_ERROR) {
+        mSource = source;
+    }
+    return result;
+}    
+
+/**
+ * This creates an "overlay" source for this surface
+ */
+sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f)
+{
+    sp<OverlayRef> result;
+    Mutex::Autolock _l(mLock);
+    if (mSource != 0)
+        return result;
+
+    sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f);
+    if (result != 0) {
+        mSource = source;
+    }
+    return result;
+}
+
+sp<LayerBuffer::Source> LayerBuffer::getSource() const {
+    Mutex::Autolock _l(mLock);
+    return mSource;
+}
+
+sp<LayerBuffer::Source> LayerBuffer::clearSource() {
+    sp<Source> source;
+    Mutex::Autolock _l(mLock);
+    source = mSource;
+    mSource.clear();
+    return source;
+}
+
+// ============================================================================
+// LayerBuffer::SurfaceBuffer
+// ============================================================================
+
+LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, LayerBuffer* owner)
+: LayerBaseClient::Surface(id, owner->getIdentity()), mOwner(owner)
+{
+}
+
+LayerBuffer::SurfaceBuffer::~SurfaceBuffer()
+{
+    unregisterBuffers();
+    mOwner = 0;
+}
+
+status_t LayerBuffer::SurfaceBuffer::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case REGISTER_BUFFERS:
+        case UNREGISTER_BUFFERS:
+        case CREATE_OVERLAY:
+        {
+            // codes that require permission check
+            IPCThreadState* ipc = IPCThreadState::self();
+            const int pid = ipc->getCallingPid();
+            const int self_pid = getpid();
+            if (LIKELY(pid != self_pid)) {
+                // we're called from a different process, do the real check
+                if (!checkCallingPermission(
+                        String16("android.permission.ACCESS_SURFACE_FLINGER")))
+                {
+                    const int uid = ipc->getCallingUid();
+                    LOGE("Permission Denial: "
+                            "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
+                    return PERMISSION_DENIED;
+                }
+            }
+        }
+    }
+    return LayerBaseClient::Surface::onTransact(code, data, reply, flags);
+}
+
+status_t LayerBuffer::SurfaceBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
+{
+    LayerBuffer* owner(getOwner());
+    if (owner)
+        return owner->registerBuffers(buffers);
+    return NO_INIT;
+}
+
+void LayerBuffer::SurfaceBuffer::postBuffer(ssize_t offset)
+{
+    LayerBuffer* owner(getOwner());
+    if (owner)
+        owner->postBuffer(offset);
+}
+
+void LayerBuffer::SurfaceBuffer::unregisterBuffers()
+{
+    LayerBuffer* owner(getOwner());
+    if (owner)
+        owner->unregisterBuffers();
+}
+
+sp<OverlayRef> LayerBuffer::SurfaceBuffer::createOverlay(
+        uint32_t w, uint32_t h, int32_t format) {
+    sp<OverlayRef> result;
+    LayerBuffer* owner(getOwner());
+    if (owner)
+        result = owner->createOverlay(w, h, format);
+    return result;
+}
+
+void LayerBuffer::SurfaceBuffer::disown()
+{
+    Mutex::Autolock _l(mLock);
+    mOwner = 0;
+}
+
+// ============================================================================
+// LayerBuffer::Buffer
+// ============================================================================
+
+LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, ssize_t offset)
+    : mBufferHeap(buffers)
+{
+    NativeBuffer& src(mNativeBuffer);
+    src.crop.l = 0;
+    src.crop.t = 0;
+    src.crop.r = buffers.w;
+    src.crop.b = buffers.h;
+    src.img.w = buffers.hor_stride ?: buffers.w;
+    src.img.h = buffers.ver_stride ?: buffers.h;
+    src.img.format = buffers.format;
+    src.img.offset = offset;
+    src.img.base   = buffers.heap->base();
+    src.img.fd     = buffers.heap->heapID();
+}
+
+LayerBuffer::Buffer::~Buffer()
+{
+}
+
+// ============================================================================
+// LayerBuffer::Source
+// LayerBuffer::BufferSource
+// LayerBuffer::OverlaySource
+// ============================================================================
+
+LayerBuffer::Source::Source(LayerBuffer& layer)
+    : mLayer(layer)
+{    
+}
+LayerBuffer::Source::~Source() {    
+}
+void LayerBuffer::Source::onDraw(const Region& clip) const {
+}
+void LayerBuffer::Source::onTransaction(uint32_t flags) {
+}
+void LayerBuffer::Source::onVisibilityResolved(
+        const Transform& planeTransform) {
+}
+void LayerBuffer::Source::postBuffer(ssize_t offset) {
+}
+void LayerBuffer::Source::unregisterBuffers() {
+}
+bool LayerBuffer::Source::transformed() const {
+    return mLayer.mTransformed; 
+}
+
+// ---------------------------------------------------------------------------
+
+LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
+        const ISurface::BufferHeap& buffers)
+    : Source(layer), mStatus(NO_ERROR), 
+      mBufferSize(0), mTextureName(-1U)
+{
+    if (buffers.heap == NULL) {
+        // this is allowed, but in this case, it is illegal to receive
+        // postBuffer(). The surface just erases the framebuffer with
+        // fully transparent pixels.
+        mBufferHeap = buffers;
+        mLayer.setNeedsBlending(false);
+        return;
+    }
+
+    status_t err = (buffers.heap->heapID() >= 0) ? NO_ERROR : NO_INIT;
+    if (err != NO_ERROR) {
+        LOGE("LayerBuffer::BufferSource: invalid heap (%s)", strerror(err));
+        mStatus = err;
+        return;
+    }
+    
+    PixelFormatInfo info;
+    err = getPixelFormatInfo(buffers.format, &info);
+    if (err != NO_ERROR) {
+        LOGE("LayerBuffer::BufferSource: invalid format %d (%s)",
+                buffers.format, strerror(err));
+        mStatus = err;
+        return;
+    }
+
+    if (buffers.hor_stride<0 || buffers.ver_stride<0) {
+        LOGE("LayerBuffer::BufferSource: invalid parameters "
+             "(w=%d, h=%d, xs=%d, ys=%d)", 
+             buffers.w, buffers.h, buffers.hor_stride, buffers.ver_stride);
+        mStatus = BAD_VALUE;
+        return;
+    }
+
+    mBufferHeap = buffers;
+    mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);    
+    mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
+    mLayer.forceVisibilityTransaction();
+    
+}
+
+LayerBuffer::BufferSource::~BufferSource()
+{    
+    if (mTextureName != -1U) {
+        LayerBase::deletedTextures.add(mTextureName);
+    }
+}
+
+void LayerBuffer::BufferSource::postBuffer(ssize_t offset)
+{    
+    ISurface::BufferHeap buffers;
+    { // scope for the lock
+        Mutex::Autolock _l(mLock);
+        buffers = mBufferHeap;
+        if (buffers.heap != 0) {
+            const size_t memorySize = buffers.heap->getSize();
+            if ((size_t(offset) + mBufferSize) > memorySize) {
+                LOGE("LayerBuffer::BufferSource::postBuffer() "
+                     "invalid buffer (offset=%d, size=%d, heap-size=%d",
+                     int(offset), int(mBufferSize), int(memorySize));
+                return;
+            }
+        }
+    }
+
+    sp<Buffer> buffer;
+    if (buffers.heap != 0) {
+        buffer = new LayerBuffer::Buffer(buffers, offset);
+        if (buffer->getStatus() != NO_ERROR)
+            buffer.clear();
+        setBuffer(buffer);
+        mLayer.invalidate();
+    }
+}
+
+void LayerBuffer::BufferSource::unregisterBuffers()
+{
+    Mutex::Autolock _l(mLock);
+    mBufferHeap.heap.clear();
+    mBuffer.clear();
+    mLayer.invalidate();
+}
+
+sp<LayerBuffer::Buffer> LayerBuffer::BufferSource::getBuffer() const
+{
+    Mutex::Autolock _l(mLock);
+    return mBuffer;
+}
+
+void LayerBuffer::BufferSource::setBuffer(const sp<LayerBuffer::Buffer>& buffer)
+{
+    Mutex::Autolock _l(mLock);
+    mBuffer = buffer;
+}
+
+bool LayerBuffer::BufferSource::transformed() const
+{
+    return mBufferHeap.transform ? true : Source::transformed(); 
+}
+
+void LayerBuffer::BufferSource::onDraw(const Region& clip) const 
+{
+    sp<Buffer> buffer(getBuffer());
+    if (UNLIKELY(buffer == 0))  {
+        // nothing to do, we don't have a buffer
+        mLayer.clearWithOpenGL(clip);
+        return;
+    }
+
+    status_t err = NO_ERROR;
+    NativeBuffer src(buffer->getBuffer());
+    const Rect& transformedBounds = mLayer.getTransformedBounds();
+    const int can_use_copybit = mLayer.canUseCopybit();
+
+    if (can_use_copybit)  {
+        const int src_width  = src.crop.r - src.crop.l;
+        const int src_height = src.crop.b - src.crop.t;
+        int W = transformedBounds.width();
+        int H = transformedBounds.height();
+        if (mLayer.getOrientation() & Transform::ROT_90) {
+            int t(W); W=H; H=t;
+        }
+
+        /* With LayerBuffer, it is likely that we'll have to rescale the
+         * surface, because this is often used for video playback or
+         * camera-preview. Since we want these operation as fast as possible
+         * we make sure we can use the 2D H/W even if it doesn't support
+         * the requested scale factor, in which case we perform the scaling
+         * in several passes. */
+
+        copybit_device_t* copybit = mLayer.mFlinger->getBlitEngine();
+        const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
+        const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
+
+        float xscale = 1.0f;
+        if (src_width > W*min)          xscale = 1.0f / min;
+        else if (src_width*mag < W)     xscale = mag;
+
+        float yscale = 1.0f;
+        if (src_height > H*min)         yscale = 1.0f / min;
+        else if (src_height*mag < H)    yscale = mag;
+
+        if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) {
+            if (UNLIKELY(mTemporaryDealer == 0)) {
+                // allocate a memory-dealer for this the first time
+                mTemporaryDealer = mLayer.mFlinger->getSurfaceHeapManager()
+                    ->createHeap(ISurfaceComposer::eHardware);
+                mTempBitmap.init(mTemporaryDealer);
+            }
+
+            const int tmp_w = floorf(src_width  * xscale);
+            const int tmp_h = floorf(src_height * yscale);
+            err = mTempBitmap.setBits(tmp_w, tmp_h, 1, src.img.format);
+
+            if (LIKELY(err == NO_ERROR)) {
+                NativeBuffer tmp;
+                mTempBitmap.getBitmapSurface(&tmp.img);
+                tmp.crop.l = 0;
+                tmp.crop.t = 0;
+                tmp.crop.r = tmp.img.w;
+                tmp.crop.b = tmp.img.h;
+
+                region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b)));
+                copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+                copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
+                copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
+                err = copybit->stretch(copybit,
+                        &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it);
+                src = tmp;
+            }
+        }
+
+        const DisplayHardware& hw(mLayer.graphicPlane(0).displayHardware());
+        copybit_image_t dst;
+        hw.getDisplaySurface(&dst);
+        const copybit_rect_t& drect
+            = reinterpret_cast<const copybit_rect_t&>(transformedBounds);
+        const State& s(mLayer.drawingState());
+        region_iterator it(clip);
+        
+        // pick the right orientation for this buffer
+        int orientation = mLayer.getOrientation();
+        if (UNLIKELY(mBufferHeap.transform)) {
+            Transform rot90;
+            GraphicPlane::orientationToTransfrom(
+                    ISurfaceComposer::eOrientation90, 0, 0, &rot90);
+            const Transform& planeTransform(mLayer.graphicPlane(0).transform());
+            const Layer::State& s(mLayer.drawingState());
+            Transform tr(planeTransform * s.transform * rot90);
+            orientation = tr.getOrientation();
+        }
+        
+        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation);
+        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
+        copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
+
+        err = copybit->stretch(copybit,
+                &dst, &src.img, &drect, &src.crop, &it);
+        if (err != NO_ERROR) {
+            LOGE("copybit failed (%s)", strerror(err));
+        }
+    }
+
+    if (!can_use_copybit || err) {
+        if (UNLIKELY(mTextureName == -1LU)) {
+            mTextureName = mLayer.createTexture();
+        }
+        GLuint w = 0;
+        GLuint h = 0;
+        GGLSurface t;
+        t.version = sizeof(GGLSurface);
+        t.width  = src.crop.r;
+        t.height = src.crop.b;
+        t.stride = src.img.w;
+        t.vstride= src.img.h;
+        t.format = src.img.format;
+        t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset);
+        const Region dirty(Rect(t.width, t.height));
+        mLayer.loadTexture(dirty, mTextureName, t, w, h);
+        mLayer.drawWithOpenGL(clip, mTextureName, t, mBufferHeap.transform);
+    }
+}
+
+
+// ---------------------------------------------------------------------------
+
+LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer,
+        sp<OverlayRef>* overlayRef, 
+        uint32_t w, uint32_t h, int32_t format)
+    : Source(layer), mVisibilityChanged(false),
+    mOverlay(0), mOverlayHandle(0), mOverlayDevice(0)
+{
+    overlay_control_device_t* overlay_dev = mLayer.mFlinger->getOverlayEngine();
+    if (overlay_dev == NULL) {
+        // overlays not supported
+        return;
+    }
+
+    mOverlayDevice = overlay_dev;
+    overlay_t* overlay = overlay_dev->createOverlay(overlay_dev, w, h, format);
+    if (overlay == NULL) {
+        // couldn't create the overlay (no memory? no more overlays?)
+        return;
+    }
+
+    // enable dithering...
+    overlay_dev->setParameter(overlay_dev, overlay, 
+            OVERLAY_DITHER, OVERLAY_ENABLE);
+
+    mOverlay = overlay;
+    mWidth = overlay->w;
+    mHeight = overlay->h;
+    mFormat = overlay->format; 
+    mWidthStride = overlay->w_stride;
+    mHeightStride = overlay->h_stride;
+
+    mOverlayHandle = overlay->getHandleRef(overlay);
+    
+    // NOTE: here it's okay to acquire a reference to "this"m as long as
+    // the reference is not released before we leave the ctor.
+    sp<OverlayChannel> channel = new OverlayChannel(this);
+
+    *overlayRef = new OverlayRef(mOverlayHandle, channel,
+            mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
+}
+
+LayerBuffer::OverlaySource::~OverlaySource()
+{
+    if (mOverlay && mOverlayDevice) {
+        overlay_control_device_t* overlay_dev = mOverlayDevice;
+        overlay_dev->destroyOverlay(overlay_dev, mOverlay);
+    }
+}
+
+void LayerBuffer::OverlaySource::onTransaction(uint32_t flags)
+{
+    const Layer::State& front(mLayer.drawingState());
+    const Layer::State& temp(mLayer.currentState());
+    if (temp.sequence != front.sequence) {
+        mVisibilityChanged = true;
+    }
+}
+
+void LayerBuffer::OverlaySource::onVisibilityResolved(
+        const Transform& planeTransform)
+{
+    // this code-path must be as tight as possible, it's called each time
+    // the screen is composited.
+    if (UNLIKELY(mOverlay != 0)) {
+        if (mVisibilityChanged) {
+            mVisibilityChanged = false;
+            const Rect& bounds = mLayer.getTransformedBounds();
+            int x = bounds.left;
+            int y = bounds.top;
+            int w = bounds.width();
+            int h = bounds.height();
+            
+            // we need a lock here to protect "destroy"
+            Mutex::Autolock _l(mLock);
+            if (mOverlay) {
+                overlay_control_device_t* overlay_dev = mOverlayDevice;
+                overlay_dev->setPosition(overlay_dev, mOverlay, x,y,w,h);
+                overlay_dev->setParameter(overlay_dev, mOverlay, 
+                        OVERLAY_TRANSFORM, mLayer.getOrientation());
+            }
+        }
+    }
+}
+
+void LayerBuffer::OverlaySource::serverDestroy() 
+{
+    mLayer.clearSource();
+    destroyOverlay();
+}
+
+void LayerBuffer::OverlaySource::destroyOverlay() 
+{
+    // we need a lock here to protect "onVisibilityResolved"
+    Mutex::Autolock _l(mLock);
+    if (mOverlay) {
+        overlay_control_device_t* overlay_dev = mOverlayDevice;
+        overlay_dev->destroyOverlay(overlay_dev, mOverlay);
+        mOverlay = 0;
+    }
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
new file mode 100644
index 0000000..2dc77f1
--- /dev/null
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -0,0 +1,216 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_LAYER_BUFFER_H
+#define ANDROID_LAYER_BUFFER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/IMemory.h>
+#include <private/ui/LayerState.h>
+#include <EGL/eglnatives.h>
+
+#include "LayerBase.h"
+#include "LayerBitmap.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class MemoryDealer;
+class Region;
+class OverlayRef;
+
+class LayerBuffer : public LayerBaseClient
+{
+    class Source : public LightRefBase<Source> {
+    public:
+        Source(LayerBuffer& layer);
+        virtual ~Source();
+        virtual void onDraw(const Region& clip) const;
+        virtual void onTransaction(uint32_t flags);
+        virtual void onVisibilityResolved(const Transform& planeTransform);
+        virtual void postBuffer(ssize_t offset);
+        virtual void unregisterBuffers();
+        virtual bool transformed() const;
+    protected:
+        LayerBuffer& mLayer;
+    };
+
+
+public:
+    static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+
+            LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
+                        Client* client, int32_t i);
+        virtual ~LayerBuffer();
+
+    virtual bool needsBlending() const;
+
+    virtual sp<LayerBaseClient::Surface> getSurface() const;
+    virtual void onDraw(const Region& clip) const;
+    virtual uint32_t doTransaction(uint32_t flags);
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+    virtual bool transformed() const;
+
+    status_t registerBuffers(const ISurface::BufferHeap& buffers);
+    void postBuffer(ssize_t offset);
+    void unregisterBuffers();
+    sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, int32_t format);
+    
+    sp<Source> getSource() const;
+    sp<Source> clearSource();
+    void setNeedsBlending(bool blending);
+    const Rect& getTransformedBounds() const {
+        return mTransformedBounds;
+    }
+
+private:
+    struct NativeBuffer {
+        copybit_image_t   img;
+        copybit_rect_t    crop;
+    };
+
+    class Buffer : public LightRefBase<Buffer> {
+    public:
+        Buffer(const ISurface::BufferHeap& buffers, ssize_t offset);
+        inline status_t getStatus() const {
+            return mBufferHeap.heap!=0 ? NO_ERROR : NO_INIT;
+        }
+        inline const NativeBuffer& getBuffer() const {
+            return mNativeBuffer;
+        }
+    protected:
+        friend class LightRefBase<Buffer>;
+        Buffer& operator = (const Buffer& rhs);
+        Buffer(const Buffer& rhs);
+        ~Buffer();
+    private:
+        ISurface::BufferHeap    mBufferHeap;
+        NativeBuffer            mNativeBuffer;
+    };
+
+    class BufferSource : public Source {
+    public:
+        BufferSource(LayerBuffer& layer, const ISurface::BufferHeap& buffers);
+        virtual ~BufferSource();
+
+        status_t getStatus() const { return mStatus; }
+        sp<Buffer> getBuffer() const;
+        void setBuffer(const sp<Buffer>& buffer);
+
+        virtual void onDraw(const Region& clip) const;
+        virtual void postBuffer(ssize_t offset);
+        virtual void unregisterBuffers();
+        virtual bool transformed() const;
+    private:
+        mutable Mutex   mLock;
+        sp<Buffer>      mBuffer;
+        status_t        mStatus;
+        ISurface::BufferHeap mBufferHeap;
+        size_t          mBufferSize;
+        mutable sp<MemoryDealer> mTemporaryDealer;
+        mutable LayerBitmap mTempBitmap;
+        mutable GLuint  mTextureName;
+    };
+    
+    class OverlaySource : public Source {
+    public:
+        OverlaySource(LayerBuffer& layer,
+                sp<OverlayRef>* overlayRef, 
+                uint32_t w, uint32_t h, int32_t format);
+        virtual ~OverlaySource();
+        virtual void onTransaction(uint32_t flags);
+        virtual void onVisibilityResolved(const Transform& planeTransform);
+    private:
+        void serverDestroy(); 
+        void destroyOverlay(); 
+        class OverlayChannel : public BnOverlay {
+            mutable Mutex mLock;
+            sp<OverlaySource> mSource;
+            virtual void destroy() {
+                sp<OverlaySource> source;
+                { // scope for the lock;
+                    Mutex::Autolock _l(mLock);
+                    source = mSource;
+                    mSource.clear();
+                }
+                if (source != 0) {
+                    source->serverDestroy();
+                }
+            }
+        public:
+            OverlayChannel(const sp<OverlaySource>& source)
+                : mSource(source) {
+            }
+        };
+        friend class OverlayChannel;
+        bool mVisibilityChanged;
+
+        overlay_t* mOverlay;        
+        overlay_handle_t mOverlayHandle;
+        overlay_control_device_t* mOverlayDevice;
+        uint32_t mWidth;
+        uint32_t mHeight;
+        int32_t mFormat;
+        int32_t mWidthStride;
+        int32_t mHeightStride;
+        mutable Mutex mLock;
+    };
+
+
+    class SurfaceBuffer : public LayerBaseClient::Surface
+    {
+    public:
+                SurfaceBuffer(SurfaceID id, LayerBuffer* owner);
+        virtual ~SurfaceBuffer();
+        virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
+        virtual void postBuffer(ssize_t offset);
+        virtual void unregisterBuffers();
+        virtual sp<OverlayRef> createOverlay(
+                uint32_t w, uint32_t h, int32_t format);
+       void disown();
+    private:
+        LayerBuffer* getOwner() const {
+            Mutex::Autolock _l(mLock);
+            return mOwner;
+        }
+        mutable Mutex   mLock;
+        LayerBuffer*    mOwner;
+    };
+
+    friend class SurfaceFlinger;
+    sp<SurfaceBuffer>   getClientSurface() const;
+
+    mutable Mutex   mLock;
+    sp<Source>      mSource;
+
+    bool            mInvalidate;
+    bool            mNeedsBlending;
+    mutable wp<SurfaceBuffer> mClientSurface;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BUFFER_H
diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp
new file mode 100644
index 0000000..0c347cc
--- /dev/null
+++ b/libs/surfaceflinger/LayerDim.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include "LayerDim.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerDim::typeInfo = LayerBaseClient::typeInfo | 0x10;
+const char* const LayerDim::typeID = "LayerDim";
+sp<MemoryDealer> LayerDim::mDimmerDealer;
+LayerBitmap LayerDim::mDimmerBitmap;
+
+// ---------------------------------------------------------------------------
+
+LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display,
+        Client* client, int32_t i)
+     : LayerBaseClient(flinger, display, client, i)
+{
+}
+
+void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h)
+{
+    // must only be called once.
+    mDimmerDealer = flinger->getSurfaceHeapManager()
+            ->createHeap(ISurfaceComposer::eHardware);
+    if (mDimmerDealer != 0) {
+        mDimmerBitmap.init(mDimmerDealer);
+        mDimmerBitmap.setBits(w, h, 1, PIXEL_FORMAT_RGB_565);
+        mDimmerBitmap.clear();
+    }
+}
+
+LayerDim::~LayerDim()
+{
+}
+
+void LayerDim::onDraw(const Region& clip) const
+{
+    const State& s(drawingState());
+
+    Region::iterator iterator(clip);
+    if (s.alpha>0 && iterator) {
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+
+        status_t err = NO_ERROR;
+        const int can_use_copybit = canUseCopybit();
+        if (can_use_copybit)  {
+            // StopWatch watch("copybit");
+            copybit_image_t dst;
+            hw.getDisplaySurface(&dst);
+            const copybit_rect_t& drect
+                = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
+
+            copybit_image_t src;
+            mDimmerBitmap.getBitmapSurface(&src);
+            const copybit_rect_t& srect(drect);
+
+            copybit_device_t* copybit = mFlinger->getBlitEngine();
+            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
+            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
+            region_iterator it(clip);
+            err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+        }
+
+        if (!can_use_copybit || err) {
+            const GGLfixed alpha = (s.alpha << 16)/255;
+            const uint32_t fbHeight = hw.getHeight();
+            glDisable(GL_TEXTURE_2D);
+            glDisable(GL_DITHER);
+            glEnable(GL_BLEND);
+            glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+            glColor4x(0, 0, 0, alpha);
+            glVertexPointer(2, GL_FIXED, 0, mVertices);
+            Rect r;
+            while (iterator.iterate(&r)) {
+                const GLint sy = fbHeight - (r.top + r.height());
+                glScissor(r.left, sy, r.width(), r.height());
+                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+            }
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h
new file mode 100644
index 0000000..3e37a47
--- /dev/null
+++ b/libs/surfaceflinger/LayerDim.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_LAYER_DIM_H
+#define ANDROID_LAYER_DIM_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "LayerBase.h"
+#include "LayerBitmap.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class LayerDim : public LayerBaseClient
+{
+public:    
+    static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+    
+                LayerDim(SurfaceFlinger* flinger, DisplayID display,
+                        Client* client, int32_t i);
+        virtual ~LayerDim();
+
+    virtual void onDraw(const Region& clip) const;
+    virtual bool needsBlending() const  { return true; }
+    virtual bool isSecure() const       { return false; }
+
+    static void initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h);
+
+private:
+    static sp<MemoryDealer> mDimmerDealer;
+    static LayerBitmap mDimmerBitmap;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_DIM_H
diff --git a/libs/surfaceflinger/LayerOrientationAnim.cpp b/libs/surfaceflinger/LayerOrientationAnim.cpp
new file mode 100644
index 0000000..2b72d7c
--- /dev/null
+++ b/libs/surfaceflinger/LayerOrientationAnim.cpp
@@ -0,0 +1,287 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <core/SkBitmap.h>
+
+#include <ui/EGLDisplaySurface.h>
+
+#include "LayerBase.h"
+#include "LayerOrientationAnim.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+#include "OrientationAnimation.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerOrientationAnim::typeInfo = LayerBase::typeInfo | 0x80;
+const char* const LayerOrientationAnim::typeID = "LayerOrientationAnim";
+
+// ---------------------------------------------------------------------------
+
+LayerOrientationAnim::LayerOrientationAnim(
+        SurfaceFlinger* flinger, DisplayID display, 
+        OrientationAnimation* anim, 
+        const LayerBitmap& bitmap,
+        const LayerBitmap& bitmapIn)
+    : LayerBase(flinger, display), mAnim(anim), 
+      mBitmap(bitmap), mBitmapIn(bitmapIn), 
+      mTextureName(-1), mTextureNameIn(-1)
+{
+    mStartTime = systemTime();
+    mFinishTime = 0;
+    mOrientationCompleted = false;
+    mFirstRedraw = false;
+    mLastNormalizedTime = 0;
+    mLastScale = 0;
+    mNeedsBlending = false;
+}
+
+LayerOrientationAnim::~LayerOrientationAnim()
+{
+    if (mTextureName != -1U) {
+        LayerBase::deletedTextures.add(mTextureName);
+    }
+    if (mTextureNameIn != -1U) {
+        LayerBase::deletedTextures.add(mTextureNameIn);
+    }
+}
+
+bool LayerOrientationAnim::needsBlending() const 
+{
+    return mNeedsBlending; 
+}
+
+Point LayerOrientationAnim::getPhysicalSize() const
+{
+    const GraphicPlane& plane(graphicPlane(0));
+    const DisplayHardware& hw(plane.displayHardware());
+    return Point(hw.getWidth(), hw.getHeight());
+}
+
+void LayerOrientationAnim::validateVisibility(const Transform&)
+{
+    const Layer::State& s(drawingState());
+    const Transform tr(s.transform);
+    const Point size(getPhysicalSize());
+    uint32_t w = size.x;
+    uint32_t h = size.y;
+    mTransformedBounds = tr.makeBounds(w, h);
+    mLeft = tr.tx();
+    mTop  = tr.ty();
+    transparentRegionScreen.clear();
+    mTransformed = true;
+    mCanUseCopyBit = false;
+    copybit_device_t* copybit = mFlinger->getBlitEngine();
+    if (copybit) { 
+        mCanUseCopyBit = true;
+    }
+}
+
+void LayerOrientationAnim::onOrientationCompleted()
+{
+    mFinishTime = systemTime();
+    mOrientationCompleted = true;
+    mFirstRedraw = true;
+    mNeedsBlending = true;
+    mFlinger->invalidateLayerVisibility(this);
+}
+
+void LayerOrientationAnim::onDraw(const Region& clip) const
+{
+    // Animation...
+    const float MIN_SCALE = 0.5f;
+    const float DURATION = ms2ns(200);
+    const float BOUNCES_PER_SECOND = 1.618f;
+    const float BOUNCES_AMPLITUDE = 1.0f/32.0f;
+
+    const nsecs_t now = systemTime();
+    float scale, alpha;
+    
+    if (mOrientationCompleted) {
+        if (mFirstRedraw) {
+            mFirstRedraw = false;
+            
+            // make a copy of what's on screen
+            copybit_image_t image;
+            mBitmapIn.getBitmapSurface(&image);
+            const DisplayHardware& hw(graphicPlane(0).displayHardware());
+            hw.copyBackToImage(image);
+
+            // and erase the screen for this round
+            glDisable(GL_BLEND);
+            glDisable(GL_DITHER);
+            glDisable(GL_SCISSOR_TEST);
+            glClearColor(0,0,0,0);
+            glClear(GL_COLOR_BUFFER_BIT);
+            
+            // FIXME: code below is gross
+            mNeedsBlending = false;
+            LayerOrientationAnim* self(const_cast<LayerOrientationAnim*>(this));
+            mFlinger->invalidateLayerVisibility(self);
+        }
+
+        // make sure pick-up where we left off
+        const float duration = DURATION * mLastNormalizedTime;
+        const float normalizedTime = (float(now - mFinishTime) / duration);
+        if (normalizedTime <= 1.0f) {
+            const float squaredTime = normalizedTime*normalizedTime;
+            scale = (1.0f - mLastScale)*squaredTime + mLastScale;
+            alpha = (1.0f - normalizedTime);
+            alpha *= alpha;
+            alpha *= alpha;
+        } else {
+            mAnim->onAnimationFinished();
+            scale = 1.0f;
+            alpha = 0.0f;
+        }
+    } else {
+        const float normalizedTime = float(now - mStartTime) / DURATION;
+        if (normalizedTime <= 1.0f) {
+            mLastNormalizedTime = normalizedTime;
+            const float squaredTime = normalizedTime*normalizedTime;
+            scale = (MIN_SCALE-1.0f)*squaredTime + 1.0f;
+            alpha = 1.0f;
+        } else {
+            mLastNormalizedTime = 1.0f;
+            const float to_seconds = DURATION / seconds(1);
+            const float phi = BOUNCES_PER_SECOND * 
+                    (((normalizedTime - 1.0f) * to_seconds)*M_PI*2);
+            scale = MIN_SCALE + BOUNCES_AMPLITUDE * (1.0f - cosf(phi));
+            alpha = 1.0f;
+        }
+        mLastScale = scale;
+    }
+    drawScaled(scale, alpha);
+}
+
+void LayerOrientationAnim::drawScaled(float f, float alpha) const
+{
+    copybit_image_t dst;
+    const GraphicPlane& plane(graphicPlane(0));
+    const DisplayHardware& hw(plane.displayHardware());
+    hw.getDisplaySurface(&dst);
+
+    // clear screen
+    // TODO: with update on demand, we may be able 
+    // to not erase the screen at all during the animation 
+    if (!mOrientationCompleted) {
+        glDisable(GL_BLEND);
+        glDisable(GL_DITHER);
+        glDisable(GL_SCISSOR_TEST);
+        glClearColor(0,0,0,0);
+        glClear(GL_COLOR_BUFFER_BIT);
+    }
+    
+    const int w = dst.w*f; 
+    const int h = dst.h*f; 
+    const int xc = uint32_t(dst.w-w)/2;
+    const int yc = uint32_t(dst.h-h)/2;
+    const copybit_rect_t drect = { xc, yc, xc+w, yc+h }; 
+
+    copybit_image_t src;
+    mBitmap.getBitmapSurface(&src);
+    const copybit_rect_t srect = { 0, 0, src.w, src.h };
+
+    int err = NO_ERROR;
+    const int can_use_copybit = canUseCopybit();
+    if (can_use_copybit)  {
+        copybit_device_t* copybit = mFlinger->getBlitEngine();
+        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+        copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
+
+        if (alpha < 1.0f) {
+            copybit_image_t srcIn;
+            mBitmapIn.getBitmapSurface(&srcIn);
+            region_iterator it(Region(Rect( drect.l, drect.t, drect.r, drect.b )));
+            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
+            err = copybit->stretch(copybit, &dst, &srcIn, &drect, &srect, &it);
+        }
+
+        if (!err && alpha > 0.0f) {
+            region_iterator it(Region(Rect( drect.l, drect.t, drect.r, drect.b )));
+            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, int(alpha*255));
+            err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+        }
+        LOGE_IF(err != NO_ERROR, "copybit failed (%s)", strerror(err));
+    }
+    if (!can_use_copybit || err) {   
+        GGLSurface t;
+        t.version = sizeof(GGLSurface);
+        t.width  = src.w;
+        t.height = src.h;
+        t.stride = src.w;
+        t.vstride= src.h;
+        t.format = src.format;
+        t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
+
+        Transform tr;
+        tr.set(f,0,0,f);
+        tr.set(xc, yc);
+        
+        // FIXME: we should not access mVertices and mDrawingState like that,
+        // but since we control the animation, we know it's going to work okay.
+        // eventually we'd need a more formal way of doing things like this.
+        LayerOrientationAnim& self(const_cast<LayerOrientationAnim&>(*this));
+        tr.transform(self.mVertices[0], 0, 0);
+        tr.transform(self.mVertices[1], 0, src.h);
+        tr.transform(self.mVertices[2], src.w, src.h);
+        tr.transform(self.mVertices[3], src.w, 0);
+        if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
+            // Too slow to do this in software
+            self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter;
+        }
+
+        if (alpha < 1.0f) {
+            copybit_image_t src;
+            mBitmapIn.getBitmapSurface(&src);
+            t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
+            if (UNLIKELY(mTextureNameIn == -1LU)) {
+                mTextureNameIn = createTexture();
+                GLuint w=0, h=0;
+                const Region dirty(Rect(t.width, t.height));
+                loadTexture(dirty, mTextureNameIn, t, w, h);
+            }
+            self.mDrawingState.alpha = 255;
+            const Region clip(Rect( drect.l, drect.t, drect.r, drect.b ));
+            drawWithOpenGL(clip, mTextureName, t);
+        }
+
+        t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
+        if (UNLIKELY(mTextureName == -1LU)) {
+            mTextureName = createTexture();
+            GLuint w=0, h=0;
+            const Region dirty(Rect(t.width, t.height));
+            loadTexture(dirty, mTextureName, t, w, h);
+        }
+        self.mDrawingState.alpha = int(alpha*255);
+        const Region clip(Rect( drect.l, drect.t, drect.r, drect.b ));
+        drawWithOpenGL(clip, mTextureName, t);
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerOrientationAnim.h b/libs/surfaceflinger/LayerOrientationAnim.h
new file mode 100644
index 0000000..7367685
--- /dev/null
+++ b/libs/surfaceflinger/LayerOrientationAnim.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_LAYER_ORIENTATION_ANIM_H
+#define ANDROID_LAYER_ORIENTATION_ANIM_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/threads.h>
+#include <utils/Parcel.h>
+
+#include "LayerBase.h"
+#include "LayerBitmap.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+class OrientationAnimation;
+
+class LayerOrientationAnim : public LayerBase
+{
+public:    
+    static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+    
+                LayerOrientationAnim(SurfaceFlinger* flinger, DisplayID display,
+                        OrientationAnimation* anim, 
+                        const LayerBitmap& zoomOut,
+                        const LayerBitmap& zoomIn);
+        virtual ~LayerOrientationAnim();
+
+            void onOrientationCompleted();
+
+    virtual void onDraw(const Region& clip) const;
+    virtual Point getPhysicalSize() const;
+    virtual void validateVisibility(const Transform& globalTransform);
+    virtual bool needsBlending() const;
+    virtual bool isSecure() const       { return false; }
+private:
+    void drawScaled(float scale, float alpha) const;
+
+    OrientationAnimation* mAnim;
+    LayerBitmap mBitmap;
+    LayerBitmap mBitmapIn;
+    nsecs_t mStartTime;
+    nsecs_t mFinishTime;
+    bool mOrientationCompleted;
+    mutable bool mFirstRedraw;
+    mutable float mLastNormalizedTime;
+    mutable float mLastScale;
+    mutable GLuint  mTextureName;
+    mutable GLuint  mTextureNameIn;
+    mutable bool mNeedsBlending;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_ORIENTATION_ANIM_H
diff --git a/libs/surfaceflinger/MODULE_LICENSE_APACHE2 b/libs/surfaceflinger/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/surfaceflinger/MODULE_LICENSE_APACHE2
diff --git a/libs/surfaceflinger/OrientationAnimation.cpp b/libs/surfaceflinger/OrientationAnimation.cpp
new file mode 100644
index 0000000..f6f1326
--- /dev/null
+++ b/libs/surfaceflinger/OrientationAnimation.cpp
@@ -0,0 +1,155 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <limits.h>
+
+#include "LayerOrientationAnim.h"
+#include "OrientationAnimation.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+
+#include "DisplayHardware/DisplayHardware.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+OrientationAnimation::OrientationAnimation(const sp<SurfaceFlinger>& flinger)
+    : mFlinger(flinger), mLayerOrientationAnim(NULL), mState(DONE)
+{
+    // allocate a memory-dealer for this the first time
+    mTemporaryDealer = mFlinger->getSurfaceHeapManager()->createHeap(
+            ISurfaceComposer::eHardware);
+}
+
+OrientationAnimation::~OrientationAnimation()
+{
+}
+
+void OrientationAnimation::onOrientationChanged()
+{
+    if (mState == DONE)
+        mState = PREPARE;
+}
+
+void OrientationAnimation::onAnimationFinished()
+{
+    if (mState != DONE)
+        mState = FINISH;
+}
+
+bool OrientationAnimation::run_impl()
+{
+    bool skip_frame;
+    switch (mState) {
+        default:
+        case DONE:
+            skip_frame = done();
+            break;
+        case PREPARE:
+            skip_frame = prepare();
+            break;
+        case PHASE1:
+            skip_frame = phase1();
+            break;
+        case PHASE2:
+            skip_frame = phase2();
+            break;
+        case FINISH:
+            skip_frame = finished();
+            break;
+    }
+    return skip_frame;
+}
+
+bool OrientationAnimation::done()
+{
+    if (mFlinger->isFrozen()) {
+        // we are not allowed to draw, but pause a bit to make sure
+        // apps don't end up using the whole CPU, if they depend on
+        // surfaceflinger for synchronization.
+        usleep(8333); // 8.3ms ~ 120fps
+        return true;
+    }
+    return false;
+}
+
+bool OrientationAnimation::prepare()
+{
+    mState = PHASE1;
+    
+    const GraphicPlane& plane(mFlinger->graphicPlane(0));
+    const DisplayHardware& hw(plane.displayHardware());
+    const uint32_t w = hw.getWidth();
+    const uint32_t h = hw.getHeight();
+
+    LayerBitmap bitmap;
+    bitmap.init(mTemporaryDealer);
+    bitmap.setBits(w, h, 1, hw.getFormat());
+
+    LayerBitmap bitmapIn;
+    bitmapIn.init(mTemporaryDealer);
+    bitmapIn.setBits(w, h, 1, hw.getFormat());
+
+    copybit_image_t front;
+    bitmap.getBitmapSurface(&front);
+    hw.copyFrontToImage(front);
+
+    LayerOrientationAnim* l = new LayerOrientationAnim(
+            mFlinger.get(), 0, this, bitmap, bitmapIn);
+    l->initStates(w, h, 0);
+    l->setLayer(INT_MAX-1);
+    mFlinger->addLayer(l);
+    mLayerOrientationAnim = l;
+    return true;
+}
+
+bool OrientationAnimation::phase1()
+{
+    if (mFlinger->isFrozen() == false) {
+        // start phase 2
+        mState = PHASE2;
+        mLayerOrientationAnim->onOrientationCompleted();
+        mLayerOrientationAnim->invalidate();
+        return true;
+        
+    }
+    mLayerOrientationAnim->invalidate();
+    return false;
+}
+
+bool OrientationAnimation::phase2()
+{
+    // do the 2nd phase of the animation
+    mLayerOrientationAnim->invalidate();
+    return false;
+}
+
+bool OrientationAnimation::finished()
+{
+    mState = DONE;
+    mFlinger->removeLayer(mLayerOrientationAnim);
+    mLayerOrientationAnim = NULL;
+    return true;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/OrientationAnimation.h b/libs/surfaceflinger/OrientationAnimation.h
new file mode 100644
index 0000000..ba33fce
--- /dev/null
+++ b/libs/surfaceflinger/OrientationAnimation.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_ORIENTATION_ANIMATION_H
+#define ANDROID_ORIENTATION_ANIMATION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "SurfaceFlinger.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class SurfaceFlinger;
+class MemoryDealer;
+class LayerOrientationAnim;
+
+class OrientationAnimation
+{
+public:    
+                 OrientationAnimation(const sp<SurfaceFlinger>& flinger);
+        virtual ~OrientationAnimation();
+
+   void onOrientationChanged();
+   void onAnimationFinished();
+   inline bool run() {
+       if (LIKELY(mState == DONE))
+           return false;
+       return run_impl();
+   }
+
+private:
+    enum {
+        DONE = 0,
+        PREPARE,
+        PHASE1,
+        PHASE2,
+        FINISH
+    };
+
+    bool run_impl();
+    bool done();
+    bool prepare();
+    bool phase1();
+    bool phase2();
+    bool finished();
+
+    sp<SurfaceFlinger> mFlinger;
+    sp<MemoryDealer> mTemporaryDealer;
+    LayerOrientationAnim* mLayerOrientationAnim;
+    int mState;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_ORIENTATION_ANIMATION_H
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
new file mode 100644
index 0000000..900282a
--- /dev/null
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -0,0 +1,1840 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+#include <utils/MemoryDealer.h>
+#include <utils/MemoryBase.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+#include <utils/StopWatch.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/DisplayInfo.h>
+#include <ui/EGLDisplaySurface.h>
+
+#include <pixelflinger/pixelflinger.h>
+#include <GLES/gl.h>
+
+#include "clz.h"
+#include "CPUGauge.h"
+#include "Layer.h"
+#include "LayerBlur.h"
+#include "LayerBuffer.h"
+#include "LayerDim.h"
+#include "LayerBitmap.h"
+#include "LayerOrientationAnim.h"
+#include "OrientationAnimation.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+
+#include "DisplayHardware/DisplayHardware.h"
+#include "GPUHardware/GPUHardware.h"
+
+
+#define DISPLAY_COUNT       1
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+void SurfaceFlinger::instantiate() {
+    defaultServiceManager()->addService(
+            String16("SurfaceFlinger"), new SurfaceFlinger());
+}
+
+void SurfaceFlinger::shutdown() {
+    // we should unregister here, but not really because
+    // when (if) the service manager goes away, all the services
+    // it has a reference to will leave too.
+}
+
+// ---------------------------------------------------------------------------
+
+SurfaceFlinger::LayerVector::LayerVector(const SurfaceFlinger::LayerVector& rhs)
+    : lookup(rhs.lookup), layers(rhs.layers)
+{
+}
+
+ssize_t SurfaceFlinger::LayerVector::indexOf(
+        LayerBase* key, size_t guess) const
+{
+    if (guess<size() && lookup.keyAt(guess) == key)
+        return guess;
+    const ssize_t i = lookup.indexOfKey(key);
+    if (i>=0) {
+        const size_t idx = lookup.valueAt(i);
+        LOG_ASSERT(layers[idx]==key,
+            "LayerVector[%p]: layers[%d]=%p, key=%p",
+            this, int(idx), layers[idx], key);
+        return idx;
+    }
+    return i;
+}
+
+ssize_t SurfaceFlinger::LayerVector::add(
+        LayerBase* layer,
+        Vector<LayerBase*>::compar_t cmp)
+{
+    size_t count = layers.size();
+    ssize_t l = 0;
+    ssize_t h = count-1;
+    ssize_t mid;
+    LayerBase* const* a = layers.array();
+    while (l <= h) {
+        mid = l + (h - l)/2;
+        const int c = cmp(a+mid, &layer);
+        if (c == 0)     { l = mid; break; }
+        else if (c<0)   { l = mid+1; }
+        else            { h = mid-1; }
+    }
+    size_t order = l;
+    while (order<count && !cmp(&layer, a+order)) {
+        order++;
+    }
+    count = lookup.size();
+    for (size_t i=0 ; i<count ; i++) {
+        if (lookup.valueAt(i) >= order) {
+            lookup.editValueAt(i)++;
+        }
+    }
+    layers.insertAt(layer, order);
+    lookup.add(layer, order);
+    return order;
+}
+
+ssize_t SurfaceFlinger::LayerVector::remove(LayerBase* layer)
+{
+    const ssize_t keyIndex = lookup.indexOfKey(layer);
+    if (keyIndex >= 0) {
+        const size_t index = lookup.valueAt(keyIndex);
+        LOG_ASSERT(layers[index]==layer,
+                "LayerVector[%p]: layers[%u]=%p, layer=%p",
+                this, int(index), layers[index], layer);
+        layers.removeItemsAt(index);
+        lookup.removeItemsAt(keyIndex);
+        const size_t count = lookup.size();
+        for (size_t i=0 ; i<count ; i++) {
+            if (lookup.valueAt(i) >= size_t(index)) {
+                lookup.editValueAt(i)--;
+            }
+        }
+        return index;
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t SurfaceFlinger::LayerVector::reorder(
+        LayerBase* layer,
+        Vector<LayerBase*>::compar_t cmp)
+{
+    // XXX: it's a little lame. but oh well...
+    ssize_t err = remove(layer);
+    if (err >=0)
+        err = add(layer, cmp);
+    return err;
+}
+
+// ---------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+SurfaceFlinger::SurfaceFlinger()
+    :   BnSurfaceComposer(), Thread(false),
+        mTransactionFlags(0),
+        mTransactionCount(0),
+        mBootTime(systemTime()),
+        mLastScheduledBroadcast(NULL),
+        mVisibleRegionsDirty(false),
+        mDeferReleaseConsole(false),
+        mFreezeDisplay(false),
+        mFreezeCount(0),
+        mDebugRegion(0),
+        mDebugCpu(0),
+        mDebugFps(0),
+        mDebugBackground(0),
+        mDebugNoBootAnimation(0),
+        mSyncObject(),
+        mDeplayedTransactionPending(0),
+        mConsoleSignals(0),
+        mSecureFrameBuffer(0)
+{
+    init();
+}
+
+void SurfaceFlinger::init()
+{
+    LOGI("SurfaceFlinger is starting");
+
+    // debugging stuff...
+    char value[PROPERTY_VALUE_MAX];
+    property_get("debug.sf.showupdates", value, "0");
+    mDebugRegion = atoi(value);
+    property_get("debug.sf.showcpu", value, "0");
+    mDebugCpu = atoi(value);
+    property_get("debug.sf.showbackground", value, "0");
+    mDebugBackground = atoi(value);
+    property_get("debug.sf.showfps", value, "0");
+    mDebugFps = atoi(value);
+    property_get("debug.sf.nobootanimation", value, "0");
+    mDebugNoBootAnimation = atoi(value);
+
+    LOGI_IF(mDebugRegion,           "showupdates enabled");
+    LOGI_IF(mDebugCpu,              "showcpu enabled");
+    LOGI_IF(mDebugBackground,       "showbackground enabled");
+    LOGI_IF(mDebugFps,              "showfps enabled");
+    LOGI_IF(mDebugNoBootAnimation,  "boot animation disabled");
+}
+
+SurfaceFlinger::~SurfaceFlinger()
+{
+    glDeleteTextures(1, &mWormholeTexName);
+    delete mOrientationAnimation;
+}
+
+copybit_device_t* SurfaceFlinger::getBlitEngine() const
+{
+    return graphicPlane(0).displayHardware().getBlitEngine();
+}
+
+overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
+{
+    return graphicPlane(0).displayHardware().getOverlayEngine();
+}
+
+sp<IMemory> SurfaceFlinger::getCblk() const
+{
+    return mServerCblkMemory;
+}
+
+status_t SurfaceFlinger::requestGPU(const sp<IGPUCallback>& callback,
+        gpu_info_t* gpu)
+{
+    IPCThreadState* ipc = IPCThreadState::self();
+    const int pid = ipc->getCallingPid();
+    status_t err = mGPU->request(pid, callback, gpu);
+    return err;
+}
+
+status_t SurfaceFlinger::revokeGPU()
+{
+    return mGPU->friendlyRevoke();
+}
+
+sp<ISurfaceFlingerClient> SurfaceFlinger::createConnection()
+{
+    Mutex::Autolock _l(mStateLock);
+    uint32_t token = mTokens.acquire();
+
+    Client* client = new Client(token, this);
+    if ((client == 0) || (client->ctrlblk == 0)) {
+        mTokens.release(token);
+        return 0;
+    }
+    status_t err = mClientsMap.add(token, client);
+    if (err < 0) {
+        delete client;
+        mTokens.release(token);
+        return 0;
+    }
+    sp<BClient> bclient =
+        new BClient(this, token, client->controlBlockMemory());
+    return bclient;
+}
+
+void SurfaceFlinger::destroyConnection(ClientID cid)
+{
+    Mutex::Autolock _l(mStateLock);
+    Client* const client = mClientsMap.valueFor(cid);
+    if (client) {
+        // free all the layers this client owns
+        const Vector<LayerBaseClient*>& layers = client->getLayers();
+        const size_t count = layers.size();
+        for (size_t i=0 ; i<count ; i++) {
+            LayerBaseClient* const layer = layers[i];
+            removeLayer_l(layer);
+        }
+
+        // the resources associated with this client will be freed
+        // during the next transaction, after these surfaces have been
+        // properly removed from the screen
+
+        // remove this client from our ClientID->Client mapping.
+        mClientsMap.removeItem(cid);
+
+        // and add it to the list of disconnected clients
+        mDisconnectedClients.add(client);
+
+        // request a transaction
+        setTransactionFlags(eTransactionNeeded);
+    }
+}
+
+const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
+{
+    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
+    const GraphicPlane& plane(mGraphicPlanes[dpy]);
+    return plane;
+}
+
+GraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
+{
+    return const_cast<GraphicPlane&>(
+        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
+}
+
+void SurfaceFlinger::bootFinished()
+{
+    const nsecs_t now = systemTime();
+    const nsecs_t duration = now - mBootTime;
+    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
+    if (mBootAnimation != 0) {
+        mBootAnimation->requestExit();
+        mBootAnimation.clear();
+    }
+}
+
+void SurfaceFlinger::onFirstRef()
+{
+    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
+
+    // Wait for the main thread to be done with its initialization
+    mReadyToRunBarrier.wait();
+}
+
+
+static inline uint16_t pack565(int r, int g, int b) {
+    return (r<<11)|(g<<5)|b;
+}
+
+// this is defined in libGLES_CM.so
+extern ISurfaceComposer* GLES_localSurfaceManager;
+
+status_t SurfaceFlinger::readyToRun()
+{
+    LOGI(   "SurfaceFlinger's main thread ready to run. "
+            "Initializing graphics H/W...");
+
+    // create the shared control-block
+    mServerHeap = new MemoryDealer(4096, MemoryDealer::READ_ONLY);
+    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
+
+    mServerCblkMemory = mServerHeap->allocate(4096);
+    LOGE_IF(mServerCblkMemory==0, "can't create shared control block");
+
+    mServerCblk = static_cast<surface_flinger_cblk_t *>(mServerCblkMemory->pointer());
+    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
+    new(mServerCblk) surface_flinger_cblk_t;
+
+    // get a reference to the GPU if we have one
+    mGPU = GPUFactory::getGPU();
+
+    // create the surface Heap manager, which manages the heaps
+    // (be it in RAM or VRAM) where surfaces are allocated
+    // We give 8 MB per client.
+    mSurfaceHeapManager = new SurfaceHeapManager(this, 8 << 20);
+
+    
+    GLES_localSurfaceManager = static_cast<ISurfaceComposer*>(this);
+
+    // we only support one display currently
+    int dpy = 0;
+
+    {
+        // initialize the main display
+        GraphicPlane& plane(graphicPlane(dpy));
+        DisplayHardware* const hw = new DisplayHardware(this, dpy);
+        plane.setDisplayHardware(hw);
+    }
+
+    // initialize primary screen
+    // (other display should be initialized in the same manner, but
+    // asynchronously, as they could come and go. None of this is supported
+    // yet).
+    const GraphicPlane& plane(graphicPlane(dpy));
+    const DisplayHardware& hw = plane.displayHardware();
+    const uint32_t w = hw.getWidth();
+    const uint32_t h = hw.getHeight();
+    const uint32_t f = hw.getFormat();
+    hw.makeCurrent();
+
+    // initialize the shared control block
+    mServerCblk->connected |= 1<<dpy;
+    display_cblk_t* dcblk = mServerCblk->displays + dpy;
+    memset(dcblk, 0, sizeof(display_cblk_t));
+    dcblk->w            = w;
+    dcblk->h            = h;
+    dcblk->format       = f;
+    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
+    dcblk->xdpi         = hw.getDpiX();
+    dcblk->ydpi         = hw.getDpiY();
+    dcblk->fps          = hw.getRefreshRate();
+    dcblk->density      = hw.getDensity();
+    asm volatile ("":::"memory");
+
+    // Initialize OpenGL|ES
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, 0);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+    glPixelStorei(GL_PACK_ALIGNMENT, 4); 
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glEnable(GL_SCISSOR_TEST);
+    glShadeModel(GL_FLAT);
+    glDisable(GL_DITHER);
+    glDisable(GL_CULL_FACE);
+
+    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
+    const uint16_t g1 = pack565(0x17,0x2f,0x17);
+    const uint16_t textureData[4] = { g0, g1, g1, g0 };
+    glGenTextures(1, &mWormholeTexName);
+    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
+            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
+
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrthof(0, w, h, 0, 0, 1);
+
+   LayerDim::initDimmer(this, w, h);
+
+    mReadyToRunBarrier.open();
+
+    /*
+     *  We're now ready to accept clients...
+     */
+
+    mOrientationAnimation = new OrientationAnimation(this);
+    
+    // start CPU gauge display
+    if (mDebugCpu)
+        mCpuGauge = new CPUGauge(this, ms2ns(500));
+
+    // the boot animation!
+    if (mDebugNoBootAnimation == false)
+        mBootAnimation = new BootAnimation(this);
+
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Events Handler
+#endif
+
+void SurfaceFlinger::waitForEvent()
+{
+    // wait for something to do
+    if (UNLIKELY(isFrozen())) {
+        // wait 5 seconds
+        int err = mSyncObject.wait(ms2ns(5000));
+        if (err != NO_ERROR) {
+            if (isFrozen()) {
+                // we timed out and are still frozen
+                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
+                        mFreezeDisplay, mFreezeCount);
+                mFreezeCount = 0;
+            }
+        }
+    } else {
+        mSyncObject.wait();
+    }
+}
+
+void SurfaceFlinger::signalEvent() {
+    mSyncObject.open();
+}
+
+void SurfaceFlinger::signal() const {
+    mSyncObject.open();
+}
+
+void SurfaceFlinger::signalDelayedEvent(nsecs_t delay)
+{
+    if (android_atomic_or(1, &mDeplayedTransactionPending) == 0) {
+        sp<DelayedTransaction> delayedEvent(new DelayedTransaction(this, delay));
+        delayedEvent->run("DelayedeEvent", PRIORITY_URGENT_DISPLAY);
+    }
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Main loop
+#endif
+
+bool SurfaceFlinger::threadLoop()
+{
+    waitForEvent();
+
+    // check for transactions
+    if (UNLIKELY(mConsoleSignals)) {
+        handleConsoleEvents();
+    }
+
+    if (LIKELY(mTransactionCount == 0)) {
+        // if we're in a global transaction, don't do anything.
+        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
+        uint32_t transactionFlags = getTransactionFlags(mask);
+        if (LIKELY(transactionFlags)) {
+            handleTransaction(transactionFlags);
+        }
+    }
+
+    // post surfaces (if needed)
+    handlePageFlip();
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    if (LIKELY(hw.canDraw())) {
+        // repaint the framebuffer (if needed)
+        handleRepaint();
+
+        // release the clients before we flip ('cause flip might block)
+        unlockClients();
+        executeScheduledBroadcasts();
+
+        // sample the cpu gauge
+        if (UNLIKELY(mDebugCpu)) {
+            handleDebugCpu();
+        }
+
+        postFramebuffer();
+    } else {
+        // pretend we did the post
+        unlockClients();
+        executeScheduledBroadcasts();
+        usleep(16667); // 60 fps period
+    }
+    return true;
+}
+
+void SurfaceFlinger::postFramebuffer()
+{
+    const bool skip = mOrientationAnimation->run();
+    if (UNLIKELY(skip)) {
+        return;
+    }
+
+    if (!mInvalidRegion.isEmpty()) {
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+
+        if (UNLIKELY(mDebugFps)) {
+            debugShowFPS();
+        }
+
+        hw.flip(mInvalidRegion);
+
+        mInvalidRegion.clear();
+
+        if (Layer::deletedTextures.size()) {
+            glDeleteTextures(
+                    Layer::deletedTextures.size(),
+                    Layer::deletedTextures.array());
+            Layer::deletedTextures.clear();
+        }
+    }
+}
+
+void SurfaceFlinger::handleConsoleEvents()
+{
+    // something to do with the console
+    const DisplayHardware& hw = graphicPlane(0).displayHardware();
+
+    int what = android_atomic_and(0, &mConsoleSignals);
+    if (what & eConsoleAcquired) {
+        hw.acquireScreen();
+    }
+
+    if (mDeferReleaseConsole && hw.canDraw()) {
+        // We got the release signal before the aquire signal
+        mDeferReleaseConsole = false;
+        revokeGPU();
+        hw.releaseScreen();
+    }
+
+    if (what & eConsoleReleased) {
+        if (hw.canDraw()) {
+            revokeGPU();
+            hw.releaseScreen();
+        } else {
+            mDeferReleaseConsole = true;
+        }
+    }
+
+    mDirtyRegion.set(hw.bounds());
+}
+
+void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
+{
+    Mutex::Autolock _l(mStateLock);
+
+    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+    const size_t count = currentLayers.size();
+
+    /*
+     * Traversal of the children
+     * (perform the transaction for each of them if needed)
+     */
+
+    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
+    if (layersNeedTransaction) {
+        for (size_t i=0 ; i<count ; i++) {
+            LayerBase* const layer = currentLayers[i];
+            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
+            if (!trFlags) continue;
+
+            const uint32_t flags = layer->doTransaction(0);
+            if (flags & Layer::eVisibleRegion)
+                mVisibleRegionsDirty = true;
+
+            if (flags & Layer::eRestartTransaction) {
+                // restart the transaction, but back-off a little
+                layer->setTransactionFlags(eTransactionNeeded);
+                setTransactionFlags(eTraversalNeeded, ms2ns(8));
+            }
+        }
+    }
+
+    /*
+     * Perform our own transaction if needed
+     */
+
+    if (transactionFlags & eTransactionNeeded) {
+        if (mCurrentState.orientation != mDrawingState.orientation) {
+            // the orientation has changed, recompute all visible regions
+            // and invalidate everything.
+
+            const int dpy = 0;
+            const int orientation = mCurrentState.orientation;
+            GraphicPlane& plane(graphicPlane(dpy));
+            plane.setOrientation(orientation);
+
+            // update the shared control block
+            const DisplayHardware& hw(plane.displayHardware());
+            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
+            dcblk->orientation = orientation;
+            if (orientation & eOrientationSwapMask) {
+                // 90 or 270 degrees orientation
+                dcblk->w = hw.getHeight();
+                dcblk->h = hw.getWidth();
+            } else {
+                dcblk->w = hw.getWidth();
+                dcblk->h = hw.getHeight();
+            }
+
+            mVisibleRegionsDirty = true;
+            mDirtyRegion.set(hw.bounds());
+
+            mOrientationAnimation->onOrientationChanged();
+        }
+
+        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
+            // freezing or unfreezing the display -> trigger animation if needed
+            mFreezeDisplay = mCurrentState.freezeDisplay;
+            const nsecs_t now = systemTime();
+            if (mFreezeDisplay) {
+                mFreezeDisplayTime = now;
+            } else {
+                //LOGD("Screen was frozen for %llu us",
+                //        ns2us(now-mFreezeDisplayTime));
+            }
+        }
+
+        // some layers might have been removed, so
+        // we need to update the regions they're exposing.
+        size_t c = mRemovedLayers.size();
+        if (c) {
+            mVisibleRegionsDirty = true;
+        }
+
+        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
+            // layers have been added
+            mVisibleRegionsDirty = true;
+        }
+
+        // get rid of all resources we don't need anymore
+        // (layers and clients)
+        free_resources_l();
+    }
+
+    commitTransaction();
+}
+
+sp<FreezeLock> SurfaceFlinger::getFreezeLock() const
+{
+    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
+}
+
+void SurfaceFlinger::computeVisibleRegions(
+    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
+{
+    const GraphicPlane& plane(graphicPlane(0));
+    const Transform& planeTransform(plane.transform());
+
+    Region aboveOpaqueLayers;
+    Region aboveCoveredLayers;
+    Region dirty;
+
+    bool secureFrameBuffer = false;
+
+    size_t i = currentLayers.size();
+    while (i--) {
+        LayerBase* const layer = currentLayers[i];
+        layer->validateVisibility(planeTransform);
+
+        // start with the whole surface at its current location
+        const Layer::State& s = layer->drawingState();
+        const Rect bounds(layer->visibleBounds());
+
+        // handle hidden surfaces by setting the visible region to empty
+        Region opaqueRegion;
+        Region visibleRegion;
+        Region coveredRegion;
+        if (UNLIKELY((s.flags & ISurfaceComposer::eLayerHidden) || !s.alpha)) {
+            visibleRegion.clear();
+        } else {
+            const bool translucent = layer->needsBlending();
+            visibleRegion.set(bounds);
+            coveredRegion = visibleRegion;
+
+            // Remove the transparent area from the visible region
+            if (translucent) {
+                visibleRegion.subtractSelf(layer->transparentRegionScreen);
+            }
+
+            // compute the opaque region
+            if (s.alpha==255 && !translucent && layer->getOrientation()>=0) {
+                // the opaque region is the visible region
+                opaqueRegion = visibleRegion;
+            }
+        }
+
+        // subtract the opaque region covered by the layers above us
+        visibleRegion.subtractSelf(aboveOpaqueLayers);
+        coveredRegion.andSelf(aboveCoveredLayers);
+
+        // compute this layer's dirty region
+        if (layer->contentDirty) {
+            // we need to invalidate the whole region
+            dirty = visibleRegion;
+            // as well, as the old visible region
+            dirty.orSelf(layer->visibleRegionScreen);
+            layer->contentDirty = false;
+        } else {
+            // compute the exposed region
+            // dirty = what's visible now - what's wasn't covered before
+            //       = what's visible now & what's was covered before
+            dirty = visibleRegion.intersect(layer->coveredRegionScreen);            
+        }
+        dirty.subtractSelf(aboveOpaqueLayers);
+
+        // accumulate to the screen dirty region
+        dirtyRegion.orSelf(dirty);
+
+        // updade aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer
+        aboveOpaqueLayers.orSelf(opaqueRegion);
+        aboveCoveredLayers.orSelf(bounds);
+        
+        // Store the visible region is screen space
+        layer->setVisibleRegion(visibleRegion);
+        layer->setCoveredRegion(coveredRegion);
+
+        // If a secure layer is partially visible, lockdown the screen!
+        if (layer->isSecure() && !visibleRegion.isEmpty()) {
+            secureFrameBuffer = true;
+        }
+    }
+
+    mSecureFrameBuffer = secureFrameBuffer;
+    opaqueRegion = aboveOpaqueLayers;
+}
+
+
+void SurfaceFlinger::commitTransaction()
+{
+    mDrawingState = mCurrentState;
+    mTransactionCV.signal();
+}
+
+void SurfaceFlinger::handlePageFlip()
+{
+    bool visibleRegions = mVisibleRegionsDirty;
+    LayerVector& currentLayers = const_cast<LayerVector&>(mDrawingState.layersSortedByZ);
+    visibleRegions |= lockPageFlip(currentLayers);
+
+        const DisplayHardware& hw = graphicPlane(0).displayHardware();
+        const Region screenRegion(hw.bounds());
+        if (visibleRegions) {
+            Region opaqueRegion;
+            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
+            mWormholeRegion = screenRegion.subtract(opaqueRegion);
+            mVisibleRegionsDirty = false;
+        }
+
+    unlockPageFlip(currentLayers);
+    mDirtyRegion.andSelf(screenRegion);
+}
+
+bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
+{
+    bool recomputeVisibleRegions = false;
+    size_t count = currentLayers.size();
+    LayerBase* const* layers = currentLayers.array();
+    for (size_t i=0 ; i<count ; i++) {
+        LayerBase* const layer = layers[i];
+        layer->lockPageFlip(recomputeVisibleRegions);
+    }
+    return recomputeVisibleRegions;
+}
+
+void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
+{
+    const GraphicPlane& plane(graphicPlane(0));
+    const Transform& planeTransform(plane.transform());
+    size_t count = currentLayers.size();
+    LayerBase* const* layers = currentLayers.array();
+    for (size_t i=0 ; i<count ; i++) {
+        LayerBase* const layer = layers[i];
+        layer->unlockPageFlip(planeTransform, mDirtyRegion);
+    }
+}
+
+void SurfaceFlinger::handleRepaint()
+{
+    // set the frame buffer
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+
+    if (UNLIKELY(mDebugRegion)) {
+        debugFlashRegions();
+    }
+
+    // compute the invalid region
+    mInvalidRegion.orSelf(mDirtyRegion);
+
+    uint32_t flags = hw.getFlags();
+    if (flags & DisplayHardware::BUFFER_PRESERVED) {
+        // here we assume DisplayHardware::flip()'s  implementation
+        // performs the copy-back optimization.
+    } else {
+        if (flags & DisplayHardware::UPDATE_ON_DEMAND) {
+            // we need to fully redraw the part that will be updated
+            mDirtyRegion.set(mInvalidRegion.bounds());
+        } else {
+            // we need to redraw everything
+            mDirtyRegion.set(hw.bounds());
+            mInvalidRegion = mDirtyRegion;
+        }
+    }
+
+    // compose all surfaces
+    composeSurfaces(mDirtyRegion);
+
+    // clear the dirty regions
+    mDirtyRegion.clear();
+}
+
+void SurfaceFlinger::composeSurfaces(const Region& dirty)
+{
+    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
+        // should never happen unless the window manager has a bug
+        // draw something...
+        drawWormhole();
+    }
+    const SurfaceFlinger& flinger(*this);
+    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
+    const size_t count = drawingLayers.size();
+    LayerBase const* const* const layers = drawingLayers.array();
+    for (size_t i=0 ; i<count ; ++i) {
+        LayerBase const * const layer = layers[i];
+        const Region& visibleRegion(layer->visibleRegionScreen);
+        if (!visibleRegion.isEmpty())  {
+            const Region clip(dirty.intersect(visibleRegion));
+            if (!clip.isEmpty()) {
+                layer->draw(clip);
+            }
+        }
+    }
+}
+
+void SurfaceFlinger::unlockClients()
+{
+    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
+    const size_t count = drawingLayers.size();
+    LayerBase* const* const layers = drawingLayers.array();
+    for (size_t i=0 ; i<count ; ++i) {
+        LayerBase* const layer = layers[i];
+        layer->finishPageFlip();
+    }
+}
+
+void SurfaceFlinger::scheduleBroadcast(Client* client)
+{
+    if (mLastScheduledBroadcast != client) {
+        mLastScheduledBroadcast = client;
+        mScheduledBroadcasts.add(client);
+    }
+}
+
+void SurfaceFlinger::executeScheduledBroadcasts()
+{
+    SortedVector<Client*>& list = mScheduledBroadcasts;
+    size_t count = list.size();
+    while (count--) {
+        per_client_cblk_t* const cblk = list[count]->ctrlblk;
+        if (cblk->lock.tryLock() == NO_ERROR) {
+            cblk->cv.broadcast();
+            list.removeAt(count);
+            cblk->lock.unlock();
+        } else {
+            // schedule another round
+            LOGW("executeScheduledBroadcasts() skipped, "
+                "contention on the client. We'll try again later...");
+            signalDelayedEvent(ms2ns(4));
+        }
+    }
+    mLastScheduledBroadcast = 0;
+}
+
+void SurfaceFlinger::handleDebugCpu()
+{
+    Mutex::Autolock _l(mDebugLock);
+    if (mCpuGauge != 0)
+        mCpuGauge->sample();
+}
+
+void SurfaceFlinger::debugFlashRegions()
+{
+    if (UNLIKELY(!mDirtyRegion.isRect())) {
+        // TODO: do this only if we don't have preserving
+        // swapBuffer. If we don't have update-on-demand,
+        // redraw everything.
+        composeSurfaces(Region(mDirtyRegion.bounds()));
+    }
+
+    glDisable(GL_TEXTURE_2D);
+    glDisable(GL_BLEND);
+    glDisable(GL_DITHER);
+    glDisable(GL_SCISSOR_TEST);
+
+    glColor4x(0x10000, 0, 0x10000, 0x10000);
+
+    Rect r;
+    Region::iterator iterator(mDirtyRegion);
+    while (iterator.iterate(&r)) {
+        GLfloat vertices[][2] = {
+                { r.left,  r.top },
+                { r.left,  r.bottom },
+                { r.right, r.bottom },
+                { r.right, r.top }
+        };
+        glVertexPointer(2, GL_FLOAT, 0, vertices);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    }
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    hw.flip(mDirtyRegion.merge(mInvalidRegion));
+    mInvalidRegion.clear();
+
+    if (mDebugRegion > 1)
+       usleep(mDebugRegion * 1000);
+
+    glEnable(GL_SCISSOR_TEST);
+    //mDirtyRegion.dump("mDirtyRegion");
+}
+
+void SurfaceFlinger::drawWormhole() const
+{
+    const Region region(mWormholeRegion.intersect(mDirtyRegion));
+    if (region.isEmpty())
+        return;
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const int32_t width = hw.getWidth();
+    const int32_t height = hw.getHeight();
+
+    glDisable(GL_BLEND);
+    glDisable(GL_DITHER);
+
+    if (LIKELY(!mDebugBackground)) {
+        glClearColorx(0,0,0,0);
+        Rect r;
+        Region::iterator iterator(region);
+        while (iterator.iterate(&r)) {
+            const GLint sy = height - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glClear(GL_COLOR_BUFFER_BIT);
+        }
+    } else {
+        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
+                { width, height }, { 0, height }  };
+        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
+        glVertexPointer(2, GL_SHORT, 0, vertices);
+        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
+        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+        glEnable(GL_TEXTURE_2D);
+        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        glMatrixMode(GL_TEXTURE);
+        glLoadIdentity();
+        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
+        Rect r;
+        Region::iterator iterator(region);
+        while (iterator.iterate(&r)) {
+            const GLint sy = height - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+        }
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    }
+}
+
+void SurfaceFlinger::debugShowFPS() const
+{
+    static int mFrameCount;
+    static int mLastFrameCount = 0;
+    static nsecs_t mLastFpsTime = 0;
+    static float mFps = 0;
+    mFrameCount++;
+    nsecs_t now = systemTime();
+    nsecs_t diff = now - mLastFpsTime;
+    if (diff > ms2ns(250)) {
+        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
+        mLastFpsTime = now;
+        mLastFrameCount = mFrameCount;
+    }
+    // XXX: mFPS has the value we want
+ }
+
+status_t SurfaceFlinger::addLayer(LayerBase* layer)
+{
+    Mutex::Autolock _l(mStateLock);
+    addLayer_l(layer);
+    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::removeLayer(LayerBase* layer)
+{
+    Mutex::Autolock _l(mStateLock);
+    removeLayer_l(layer);
+    setTransactionFlags(eTransactionNeeded);
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::invalidateLayerVisibility(LayerBase* layer)
+{
+    layer->forceVisibilityTransaction();
+    setTransactionFlags(eTraversalNeeded);
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::addLayer_l(LayerBase* layer)
+{
+    ssize_t i = mCurrentState.layersSortedByZ.add(
+                layer, &LayerBase::compareCurrentStateZ);
+    LayerBaseClient* lbc = LayerBase::dynamicCast<LayerBaseClient*>(layer);
+    if (lbc) {
+        mLayerMap.add(lbc->serverIndex(), lbc);
+    }
+    mRemovedLayers.remove(layer);
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::removeLayer_l(LayerBase* layerBase)
+{
+    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
+    if (index >= 0) {
+        mRemovedLayers.add(layerBase);
+        LayerBaseClient* layer = LayerBase::dynamicCast<LayerBaseClient*>(layerBase);
+        if (layer) {
+            mLayerMap.removeItem(layer->serverIndex());
+        }
+        return NO_ERROR;
+    }
+    // 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 destroySurface,
+    // destroyclient and destroySurface-from-a-transaction.
+    return (index == NAME_NOT_FOUND) ? status_t(NO_ERROR) : index;
+}
+
+void SurfaceFlinger::free_resources_l()
+{
+    // Destroy layers that were removed
+    destroy_all_removed_layers_l();
+
+    // free resources associated with disconnected clients
+    SortedVector<Client*>& scheduledBroadcasts(mScheduledBroadcasts);
+    Vector<Client*>& disconnectedClients(mDisconnectedClients);
+    const size_t count = disconnectedClients.size();
+    for (size_t i=0 ; i<count ; i++) {
+        Client* client = disconnectedClients[i];
+        // if this client is the scheduled broadcast list,
+        // remove it from there (and we don't need to signal it
+        // since it is dead).
+        int32_t index = scheduledBroadcasts.indexOf(client);
+        if (index >= 0) {
+            scheduledBroadcasts.removeItemsAt(index);
+        }
+        mTokens.release(client->cid);
+        delete client;
+    }
+    disconnectedClients.clear();
+}
+
+void SurfaceFlinger::destroy_all_removed_layers_l()
+{
+    size_t c = mRemovedLayers.size();
+    while (c--) {
+        LayerBase* const removed_layer = mRemovedLayers[c];
+
+        LOGE_IF(mCurrentState.layersSortedByZ.indexOf(removed_layer) >= 0,
+            "layer %p removed but still in the current state list",
+            removed_layer);
+
+        delete removed_layer;
+    }
+    mRemovedLayers.clear();
+}
+
+
+uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
+{
+    return android_atomic_and(~flags, &mTransactionFlags) & flags;
+}
+
+uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, nsecs_t delay)
+{
+    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
+    if ((old & flags)==0) { // wake the server up
+        if (delay > 0) {
+            signalDelayedEvent(delay);
+        } else {
+            signalEvent();
+        }
+    }
+    return old;
+}
+
+void SurfaceFlinger::openGlobalTransaction()
+{
+    android_atomic_inc(&mTransactionCount);
+}
+
+void SurfaceFlinger::closeGlobalTransaction()
+{
+    if (android_atomic_dec(&mTransactionCount) == 1) {
+        signalEvent();
+    }
+}
+
+status_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
+{
+    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+        return BAD_VALUE;
+
+    Mutex::Autolock _l(mStateLock);
+    mCurrentState.freezeDisplay = 1;
+    setTransactionFlags(eTransactionNeeded);
+
+    // flags is intended to communicate some sort of animation behavior
+    // (for instance fadding)
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
+{
+    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+        return BAD_VALUE;
+
+    Mutex::Autolock _l(mStateLock);
+    mCurrentState.freezeDisplay = 0;
+    setTransactionFlags(eTransactionNeeded);
+
+    // flags is intended to communicate some sort of animation behavior
+    // (for instance fadding)
+    return NO_ERROR;
+}
+
+int SurfaceFlinger::setOrientation(DisplayID dpy, int orientation)
+{
+    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+        return BAD_VALUE;
+
+    Mutex::Autolock _l(mStateLock);
+    if (mCurrentState.orientation != orientation) {
+        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
+            mCurrentState.orientation = orientation;
+            setTransactionFlags(eTransactionNeeded);
+            mTransactionCV.wait(mStateLock);
+        } else {
+            orientation = BAD_VALUE;
+        }
+    }
+    return orientation;
+}
+
+sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
+        ISurfaceFlingerClient::surface_data_t* params,
+        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
+        uint32_t flags)
+{
+    LayerBaseClient* layer = 0;
+    sp<LayerBaseClient::Surface> surfaceHandle;
+    Mutex::Autolock _l(mStateLock);
+    Client* const c = mClientsMap.valueFor(clientId);
+    if (UNLIKELY(!c)) {
+        LOGE("createSurface() failed, client not found (id=%d)", clientId);
+        return surfaceHandle;
+    }
+
+    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
+    int32_t id = c->generateId(pid);
+    if (uint32_t(id) >= NUM_LAYERS_MAX) {
+        LOGE("createSurface() failed, generateId = %d", id);
+        return surfaceHandle;
+    }
+
+    switch (flags & eFXSurfaceMask) {
+        case eFXSurfaceNormal:
+            if (UNLIKELY(flags & ePushBuffers)) {
+                layer = createPushBuffersSurfaceLocked(c, d, id, w, h, flags);
+            } else {
+                layer = createNormalSurfaceLocked(c, d, id, w, h, format, flags);
+            }
+            break;
+        case eFXSurfaceBlur:
+            layer = createBlurSurfaceLocked(c, d, id, w, h, flags);
+            break;
+        case eFXSurfaceDim:
+            layer = createDimSurfaceLocked(c, d, id, w, h, flags);
+            break;
+    }
+
+    if (layer) {
+        setTransactionFlags(eTransactionNeeded);
+        surfaceHandle = layer->getSurface();
+        if (surfaceHandle != 0)
+            surfaceHandle->getSurfaceData(params);
+    }
+
+    return surfaceHandle;
+}
+
+LayerBaseClient* SurfaceFlinger::createNormalSurfaceLocked(
+        Client* client, DisplayID display,
+        int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
+{
+    // initialize the surfaces
+    switch (format) { // TODO: take h/w into account
+    case PIXEL_FORMAT_TRANSPARENT:
+    case PIXEL_FORMAT_TRANSLUCENT:
+        format = PIXEL_FORMAT_RGBA_8888;
+        break;
+    case PIXEL_FORMAT_OPAQUE:
+        format = PIXEL_FORMAT_RGB_565;
+        break;
+    }
+
+    Layer* layer = new Layer(this, display, client, id);
+    status_t err = layer->setBuffers(client, w, h, format, flags);
+    if (LIKELY(err == NO_ERROR)) {
+        layer->initStates(w, h, flags);
+        addLayer_l(layer);
+    } else {
+        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
+        delete layer;
+        return 0;
+    }
+    return layer;
+}
+
+LayerBaseClient* SurfaceFlinger::createBlurSurfaceLocked(
+        Client* client, DisplayID display,
+        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
+{
+    LayerBlur* layer = new LayerBlur(this, display, client, id);
+    layer->initStates(w, h, flags);
+    addLayer_l(layer);
+    return layer;
+}
+
+LayerBaseClient* SurfaceFlinger::createDimSurfaceLocked(
+        Client* client, DisplayID display,
+        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
+{
+    LayerDim* layer = new LayerDim(this, display, client, id);
+    layer->initStates(w, h, flags);
+    addLayer_l(layer);
+    return layer;
+}
+
+LayerBaseClient* SurfaceFlinger::createPushBuffersSurfaceLocked(
+        Client* client, DisplayID display,
+        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
+{
+    LayerBuffer* layer = new LayerBuffer(this, display, client, id);
+    layer->initStates(w, h, flags);
+    addLayer_l(layer);
+    return layer;
+}
+
+status_t SurfaceFlinger::destroySurface(SurfaceID index)
+{
+    Mutex::Autolock _l(mStateLock);
+    LayerBaseClient* const layer = getLayerUser_l(index);
+    status_t err = removeLayer_l(layer);
+    if (err < 0)
+        return err;
+    setTransactionFlags(eTransactionNeeded);
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::setClientState(
+        ClientID cid,
+        int32_t count,
+        const layer_state_t* states)
+{
+    Mutex::Autolock _l(mStateLock);
+    uint32_t flags = 0;
+    cid <<= 16;
+    for (int i=0 ; i<count ; i++) {
+        const layer_state_t& s = states[i];
+        LayerBaseClient* layer = getLayerUser_l(s.surface | cid);
+        if (layer) {
+            const uint32_t what = s.what;
+            // check if it has been destroyed first
+            if (what & eDestroyed) {
+                if (removeLayer_l(layer) == NO_ERROR) {
+                    flags |= eTransactionNeeded;
+                    // we skip everything else... well, no, not really
+                    // we skip ONLY that transaction.
+                    continue;
+                }
+            }
+            if (what & ePositionChanged) {
+                if (layer->setPosition(s.x, s.y))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eLayerChanged) {
+                if (layer->setLayer(s.z)) {
+                    mCurrentState.layersSortedByZ.reorder(
+                            layer, &Layer::compareCurrentStateZ);
+                    // we need traversal (state changed)
+                    // AND transaction (list changed)
+                    flags |= eTransactionNeeded|eTraversalNeeded;
+                }
+            }
+            if (what & eSizeChanged) {
+                if (layer->setSize(s.w, s.h))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eAlphaChanged) {
+                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eMatrixChanged) {
+                if (layer->setMatrix(s.matrix))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eTransparentRegionChanged) {
+                if (layer->setTransparentRegionHint(s.transparentRegion))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eVisibilityChanged) {
+                if (layer->setFlags(s.flags, s.mask))
+                    flags |= eTraversalNeeded;
+            }
+        }
+    }
+    if (flags) {
+        setTransactionFlags(flags);
+    }
+    return NO_ERROR;
+}
+
+LayerBaseClient* SurfaceFlinger::getLayerUser_l(SurfaceID s) const
+{
+    return mLayerMap.valueFor(s);
+}
+
+void SurfaceFlinger::screenReleased(int dpy)
+{
+    // this may be called by a signal handler, we can't do too much in here
+    android_atomic_or(eConsoleReleased, &mConsoleSignals);
+    signalEvent();
+}
+
+void SurfaceFlinger::screenAcquired(int dpy)
+{
+    // this may be called by a signal handler, we can't do too much in here
+    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
+    signalEvent();
+}
+
+status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 1024;
+    char buffer[SIZE];
+    String8 result;
+    if (checkCallingPermission(
+            String16("android.permission.DUMP")) == false)
+    { // not allowed
+        snprintf(buffer, SIZE, "Permission Denial: "
+                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
+                IPCThreadState::self()->getCallingPid(),
+                IPCThreadState::self()->getCallingUid());
+        result.append(buffer);
+    } else {
+        Mutex::Autolock _l(mStateLock);
+        size_t s = mClientsMap.size();
+        char name[64];
+        for (size_t i=0 ; i<s ; i++) {
+            Client* client = mClientsMap.valueAt(i);
+            sprintf(name, "  Client (id=0x%08x)", client->cid);
+            client->dump(name);
+        }
+        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+        const size_t count = currentLayers.size();
+        for (size_t i=0 ; i<count ; i++) {
+            /*** LayerBase ***/
+            LayerBase const * const layer = currentLayers[i];
+            const Layer::State& s = layer->drawingState();
+            snprintf(buffer, SIZE,
+                    "+ %s %p\n"
+                    "      "
+                    "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
+                    "needsBlending=%1d, invalidate=%1d, "
+                    "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
+                    layer->getTypeID(), layer,
+                    s.z, layer->tx(), layer->ty(), s.w, s.h,
+                    layer->needsBlending(), layer->contentDirty,
+                    s.alpha, s.flags,
+                    s.transform[0], s.transform[1],
+                    s.transform[2], s.transform[3]);
+            result.append(buffer);
+            buffer[0] = 0;
+            /*** LayerBaseClient ***/
+            LayerBaseClient* const lbc =
+                LayerBase::dynamicCast<LayerBaseClient*>((LayerBase*)layer);
+            if (lbc) {
+                snprintf(buffer, SIZE,
+                        "      "
+                        "id=0x%08x, client=0x%08x, identity=%u\n",
+                        lbc->clientIndex(), lbc->client ? lbc->client->cid : 0,
+                        lbc->getIdentity());
+            }
+            result.append(buffer);
+            buffer[0] = 0;
+            /*** Layer ***/
+            Layer* const l = LayerBase::dynamicCast<Layer*>((LayerBase*)layer);
+            if (l) {
+                const LayerBitmap& buf0(l->getBuffer(0));
+                const LayerBitmap& buf1(l->getBuffer(1));
+                snprintf(buffer, SIZE,
+                        "      "
+                        "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u], mTextureName=%d,"
+                        " freezeLock=%p, swapState=0x%08x\n",
+                        l->pixelFormat(),
+                        buf0.width(), buf0.height(), buf0.stride(),
+                        buf1.width(), buf1.height(), buf1.stride(),
+                        l->getTextureName(), l->getFreezeLock().get(),
+                        l->lcblk->swapState);
+            }
+            result.append(buffer);
+            buffer[0] = 0;
+            s.transparentRegion.dump(result, "transparentRegion");
+            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
+            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
+        }
+        mWormholeRegion.dump(result, "WormholeRegion");
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+        snprintf(buffer, SIZE,
+                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
+                mFreezeDisplay?"yes":"no", mFreezeCount,
+                mCurrentState.orientation, hw.canDraw());
+        result.append(buffer);
+
+        sp<AllocatorInterface> allocator;
+        if (mGPU != 0) {
+            snprintf(buffer, SIZE, "  GPU owner: %d\n", mGPU->getOwner());
+            result.append(buffer);
+            allocator = mGPU->getAllocator();
+            if (allocator != 0) {
+                allocator->dump(result, "GPU Allocator");
+            }
+        }
+        allocator = mSurfaceHeapManager->getAllocator(NATIVE_MEMORY_TYPE_PMEM);
+        if (allocator != 0) {
+            allocator->dump(result, "PMEM Allocator");
+        }
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case CREATE_CONNECTION:
+        case OPEN_GLOBAL_TRANSACTION:
+        case CLOSE_GLOBAL_TRANSACTION:
+        case SET_ORIENTATION:
+        case FREEZE_DISPLAY:
+        case UNFREEZE_DISPLAY:
+        case BOOT_FINISHED:
+        case REVOKE_GPU:
+        {
+            // codes that require permission check
+            IPCThreadState* ipc = IPCThreadState::self();
+            const int pid = ipc->getCallingPid();
+            const int self_pid = getpid();
+            if (UNLIKELY(pid != self_pid)) {
+                // we're called from a different process, do the real check
+                if (!checkCallingPermission(
+                        String16("android.permission.ACCESS_SURFACE_FLINGER")))
+                {
+                    const int uid = ipc->getCallingUid();
+                    LOGE("Permission Denial: "
+                            "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
+                    return PERMISSION_DENIED;
+                }
+            }
+        }
+    }
+
+    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
+    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
+        // HARDWARE_TEST stuff...
+        if (UNLIKELY(checkCallingPermission(
+                String16("android.permission.HARDWARE_TEST")) == false))
+        { // not allowed
+            LOGE("Permission Denial: pid=%d, uid=%d\n",
+                    IPCThreadState::self()->getCallingPid(),
+                    IPCThreadState::self()->getCallingUid());
+            return PERMISSION_DENIED;
+        }
+        int n;
+        switch (code) {
+            case 1000: // SHOW_CPU
+                n = data.readInt32();
+                mDebugCpu = n ? 1 : 0;
+                if (mDebugCpu) {
+                    if (mCpuGauge == 0) {
+                        mCpuGauge = new CPUGauge(this, ms2ns(500));
+                    }
+                } else {
+                    if (mCpuGauge != 0) {
+                        mCpuGauge->requestExitAndWait();
+                        Mutex::Autolock _l(mDebugLock);
+                        mCpuGauge.clear();
+                    }
+                }
+                return NO_ERROR;
+            case 1001:  // SHOW_FPS
+                n = data.readInt32();
+                mDebugFps = n ? 1 : 0;
+                return NO_ERROR;
+            case 1002:  // SHOW_UPDATES
+                n = data.readInt32();
+                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
+                return NO_ERROR;
+            case 1003:  // SHOW_BACKGROUND
+                n = data.readInt32();
+                mDebugBackground = n ? 1 : 0;
+                return NO_ERROR;
+            case 1004:{ // repaint everything
+                Mutex::Autolock _l(mStateLock);
+                const DisplayHardware& hw(graphicPlane(0).displayHardware());
+                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
+                signalEvent();
+            }
+            return NO_ERROR;
+            case 1005: // ask GPU revoke
+                mGPU->friendlyRevoke();
+                return NO_ERROR;
+            case 1006: // revoke GPU
+                mGPU->unconditionalRevoke();
+                return NO_ERROR;
+            case 1007: // set mFreezeCount
+                mFreezeCount = data.readInt32();
+                return NO_ERROR;
+            case 1010:  // interrogate.
+                reply->writeInt32(mDebugCpu);
+                reply->writeInt32(0);
+                reply->writeInt32(mDebugRegion);
+                reply->writeInt32(mDebugBackground);
+                return NO_ERROR;
+            case 1013: {
+                Mutex::Autolock _l(mStateLock);
+                const DisplayHardware& hw(graphicPlane(0).displayHardware());
+                reply->writeInt32(hw.getPageFlipCount());
+            }
+            return NO_ERROR;
+        }
+    }
+    return err;
+}
+
+// ---------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
+    : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
+{
+    mSharedHeapAllocator = getSurfaceHeapManager()->createHeap();
+    const int pgsize = getpagesize();
+    const int cblksize=((sizeof(per_client_cblk_t)+(pgsize-1))&~(pgsize-1));
+    mCblkHeap = new MemoryDealer(cblksize);
+    mCblkMemory = mCblkHeap->allocate(cblksize);
+    if (mCblkMemory != 0) {
+        ctrlblk = static_cast<per_client_cblk_t *>(mCblkMemory->pointer());
+        if (ctrlblk) { // construct the shared structure in-place.
+            new(ctrlblk) per_client_cblk_t;
+        }
+    }
+}
+
+Client::~Client() {
+    if (ctrlblk) {
+        const int pgsize = getpagesize();
+        ctrlblk->~per_client_cblk_t();  // destroy our shared-structure.
+    }
+}
+
+const sp<SurfaceHeapManager>& Client::getSurfaceHeapManager() const {
+    return mFlinger->getSurfaceHeapManager();
+}
+
+int32_t Client::generateId(int pid)
+{
+    const uint32_t i = clz( ~mBitmap );
+    if (i >= NUM_LAYERS_MAX) {
+        return NO_MEMORY;
+    }
+    mPid = pid;
+    mInUse.add(uint8_t(i));
+    mBitmap |= 1<<(31-i);
+    return i;
+}
+status_t Client::bindLayer(LayerBaseClient* layer, int32_t id)
+{
+    ssize_t idx = mInUse.indexOf(id);
+    if (idx < 0)
+        return NAME_NOT_FOUND;
+    return mLayers.insertAt(layer, idx);
+}
+void Client::free(int32_t id)
+{
+    ssize_t idx = mInUse.remove(uint8_t(id));
+    if (idx >= 0) {
+        mBitmap &= ~(1<<(31-id));
+        mLayers.removeItemsAt(idx);
+    }
+}
+
+sp<MemoryDealer> Client::createAllocator(uint32_t flags)
+{
+    sp<MemoryDealer> allocator;
+    allocator = getSurfaceHeapManager()->createHeap(
+            flags, getClientPid(), mSharedHeapAllocator);
+    return allocator;
+}
+
+bool Client::isValid(int32_t i) const {
+    return (uint32_t(i)<NUM_LAYERS_MAX) && (mBitmap & (1<<(31-i)));
+}
+const uint8_t* Client::inUseArray() const {
+    return mInUse.array();
+}
+size_t Client::numActiveLayers() const {
+    return mInUse.size();
+}
+LayerBaseClient* Client::getLayerUser(int32_t i) const {
+    ssize_t idx = mInUse.indexOf(uint8_t(i));
+    if (idx<0) return 0;
+    return mLayers[idx];
+}
+
+void Client::dump(const char* what)
+{
+}
+
+// ---------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp<IMemory>& cblk)
+    : mId(cid), mFlinger(flinger), mCblk(cblk)
+{
+}
+
+BClient::~BClient() {
+    // destroy all resources attached to this client
+    mFlinger->destroyConnection(mId);
+}
+
+void BClient::getControlBlocks(sp<IMemory>* ctrl) const {
+    *ctrl = mCblk;
+}
+
+sp<ISurface> BClient::createSurface(
+        ISurfaceFlingerClient::surface_data_t* params, int pid,
+        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
+        uint32_t flags)
+{
+    return mFlinger->createSurface(mId, pid, params, display, w, h, format, flags);
+}
+
+status_t BClient::destroySurface(SurfaceID sid)
+{
+    sid |= (mId << 16); // add the client-part to id
+    return mFlinger->destroySurface(sid);
+}
+
+status_t BClient::setState(int32_t count, const layer_state_t* states)
+{
+    return mFlinger->setClientState(mId, count, states);
+}
+
+// ---------------------------------------------------------------------------
+
+GraphicPlane::GraphicPlane()
+    : mHw(0)
+{
+}
+
+GraphicPlane::~GraphicPlane() {
+    delete mHw;
+}
+
+bool GraphicPlane::initialized() const {
+    return mHw ? true : false;
+}
+
+void GraphicPlane::setDisplayHardware(DisplayHardware *hw) {
+    mHw = hw;
+}
+
+void GraphicPlane::setTransform(const Transform& tr) {
+    mTransform = tr;
+    mGlobalTransform = mOrientationTransform * mTransform;
+}
+
+status_t GraphicPlane::orientationToTransfrom(
+        int orientation, int w, int h, Transform* tr)
+{    
+    float a, b, c, d, x, y;
+    switch (orientation) {
+    case ISurfaceComposer::eOrientationDefault:
+        a=1; b=0; c=0; d=1; x=0; y=0;
+        break;
+    case ISurfaceComposer::eOrientation90:
+        a=0; b=-1; c=1; d=0; x=w; y=0;
+        break;
+    case ISurfaceComposer::eOrientation180:
+        a=-1; b=0; c=0; d=-1; x=w; y=h;
+        break;
+    case ISurfaceComposer::eOrientation270:
+        a=0; b=1; c=-1; d=0; x=0; y=h;
+        break;
+    default:
+        return BAD_VALUE;
+    }
+    tr->set(a, b, c, d);
+    tr->set(x, y);
+    return NO_ERROR;
+}
+
+status_t GraphicPlane::setOrientation(int orientation)
+{
+    const DisplayHardware& hw(displayHardware());
+    const float w = hw.getWidth();
+    const float h = hw.getHeight();
+
+    if (orientation == ISurfaceComposer::eOrientationDefault) {
+        // make sure the default orientation is optimal
+        mOrientationTransform.reset();
+        mGlobalTransform = mTransform;
+        return NO_ERROR;
+    }
+
+    // If the rotation can be handled in hardware, this is where
+    // the magic should happen.
+    if (UNLIKELY(orientation == 42)) {
+        float a, b, c, d, x, y;
+        const float r = (3.14159265f / 180.0f) * 42.0f;
+        const float si = sinf(r);
+        const float co = cosf(r);
+        a=co; b=-si; c=si; d=co;
+        x = si*(h*0.5f) + (1-co)*(w*0.5f);
+        y =-si*(w*0.5f) + (1-co)*(h*0.5f);
+        mOrientationTransform.set(a, b, c, d);
+        mOrientationTransform.set(x, y);
+    } else {
+        GraphicPlane::orientationToTransfrom(orientation, w, h,
+                &mOrientationTransform);
+    }
+    
+    mGlobalTransform = mOrientationTransform * mTransform;
+    return NO_ERROR;
+}
+
+const DisplayHardware& GraphicPlane::displayHardware() const {
+    return *mHw;
+}
+
+const Transform& GraphicPlane::transform() const {
+    return mGlobalTransform;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
new file mode 100644
index 0000000..f7d7764
--- /dev/null
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -0,0 +1,435 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_SURFACE_FLINGER_H
+#define ANDROID_SURFACE_FLINGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/SortedVector.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/MemoryDealer.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/ISurfaceComposer.h>
+#include <ui/ISurfaceFlingerClient.h>
+
+#include <private/ui/SharedState.h>
+#include <private/ui/LayerState.h>
+#include <private/ui/SurfaceFlingerSynchro.h>
+
+#include "Barrier.h"
+#include "BootAnimation.h"
+#include "CPUGauge.h"
+#include "Layer.h"
+#include "Tokenizer.h"
+
+struct copybit_device_t;
+struct overlay_device_t;
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class Client;
+class BClient;
+class DisplayHardware;
+class FreezeLock;
+class GPUHardwareInterface;
+class IGPUCallback;
+class Layer;
+class LayerBuffer;
+class LayerOrientationAnim;
+class OrientationAnimation;
+class SurfaceHeapManager;
+
+typedef int32_t ClientID;
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ---------------------------------------------------------------------------
+
+class Client
+{
+public:
+            Client(ClientID cid, const sp<SurfaceFlinger>& flinger);
+            ~Client();
+
+            int32_t                 generateId(int pid);
+            void                    free(int32_t id);
+            status_t                bindLayer(LayerBaseClient* layer, int32_t id);
+            sp<MemoryDealer>        createAllocator(uint32_t memory_type);
+
+    inline  bool                    isValid(int32_t i) const;
+    inline  const uint8_t*          inUseArray() const;
+    inline  size_t                  numActiveLayers() const;
+    LayerBaseClient*                getLayerUser(int32_t i) const;
+    const Vector<LayerBaseClient*>& getLayers() const { return mLayers; }
+    const sp<IMemory>&              controlBlockMemory() const { return mCblkMemory; }
+    void                            dump(const char* what);
+    const sp<SurfaceHeapManager>&   getSurfaceHeapManager() const;
+    
+    // pointer to this client's control block
+    per_client_cblk_t*      ctrlblk;
+    ClientID                cid;
+
+    
+private:
+    int                     getClientPid() const { return mPid; }
+        
+    int                         mPid;
+    uint32_t                    mBitmap;
+    SortedVector<uint8_t>       mInUse;
+    Vector<LayerBaseClient*>    mLayers;
+    sp<MemoryDealer>            mCblkHeap;
+    sp<SurfaceFlinger>          mFlinger;
+    sp<MemoryDealer>            mSharedHeapAllocator;
+    sp<MemoryDealer>            mPMemAllocator;
+    sp<IMemory>                 mCblkMemory;
+};
+
+// ---------------------------------------------------------------------------
+
+class GraphicPlane
+{
+public:
+    static status_t orientationToTransfrom(int orientation, int w, int h,
+            Transform* tr);
+
+                                GraphicPlane();
+                                ~GraphicPlane();
+
+        bool                    initialized() const;
+
+        void                    setDisplayHardware(DisplayHardware *);
+        void                    setTransform(const Transform& tr);
+        status_t                setOrientation(int orientation);
+
+        const DisplayHardware&  displayHardware() const;
+        const Transform&        transform() const;
+private:
+                                GraphicPlane(const GraphicPlane&);
+        GraphicPlane            operator = (const GraphicPlane&);
+
+        DisplayHardware*        mHw;
+        Transform               mTransform;
+        Transform               mOrientationTransform;
+        Transform               mGlobalTransform;
+};
+
+// ---------------------------------------------------------------------------
+
+enum {
+    eTransactionNeeded      = 0x01,
+    eTraversalNeeded        = 0x02
+};
+
+class SurfaceFlinger : public BnSurfaceComposer, protected Thread
+{
+public:
+    static void instantiate();
+    static void shutdown();
+
+                    SurfaceFlinger();
+    virtual         ~SurfaceFlinger();
+            void    init();
+
+    virtual status_t onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+
+    virtual status_t dump(int fd, const Vector<String16>& args);
+
+    // ISurfaceComposer interface
+    virtual sp<ISurfaceFlingerClient>   createConnection();
+    virtual sp<IMemory>                 getCblk() const;
+    virtual void                        bootFinished();
+    virtual void                        openGlobalTransaction();
+    virtual void                        closeGlobalTransaction();
+    virtual status_t                    freezeDisplay(DisplayID dpy, uint32_t flags);
+    virtual status_t                    unfreezeDisplay(DisplayID dpy, uint32_t flags);
+    virtual int                         setOrientation(DisplayID dpy, int orientation);
+    virtual void                        signal() const;
+    virtual status_t requestGPU(const sp<IGPUCallback>& callback, 
+            gpu_info_t* gpu);
+    virtual status_t revokeGPU();
+
+            void                        screenReleased(DisplayID dpy);
+            void                        screenAcquired(DisplayID dpy);
+
+            const sp<SurfaceHeapManager>& getSurfaceHeapManager() const { 
+                return mSurfaceHeapManager; 
+            }
+
+            const sp<GPUHardwareInterface>& getGPU() const {
+                return mGPU; 
+            }
+
+            copybit_device_t* getBlitEngine() const;
+            overlay_control_device_t* getOverlayEngine() const;
+
+            
+    status_t removeLayer(LayerBase* layer);
+    status_t addLayer(LayerBase* layer);
+    status_t invalidateLayerVisibility(LayerBase* layer);
+    
+private:
+    friend class BClient;
+    friend class LayerBase;
+    friend class LayerBuffer;
+    friend class LayerBaseClient;
+    friend class Layer;
+    friend class LayerBlur;
+
+    sp<ISurface> createSurface(ClientID client, int pid, 
+            ISurfaceFlingerClient::surface_data_t* params,
+            DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
+            uint32_t flags);
+
+    LayerBaseClient* createNormalSurfaceLocked(Client* client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
+
+    LayerBaseClient* createBlurSurfaceLocked(Client* client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
+
+    LayerBaseClient* createDimSurfaceLocked(Client* client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
+
+    LayerBaseClient* createPushBuffersSurfaceLocked(Client* client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
+
+    status_t    destroySurface(SurfaceID surface_id);
+    status_t    setClientState(ClientID cid, int32_t count, const layer_state_t* states);
+
+
+    class LayerVector {
+    public:
+        inline              LayerVector() { }
+                            LayerVector(const LayerVector&);
+        inline size_t       size() const { return layers.size(); }
+        inline LayerBase*const* array() const { return layers.array(); }
+        ssize_t             add(LayerBase*, Vector<LayerBase*>::compar_t);
+        ssize_t             remove(LayerBase*);
+        ssize_t             reorder(LayerBase*, Vector<LayerBase*>::compar_t);
+        ssize_t             indexOf(LayerBase* key, size_t guess=0) const;
+        inline LayerBase*   operator [] (size_t i) const { return layers[i]; }
+    private:
+        KeyedVector<LayerBase*, size_t> lookup;
+        Vector<LayerBase*>              layers;
+    };
+
+    struct State {
+        State() {
+            orientation = ISurfaceComposer::eOrientationDefault;
+            freezeDisplay = 0;
+        }
+        LayerVector     layersSortedByZ;
+        uint8_t         orientation;
+        uint8_t         freezeDisplay;
+    };
+
+    class DelayedTransaction : public Thread
+    {
+        friend class SurfaceFlinger;
+        sp<SurfaceFlinger>  mFlinger;
+        nsecs_t             mDelay;
+    public:
+        DelayedTransaction(const sp<SurfaceFlinger>& flinger, nsecs_t delay)
+            : Thread(false), mFlinger(flinger), mDelay(delay) {
+        }
+        virtual bool threadLoop() {
+            usleep(mDelay / 1000);
+            if (android_atomic_and(~1,
+                    &mFlinger->mDeplayedTransactionPending) == 1) {
+                mFlinger->signalEvent();
+            }
+            return false;
+        }
+    };
+
+    virtual bool        threadLoop();
+    virtual status_t    readyToRun();
+    virtual void        onFirstRef();
+
+    const GraphicPlane&     graphicPlane(int dpy) const;
+          GraphicPlane&     graphicPlane(int dpy);
+
+            void        waitForEvent();
+            void        signalEvent();
+            void        signalDelayedEvent(nsecs_t delay);
+
+            void        handleConsoleEvents();
+            void        handleTransaction(uint32_t transactionFlags);
+
+            void        computeVisibleRegions(
+                            LayerVector& currentLayers,
+                            Region& dirtyRegion,
+                            Region& wormholeRegion);
+
+            void        handlePageFlip();
+            bool        lockPageFlip(const LayerVector& currentLayers);
+            void        unlockPageFlip(const LayerVector& currentLayers);
+            void        handleRepaint();
+            void        handleDebugCpu();
+            void        scheduleBroadcast(Client* client);
+            void        executeScheduledBroadcasts();
+            void        postFramebuffer();
+            void        composeSurfaces(const Region& dirty);
+            void        unlockClients();
+
+
+            void        destroyConnection(ClientID cid);
+            LayerBaseClient* getLayerUser_l(SurfaceID index) const;
+            status_t    addLayer_l(LayerBase* layer);
+            status_t    removeLayer_l(LayerBase* layer);
+            void        destroy_all_removed_layers_l();
+            void        free_resources_l();
+
+            uint32_t    getTransactionFlags(uint32_t flags);
+            uint32_t    setTransactionFlags(uint32_t flags, nsecs_t delay = 0);
+            void        commitTransaction();
+
+
+            friend class FreezeLock;
+            sp<FreezeLock> getFreezeLock() const;
+            inline void incFreezeCount() { mFreezeCount++; }
+            inline void decFreezeCount() { if (mFreezeCount > 0) mFreezeCount--; }
+            inline bool hasFreezeRequest() const { return mFreezeDisplay; }
+            inline bool isFrozen() const { 
+                return mFreezeDisplay || mFreezeCount>0;
+            }
+
+            
+            void        debugFlashRegions();
+            void        debugShowFPS() const;
+            void        drawWormhole() const;
+           
+                // access must be protected by mStateLock
+    mutable     Mutex                   mStateLock;
+                State                   mCurrentState;
+                State                   mDrawingState;
+    volatile    int32_t                 mTransactionFlags;
+    volatile    int32_t                 mTransactionCount;
+                Condition               mTransactionCV;
+
+                // protected by mStateLock (but we could use another lock)
+                Tokenizer                               mTokens;
+                DefaultKeyedVector<ClientID, Client*>   mClientsMap;
+                DefaultKeyedVector<SurfaceID, LayerBaseClient*>   mLayerMap;
+                GraphicPlane                            mGraphicPlanes[1];
+                SortedVector<LayerBase*>                mRemovedLayers;
+                Vector<Client*>                         mDisconnectedClients;
+
+                // constant members (no synchronization needed for access)
+                sp<MemoryDealer>            mServerHeap;
+                sp<IMemory>                 mServerCblkMemory;
+                surface_flinger_cblk_t*     mServerCblk;
+                sp<SurfaceHeapManager>      mSurfaceHeapManager;
+                sp<GPUHardwareInterface>    mGPU;
+                GLuint                      mWormholeTexName;
+                sp<BootAnimation>           mBootAnimation;
+                nsecs_t                     mBootTime;
+                
+                // Can only accessed from the main thread, these members
+                // don't need synchronization
+                Region                      mDirtyRegion;
+                Region                      mInvalidRegion;
+                Region                      mWormholeRegion;
+                Client*                     mLastScheduledBroadcast;
+                SortedVector<Client*>       mScheduledBroadcasts;
+                bool                        mVisibleRegionsDirty;
+                bool                        mDeferReleaseConsole;
+                bool                        mFreezeDisplay;
+                int32_t                     mFreezeCount;
+                nsecs_t                     mFreezeDisplayTime;
+                friend class OrientationAnimation;
+                OrientationAnimation*       mOrientationAnimation;
+
+                // access protected by mDebugLock
+    mutable     Mutex                       mDebugLock;
+                sp<CPUGauge>                mCpuGauge;
+
+                // don't use a lock for these, we don't care
+                int                         mDebugRegion;
+                int                         mDebugCpu;
+                int                         mDebugFps;
+                int                         mDebugBackground;
+                int                         mDebugNoBootAnimation;
+
+                // these are thread safe
+    mutable     Barrier                     mReadyToRunBarrier;
+    mutable     SurfaceFlingerSynchro       mSyncObject;
+    volatile    int32_t                     mDeplayedTransactionPending;
+
+                // atomic variables
+                enum {
+                    eConsoleReleased = 1,
+                    eConsoleAcquired = 2
+                };
+   volatile     int32_t                     mConsoleSignals;
+
+   // only written in the main thread, only read in other threads
+   volatile     int32_t                     mSecureFrameBuffer;
+};
+
+// ---------------------------------------------------------------------------
+
+class FreezeLock : public LightRefBase<FreezeLock> {
+    SurfaceFlinger* mFlinger;
+public:
+    FreezeLock(SurfaceFlinger* flinger)
+        : mFlinger(flinger) {
+        mFlinger->incFreezeCount();
+    }
+    ~FreezeLock() {
+        mFlinger->decFreezeCount();
+    }
+};
+
+// ---------------------------------------------------------------------------
+
+class BClient : public BnSurfaceFlingerClient
+{
+public:
+    BClient(SurfaceFlinger *flinger, ClientID cid,
+            const sp<IMemory>& cblk);
+    ~BClient();
+
+    // ISurfaceFlingerClient interface
+    virtual void getControlBlocks(sp<IMemory>* ctrl) const;
+
+    virtual sp<ISurface> createSurface(
+            surface_data_t* params, int pid,
+            DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
+            uint32_t flags);
+
+    virtual status_t destroySurface(SurfaceID surfaceId);
+    virtual status_t setState(int32_t count, const layer_state_t* states);
+
+private:
+    ClientID            mId;
+    SurfaceFlinger*     mFlinger;
+    sp<IMemory>         mCblk;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_SURFACE_FLINGER_H
diff --git a/libs/surfaceflinger/Tokenizer.cpp b/libs/surfaceflinger/Tokenizer.cpp
new file mode 100644
index 0000000..ef51d6a
--- /dev/null
+++ b/libs/surfaceflinger/Tokenizer.cpp
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include "Tokenizer.h"
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+ANDROID_BASIC_TYPES_TRAITS(Tokenizer::run_t)
+
+Tokenizer::Tokenizer()
+{
+}
+
+Tokenizer::Tokenizer(const Tokenizer& other)
+    : mRanges(other.mRanges)
+{
+}
+
+Tokenizer::~Tokenizer()
+{
+}
+
+uint32_t Tokenizer::acquire()
+{
+    if (!mRanges.size() || mRanges[0].first) {
+        _insertTokenAt(0,0);
+        return 0;
+    }
+    
+    // just extend the first run
+    const run_t& run = mRanges[0];
+    uint32_t token = run.first + run.length;
+    _insertTokenAt(token, 1);
+    return token;
+}
+
+bool Tokenizer::isAcquired(uint32_t token) const
+{
+    return (_indexOrderOf(token) >= 0);
+}
+
+status_t Tokenizer::reserve(uint32_t token)
+{
+    size_t o;
+    const ssize_t i = _indexOrderOf(token, &o);
+    if (i >= 0) {
+        return BAD_VALUE; // this token is already taken
+    }
+    ssize_t err = _insertTokenAt(token, o);
+    return (err<0) ? err : status_t(NO_ERROR);
+}
+
+status_t Tokenizer::release(uint32_t token)
+{
+    const ssize_t i = _indexOrderOf(token);
+    if (i >= 0) {
+        const run_t& run = mRanges[i];
+        if ((token >= run.first) && (token < run.first+run.length)) {
+            // token in this range, we need to split
+            run_t& run = mRanges.editItemAt(i);
+            if ((token == run.first) || (token == run.first+run.length-1)) {
+                if (token == run.first) {
+                    run.first += 1;
+                }
+                run.length -= 1;
+                if (run.length == 0) {
+                    // XXX: should we systematically remove a run that's empty?
+                    mRanges.removeItemsAt(i);
+                }
+            } else {
+                // split the run
+                run_t new_run;
+                new_run.first = token+1;
+                new_run.length = run.first+run.length - new_run.first;
+                run.length = token - run.first;
+                mRanges.insertAt(new_run, i+1);
+            }
+            return NO_ERROR;
+        }
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t Tokenizer::_indexOrderOf(uint32_t token, size_t* order) const
+{
+    // binary search
+    ssize_t err = NAME_NOT_FOUND;
+    ssize_t l = 0;
+    ssize_t h = mRanges.size()-1;
+    ssize_t mid;
+    const run_t* a = mRanges.array();
+    while (l <= h) {
+        mid = l + (h - l)/2;
+        const run_t* const curr = a + mid;
+        int c = 0;
+        if (token < curr->first)                        c = 1;
+        else if (token >= curr->first+curr->length)     c = -1;
+        if (c == 0) {
+            err = l = mid;
+            break;
+        } else if (c < 0) {
+            l = mid + 1;
+        } else {
+            h = mid - 1;
+        }
+    }
+    if (order) *order = l;
+    return err;
+}
+
+ssize_t Tokenizer::_insertTokenAt(uint32_t token, size_t index)
+{
+    const size_t c = mRanges.size();
+
+    if (index >= 1) {
+        // do we need to merge with the previous run?
+        run_t& p = mRanges.editItemAt(index-1);
+        if (p.first+p.length == token) {
+            p.length += 1;
+            if (index < c) {
+                const run_t& n = mRanges[index];
+                if (token+1 == n.first) {
+                    p.length += n.length;
+                    mRanges.removeItemsAt(index);
+                }
+            }
+            return index;
+        }
+    }
+    
+    if (index < c) {
+        // do we need to merge with the next run?
+        run_t& n = mRanges.editItemAt(index);
+        if (token+1 == n.first) {
+            n.first -= 1;
+            n.length += 1;
+            return index;
+        }
+    }
+
+    return mRanges.insertAt(run_t(token,1), index);
+}
+
+void Tokenizer::dump() const
+{
+    const run_t* ranges = mRanges.array();
+    const size_t c = mRanges.size();
+    printf("Tokenizer (%p, size = %lu)\n", this, c);
+    for (size_t i=0 ; i<c ; i++) {
+        printf("%lu: (%u, %u)\n", i, ranges[i].first, ranges[i].length);
+    }
+}
+
+}; // namespace android
+
diff --git a/libs/surfaceflinger/Tokenizer.h b/libs/surfaceflinger/Tokenizer.h
new file mode 100644
index 0000000..6b3057d
--- /dev/null
+++ b/libs/surfaceflinger/Tokenizer.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_TOKENIZER_H
+#define ANDROID_TOKENIZER_H
+
+#include <utils/Vector.h>
+#include <utils/Errors.h>
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+class Tokenizer
+{
+public:
+                Tokenizer();
+                Tokenizer(const Tokenizer& other);
+                ~Tokenizer();
+
+    uint32_t    acquire();
+    status_t    reserve(uint32_t token);
+    status_t    release(uint32_t token);
+    bool        isAcquired(uint32_t token) const;
+
+    void dump() const;
+
+    struct run_t {
+        run_t() {};
+        run_t(uint32_t f, uint32_t l) : first(f), length(l) {}
+        uint32_t    first;
+        uint32_t    length;
+    };
+private:
+    ssize_t _indexOrderOf(uint32_t token, size_t* order=0) const;
+    ssize_t _insertTokenAt(uint32_t token, size_t index);
+    Vector<run_t>   mRanges;
+};
+
+}; // namespace android
+
+// ----------------------------------------------------------------------------
+
+#endif // ANDROID_TOKENIZER_H
diff --git a/libs/surfaceflinger/Transform.cpp b/libs/surfaceflinger/Transform.cpp
new file mode 100644
index 0000000..bec7a64
--- /dev/null
+++ b/libs/surfaceflinger/Transform.cpp
@@ -0,0 +1,204 @@
+/*
+ * 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.
+ */
+
+#include <ui/Region.h>
+
+#include <private/pixelflinger/ggl_fixed.h>
+
+#include "Transform.h"
+
+// ---------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+Transform::Transform()
+    : mType(0)
+{
+    mTransform.reset();
+}
+
+Transform::Transform(const Transform&  other)
+    : mTransform(other.mTransform), mType(other.mType)
+{
+}
+
+Transform::~Transform() {
+}
+
+Transform Transform::operator * (const Transform& rhs) const
+{
+    if (LIKELY(mType == 0))
+        return rhs;
+
+    Transform r(*this);
+    r.mTransform.preConcat(rhs.mTransform);
+    r.mType |= rhs.mType;
+    return r;
+}
+
+float Transform::operator [] (int i) const
+{
+    float r = 0;
+    switch(i) {
+        case 0: r = SkScalarToFloat( mTransform[SkMatrix::kMScaleX] );  break;
+        case 1: r = SkScalarToFloat( mTransform[SkMatrix::kMSkewX] );   break;
+        case 2: r = SkScalarToFloat( mTransform[SkMatrix::kMSkewY] );   break;
+        case 3: r = SkScalarToFloat( mTransform[SkMatrix::kMScaleY] );  break;
+    }
+    return r;
+}
+
+uint8_t Transform::type() const
+{
+    if (UNLIKELY(mType & 0x80000000)) {
+        mType = mTransform.getType();
+    }
+    return uint8_t(mType & 0xFF);
+}
+
+bool Transform::transformed() const {
+    return type() > SkMatrix::kTranslate_Mask;
+}
+
+int Transform::tx() const {
+    return SkScalarRound( mTransform[SkMatrix::kMTransX] );
+}
+
+int Transform::ty() const {
+    return SkScalarRound( mTransform[SkMatrix::kMTransY] );
+}
+
+void Transform::reset() {
+    mTransform.reset();
+    mType = 0;
+}
+
+void Transform::set( float xx, float xy,
+                     float yx, float yy)
+{
+    mTransform.set(SkMatrix::kMScaleX, SkFloatToScalar(xx));
+    mTransform.set(SkMatrix::kMSkewX, SkFloatToScalar(xy));
+    mTransform.set(SkMatrix::kMSkewY, SkFloatToScalar(yx));
+    mTransform.set(SkMatrix::kMScaleY, SkFloatToScalar(yy));
+    mType |= 0x80000000;
+}
+
+void Transform::set(int tx, int ty)
+{
+    if (tx | ty) {
+        mTransform.set(SkMatrix::kMTransX, SkIntToScalar(tx));
+        mTransform.set(SkMatrix::kMTransY, SkIntToScalar(ty));
+        mType |= SkMatrix::kTranslate_Mask;
+    } else {
+        mTransform.set(SkMatrix::kMTransX, 0);
+        mTransform.set(SkMatrix::kMTransY, 0);
+        mType &= ~SkMatrix::kTranslate_Mask;
+    }
+}
+
+void Transform::transform(GLfixed* point, int x, int y) const
+{
+    SkPoint s;
+    mTransform.mapXY(SkIntToScalar(x), SkIntToScalar(y), &s);
+    point[0] = SkScalarToFixed(s.fX);
+    point[1] = SkScalarToFixed(s.fY);
+}
+
+Rect Transform::makeBounds(int w, int h) const
+{
+    Rect r;
+    SkRect d, s;
+    s.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
+    mTransform.mapRect(&d, s);
+    r.left   = SkScalarRound( d.fLeft );
+    r.top    = SkScalarRound( d.fTop );
+    r.right  = SkScalarRound( d.fRight );
+    r.bottom = SkScalarRound( d.fBottom );
+    return r;
+}
+
+Rect Transform::transform(const Rect& bounds) const
+{
+    Rect r;
+    SkRect d, s;
+    s.set(  SkIntToScalar( bounds.left ),
+            SkIntToScalar( bounds.top ),
+            SkIntToScalar( bounds.right ),
+            SkIntToScalar( bounds.bottom ));
+    mTransform.mapRect(&d, s);
+    r.left   = SkScalarRound( d.fLeft );
+    r.top    = SkScalarRound( d.fTop );
+    r.right  = SkScalarRound( d.fRight );
+    r.bottom = SkScalarRound( d.fBottom );
+    return r;
+}
+
+Region Transform::transform(const Region& reg) const
+{
+    Region out;
+    if (UNLIKELY(transformed())) {
+        if (LIKELY(preserveRects())) {
+            Rect r;
+            Region::iterator iterator(reg);
+            while (iterator.iterate(&r)) {
+                out.orSelf(transform(r));
+            }
+        } else {
+            out.set(transform(reg.bounds()));
+        }
+    } else {
+        out = reg.translate(tx(), ty());
+    }
+    return out;
+}
+
+int32_t Transform::getOrientation() const
+{
+    uint32_t flags = 0;
+    if (UNLIKELY(transformed())) {
+        SkScalar a = mTransform[SkMatrix::kMScaleX];
+        SkScalar b = mTransform[SkMatrix::kMSkewX];
+        SkScalar c = mTransform[SkMatrix::kMSkewY];
+        SkScalar d = mTransform[SkMatrix::kMScaleY];
+        if (b==0 && c==0 && a && d) {
+            if (a<0)    flags |= FLIP_H;
+            if (d<0)    flags |= FLIP_V;
+        } else if (b && c && a==0 && d==0) {
+            flags |= ROT_90;
+            if (b>0)    flags |= FLIP_H;
+            if (c<0)    flags |= FLIP_V;
+        } else {
+            flags = 0x80000000;
+        }
+    }
+    return flags;
+}
+
+bool Transform::preserveRects() const
+{
+    return mTransform.rectStaysRect();
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h
new file mode 100644
index 0000000..0b4835e
--- /dev/null
+++ b/libs/surfaceflinger/Transform.h
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_TRANSFORM_H
+#define ANDROID_TRANSFORM_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <ui/Point.h>
+#include <ui/Rect.h>
+
+#include <GLES/gl.h>
+
+#include <core/SkMatrix.h>
+
+namespace android {
+
+class Region;
+
+// ---------------------------------------------------------------------------
+
+class Transform
+{
+public:
+                    Transform();
+                    Transform(const Transform&  other);
+                    ~Transform();
+
+            enum orientation_flags {
+                ROT_0   = 0x00000000,
+                FLIP_H  = 0x00000001,
+                FLIP_V  = 0x00000002,
+                ROT_90  = 0x00000004,
+                ROT_180 = FLIP_H|FLIP_V,
+                ROT_270 = ROT_180|ROT_90,
+                ROT_INVALID = 0x80000000
+            };
+
+            bool    transformed() const;
+            int32_t getOrientation() const;
+            bool    preserveRects() const;
+            
+            int     tx() const;
+            int     ty() const;
+        
+            void    reset();
+            void    set(float xx, float xy, float yx, float yy);
+            void    set(int tx, int ty);
+
+            Rect    makeBounds(int w, int h) const;
+            void    transform(GLfixed* point, int x, int y) const;
+            Region  transform(const Region& reg) const;
+            Rect    transform(const Rect& bounds) const;
+
+            Transform operator * (const Transform& rhs) const;
+            float operator [] (int i) const;
+
+    inline uint32_t getType() const { return type(); }
+            
+    inline Transform(bool) : mType(0xFF) { };
+
+private:
+    uint8_t     type() const;
+
+private:
+            SkMatrix    mTransform;
+    mutable uint32_t    mType;      
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif /* ANDROID_TRANSFORM_H */
diff --git a/libs/surfaceflinger/VRamHeap.cpp b/libs/surfaceflinger/VRamHeap.cpp
new file mode 100644
index 0000000..0ccd71f
--- /dev/null
+++ b/libs/surfaceflinger/VRamHeap.cpp
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <utils/MemoryDealer.h>
+#include <utils/MemoryBase.h>
+#include <utils/MemoryHeapPmem.h>
+#include <utils/MemoryHeapBase.h>
+
+#include "GPUHardware/GPUHardware.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+/*
+ * Amount of memory we reserve for surface, per client in PMEM
+ * (PMEM is used for 2D acceleration)
+ * 8 MB of address space per client should be enough.
+ */
+static const int PMEM_SIZE = int(8 * 1024 * 1024);
+
+int SurfaceHeapManager::global_pmem_heap = 0;
+
+// ---------------------------------------------------------------------------
+
+SurfaceHeapManager::SurfaceHeapManager(const sp<SurfaceFlinger>& flinger, 
+        size_t clientHeapSize)
+    : mFlinger(flinger), mClientHeapSize(clientHeapSize)
+{
+    SurfaceHeapManager::global_pmem_heap = 1;
+}
+
+SurfaceHeapManager::~SurfaceHeapManager()
+{
+}
+
+void SurfaceHeapManager::onFirstRef()
+{
+    if (global_pmem_heap) {
+        const char* device = "/dev/pmem";
+        mPMemHeap = new PMemHeap(device, PMEM_SIZE);
+        if (mPMemHeap->base() == MAP_FAILED) {
+            mPMemHeap.clear();
+            global_pmem_heap = 0;
+        }
+    }
+}
+
+sp<MemoryDealer> SurfaceHeapManager::createHeap(
+        uint32_t flags,
+        pid_t client_pid,
+        const sp<MemoryDealer>& defaultAllocator)
+{
+    sp<MemoryDealer> dealer; 
+
+    if (flags & ISurfaceComposer::eGPU) {
+        // don't grant GPU memory if GPU is disabled
+        char value[PROPERTY_VALUE_MAX];
+        property_get("debug.egl.hw", value, "1");
+        if (atoi(value) == 0) {
+            flags &= ~ISurfaceComposer::eGPU;
+        }
+    }
+
+    if (flags & ISurfaceComposer::eGPU) {
+        // FIXME: this is msm7201A specific, where gpu surfaces may not be secure
+        if (!(flags & ISurfaceComposer::eSecure)) {
+            // if GPU doesn't work, we try eHardware
+            flags |= ISurfaceComposer::eHardware;
+            // asked for GPU memory, try that first
+            dealer = mFlinger->getGPU()->request(client_pid);
+        }
+    }
+
+    if (dealer == NULL) {
+        if (defaultAllocator != NULL)
+            // if a default allocator is given, use that
+            dealer = defaultAllocator;
+    }
+    
+    if (dealer == NULL) {
+        // always try h/w accelerated memory first
+        if (global_pmem_heap) {
+            const sp<PMemHeap>& heap(mPMemHeap);
+            if (dealer == NULL && heap != NULL) {
+                dealer = new MemoryDealer( 
+                        heap->createClientHeap(),
+                        heap->getAllocator());
+            }
+        }
+    }
+
+    if (dealer == NULL) {
+        // return the ashmem allocator (software rendering)
+        dealer = new MemoryDealer(mClientHeapSize, 0, "SFNativeHeap");
+    }
+    return dealer;
+}
+
+sp<SimpleBestFitAllocator> SurfaceHeapManager::getAllocator(int type) const 
+{
+    Mutex::Autolock _l(mLock);
+    sp<SimpleBestFitAllocator> allocator;
+
+    // this is only used for debugging
+    switch (type) {
+        case NATIVE_MEMORY_TYPE_PMEM:
+            if (mPMemHeap != 0) {
+                allocator = mPMemHeap->getAllocator();
+            }
+            break;
+    }
+    return allocator;
+}
+
+// ---------------------------------------------------------------------------
+
+PMemHeap::PMemHeap(const char* const device, size_t size, size_t reserved)
+    : MemoryHeapBase(device, size)
+{
+    //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
+    if (base() != MAP_FAILED) {
+        //LOGD("%s, %u bytes", device, virtualSize());
+        if (reserved == 0)
+            reserved = virtualSize();
+        mAllocator = new SimpleBestFitAllocator(reserved);
+    }
+}
+
+PMemHeap::~PMemHeap() {
+    //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
+}
+
+sp<MemoryHeapPmem> PMemHeap::createClientHeap() {
+    sp<MemoryHeapBase> parentHeap(this);
+    return new MemoryHeapPmem(parentHeap);
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/surfaceflinger/VRamHeap.h b/libs/surfaceflinger/VRamHeap.h
new file mode 100644
index 0000000..9140167
--- /dev/null
+++ b/libs/surfaceflinger/VRamHeap.h
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_VRAM_HEAP_H
+#define ANDROID_VRAM_HEAP_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/MemoryDealer.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class PMemHeap;
+class MemoryHeapPmem;
+class SurfaceFlinger; 
+
+// ---------------------------------------------------------------------------
+
+class SurfaceHeapManager  : public RefBase
+{
+public:
+    SurfaceHeapManager(const sp<SurfaceFlinger>& flinger, size_t clientHeapSize);
+    virtual ~SurfaceHeapManager();
+    virtual void onFirstRef();
+    /* use ISurfaceComposer flags eGPU|eHArdware|eSecure */
+    sp<MemoryDealer> createHeap(uint32_t flags=0, pid_t client_pid = 0,
+            const sp<MemoryDealer>& defaultAllocator = 0);
+    
+    // used for debugging only...
+    sp<SimpleBestFitAllocator> getAllocator(int type) const;
+
+private:
+    sp<PMemHeap> getHeap(int type) const;
+
+    sp<SurfaceFlinger> mFlinger;
+    mutable Mutex   mLock;
+    size_t          mClientHeapSize;
+    sp<PMemHeap>    mPMemHeap;
+    static int global_pmem_heap;
+};
+
+// ---------------------------------------------------------------------------
+
+class PMemHeap : public MemoryHeapBase
+{
+public:
+                PMemHeap(const char* const vram,
+                        size_t size=0, size_t reserved=0);
+    virtual     ~PMemHeap();
+    
+    virtual const sp<SimpleBestFitAllocator>& getAllocator() const {
+        return mAllocator; 
+    }
+    virtual sp<MemoryHeapPmem> createClientHeap();
+    
+private:
+    sp<SimpleBestFitAllocator>  mAllocator;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_VRAM_HEAP_H
diff --git a/libs/surfaceflinger/clz.cpp b/libs/surfaceflinger/clz.cpp
new file mode 100644
index 0000000..2456b86
--- /dev/null
+++ b/libs/surfaceflinger/clz.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#include "clz.h"
+
+namespace android {
+
+int clz_impl(int32_t x)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    return __builtin_clz(x);
+#else
+    if (!x) return 32;
+    int e = 31;
+    if (x&0xFFFF0000)   { e -=16; x >>=16; }
+    if (x&0x0000FF00)   { e -= 8; x >>= 8; }
+    if (x&0x000000F0)   { e -= 4; x >>= 4; }
+    if (x&0x0000000C)   { e -= 2; x >>= 2; }
+    if (x&0x00000002)   { e -= 1; }
+    return e;
+#endif
+}
+
+}; // namespace android
diff --git a/libs/surfaceflinger/clz.h b/libs/surfaceflinger/clz.h
new file mode 100644
index 0000000..0ddf986
--- /dev/null
+++ b/libs/surfaceflinger/clz.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_SURFACE_FLINGER_CLZ_H
+
+#include <stdint.h>
+
+namespace android {
+
+int clz_impl(int32_t x);
+
+int inline clz(int32_t x)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    return __builtin_clz(x);
+#else
+    return clz_impl(x);
+#endif
+}
+
+
+}; // namespace android
+
+#endif /* ANDROID_SURFACE_FLINGER_CLZ_H */
diff --git a/libs/surfaceflinger/tests/Android.mk b/libs/surfaceflinger/tests/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/libs/surfaceflinger/tests/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/libs/surfaceflinger/tests/overlays/Android.mk b/libs/surfaceflinger/tests/overlays/Android.mk
new file mode 100644
index 0000000..dc47e45
--- /dev/null
+++ b/libs/surfaceflinger/tests/overlays/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	overlays.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+    libui
+
+LOCAL_MODULE:= test-overlays
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/libs/surfaceflinger/tests/overlays/overlays.cpp b/libs/surfaceflinger/tests/overlays/overlays.cpp
new file mode 100644
index 0000000..f3c046f
--- /dev/null
+++ b/libs/surfaceflinger/tests/overlays/overlays.cpp
@@ -0,0 +1,58 @@
+#include <utils/IPCThreadState.h>
+#include <utils/ProcessState.h>
+#include <utils/IServiceManager.h>
+#include <utils/Log.h>
+
+#include <ui/Surface.h>
+#include <ui/ISurface.h>
+#include <ui/Overlay.h>
+#include <ui/SurfaceComposerClient.h>
+
+using namespace android;
+
+namespace android {
+class Test {
+public:
+    static const sp<ISurface>& getISurface(const sp<Surface>& s) {
+        return s->getISurface();
+    }
+};
+};
+
+int main(int argc, char** argv)
+{
+    // set up the thread-pool
+    sp<ProcessState> proc(ProcessState::self());
+    ProcessState::self()->startThreadPool();
+
+    // create a client to surfaceflinger
+    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
+    
+    // create pushbuffer surface
+    sp<Surface> surface = client->createSurface(getpid(), 0, 320, 240, 
+            PIXEL_FORMAT_UNKNOWN, ISurfaceComposer::ePushBuffers);
+
+    // get to the isurface
+    sp<ISurface> isurface = Test::getISurface(surface);
+    printf("isurface = %p\n", isurface.get());
+    
+    // now request an overlay
+    sp<OverlayRef> ref = isurface->createOverlay(320, 240, PIXEL_FORMAT_RGB_565);
+    sp<Overlay> overlay = new Overlay(ref);
+    
+
+    /*
+     * here we can use the overlay API 
+     */
+    
+    overlay_buffer_t buffer; 
+    overlay->dequeueBuffer(&buffer);
+    printf("buffer = %p\n", buffer);
+    
+    void* address = overlay->getBufferAddress(buffer);
+    printf("address = %p\n", address);
+
+    overlay->queueBuffer(buffer);
+
+    return 0;
+}
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
new file mode 100644
index 0000000..f944357
--- /dev/null
+++ b/libs/ui/Android.mk
@@ -0,0 +1,41 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	Camera.cpp \
+	CameraParameters.cpp \
+	EGLDisplaySurface.cpp \
+	EGLNativeWindowSurface.cpp \
+	EventHub.cpp \
+	EventRecurrence.cpp \
+	KeyLayoutMap.cpp \
+	KeyCharacterMap.cpp \
+	ICamera.cpp \
+	ICameraClient.cpp \
+	ICameraService.cpp \
+	IOverlay.cpp \
+	ISurfaceComposer.cpp \
+	ISurface.cpp \
+	ISurfaceFlingerClient.cpp \
+	LayerState.cpp \
+	Overlay.cpp \
+	PixelFormat.cpp \
+	Point.cpp \
+	Rect.cpp \
+	Region.cpp \
+	Surface.cpp \
+	SurfaceComposerClient.cpp \
+	SurfaceFlingerSynchro.cpp \
+	Time.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcorecg \
+	libcutils \
+	libutils \
+	libpixelflinger \
+	libhardware \
+	libhardware_legacy
+
+LOCAL_MODULE:= libui
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
new file mode 100644
index 0000000..b3cbda1
--- /dev/null
+++ b/libs/ui/Camera.cpp
@@ -0,0 +1,408 @@
+/*
+**
+** Copyright (C) 2008, The Android Open Source Project
+** Copyright (C) 2008 HTC Inc.
+**
+** 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_NDEBUG 0
+#define LOG_TAG "Camera"
+#include <utils/Log.h>
+#include <utils/IServiceManager.h>
+#include <utils/threads.h>
+#include <utils/IMemory.h>
+#include <ui/Surface.h>
+#include <ui/Camera.h>
+#include <ui/ICameraService.h>
+
+namespace android {
+
+// client singleton for camera service binder interface
+Mutex Camera::mLock;
+sp<ICameraService> Camera::mCameraService;
+sp<Camera::DeathNotifier> Camera::mDeathNotifier;
+
+// establish binder interface to camera service
+const sp<ICameraService>& Camera::getCameraService()
+{
+    Mutex::Autolock _l(mLock);
+    if (mCameraService.get() == 0) {
+        sp<IServiceManager> sm = defaultServiceManager();
+        sp<IBinder> binder;
+        do {
+            binder = sm->getService(String16("media.camera"));
+            if (binder != 0)
+                break;
+            LOGW("CameraService not published, waiting...");
+            usleep(500000); // 0.5 s
+        } while(true);
+        if (mDeathNotifier == NULL) {
+            mDeathNotifier = new DeathNotifier();
+        }
+        binder->linkToDeath(mDeathNotifier);
+        mCameraService = interface_cast<ICameraService>(binder);
+    }
+    LOGE_IF(mCameraService==0, "no CameraService!?");
+    return mCameraService;
+}
+
+// ---------------------------------------------------------------------------
+
+Camera::Camera()
+{
+    init();
+}
+
+Camera::Camera(const sp<ICamera>& camera)
+{
+    init();
+    // connect this client to existing camera remote
+    if (camera->connect(this) == NO_ERROR) {
+        mStatus = NO_ERROR;
+        mCamera = camera;
+        camera->asBinder()->linkToDeath(this);
+    }
+}
+
+void Camera::init()
+{
+    mStatus = UNKNOWN_ERROR;
+    mShutterCallback = 0;
+    mShutterCallbackCookie = 0;
+    mRawCallback = 0;
+    mRawCallbackCookie = 0;
+    mJpegCallback = 0;
+    mJpegCallbackCookie = 0;
+    mPreviewCallback = 0;
+    mPreviewCallbackCookie = 0;
+    mRecordingCallback = 0;
+    mRecordingCallbackCookie = 0;
+    mErrorCallback = 0;
+    mErrorCallbackCookie = 0;
+    mAutoFocusCallback = 0;
+    mAutoFocusCallbackCookie = 0;
+}
+
+Camera::~Camera()
+{
+    disconnect();
+}
+
+sp<Camera> Camera::connect()
+{
+    LOGV("connect");
+    sp<Camera> c = new Camera();
+    const sp<ICameraService>& cs = getCameraService();
+    if (cs != 0) {
+        c->mCamera = cs->connect(c);
+    }
+    if (c->mCamera != 0) {
+        c->mCamera->asBinder()->linkToDeath(c);
+        c->mStatus = NO_ERROR;
+    } else {
+        c.clear();
+    }
+    return c;
+}
+
+void Camera::disconnect()
+{
+    LOGV("disconnect");
+    if (mCamera != 0) {
+        mErrorCallback = 0;
+        mCamera->disconnect();
+        mCamera = 0;
+    }
+}
+
+status_t Camera::reconnect()
+{
+    LOGV("reconnect");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->connect(this);
+}
+
+sp<ICamera> Camera::remote()
+{
+    return mCamera;
+}
+
+status_t Camera::lock()
+{
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->lock();
+}
+
+status_t Camera::unlock()
+{
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->unlock();
+}
+
+// pass the buffered ISurface to the camera service
+status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
+{
+    LOGV("setPreviewDisplay");
+    if (surface == 0) {
+        LOGE("app passed NULL surface");
+        return NO_INIT;
+    }
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->setPreviewDisplay(surface->getISurface());
+}
+
+status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
+{
+    LOGV("setPreviewDisplay");
+    if (surface == 0) {
+        LOGE("app passed NULL surface");
+        return NO_INIT;
+    }
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->setPreviewDisplay(surface);
+}
+
+
+// start preview mode, must call setPreviewDisplay first
+status_t Camera::startPreview()
+{
+    LOGV("startPreview");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->startPreview();
+}
+
+// start recording mode, must call setPreviewDisplay first
+status_t Camera::startRecording()
+{
+    LOGV("startRecording");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->startRecording();
+}
+
+// stop preview mode
+void Camera::stopPreview()
+{
+    LOGV("stopPreview");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return;
+    c->stopPreview();
+}
+
+// stop recording mode
+void Camera::stopRecording()
+{
+    LOGV("stopRecording");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return;
+    c->stopRecording();
+}
+
+// release a recording frame
+void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
+{
+    LOGV("releaseRecordingFrame");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return;
+    c->releaseRecordingFrame(mem);
+}
+
+// get preview state
+bool Camera::previewEnabled()
+{
+    LOGV("previewEnabled");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return false;
+    return c->previewEnabled();
+}
+
+// get recording state
+bool Camera::recordingEnabled()
+{
+    LOGV("recordingEnabled");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return false;
+    return c->recordingEnabled();
+}
+
+status_t Camera::autoFocus()
+{
+    LOGV("autoFocus");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->autoFocus();
+}
+
+// take a picture
+status_t Camera::takePicture()
+{
+    LOGV("takePicture");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->takePicture();
+}
+
+// set preview/capture parameters - key/value pairs
+status_t Camera::setParameters(const String8& params)
+{
+    LOGV("setParameters");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->setParameters(params);
+}
+
+// get preview/capture parameters - key/value pairs
+String8 Camera::getParameters() const
+{
+    LOGV("getParameters");
+    String8 params;
+    sp <ICamera> c = mCamera;
+    if (c != 0) params = mCamera->getParameters();
+    return params;
+}
+
+void Camera::setAutoFocusCallback(autofocus_callback cb, void *cookie)
+{
+    LOGV("setAutoFocusCallback");
+    mAutoFocusCallback = cb;
+    mAutoFocusCallbackCookie = cookie;
+}
+
+void Camera::setShutterCallback(shutter_callback cb, void *cookie)
+{
+    LOGV("setShutterCallback");
+    mShutterCallback = cb;
+    mShutterCallbackCookie = cookie;
+}
+
+void Camera::setRawCallback(frame_callback cb, void *cookie)
+{
+    LOGV("setRawCallback");
+    mRawCallback = cb;
+    mRawCallbackCookie = cookie;
+}
+
+void Camera::setJpegCallback(frame_callback cb, void *cookie)
+{
+    LOGV("setJpegCallback");
+    mJpegCallback = cb;
+    mJpegCallbackCookie = cookie;
+}
+
+void Camera::setPreviewCallback(frame_callback cb, void *cookie, int flag)
+{
+    LOGV("setPreviewCallback");
+    mPreviewCallback = cb;
+    mPreviewCallbackCookie = cookie;
+    sp <ICamera> c = mCamera;
+    if (c == 0) return;
+    mCamera->setPreviewCallbackFlag(flag);
+}
+
+void Camera::setRecordingCallback(frame_callback cb, void *cookie)
+{
+    LOGV("setRecordingCallback");
+    mRecordingCallback = cb;
+    mRecordingCallbackCookie = cookie;
+}
+
+void Camera::setErrorCallback(error_callback cb, void *cookie)
+{
+    LOGV("setErrorCallback");
+    mErrorCallback = cb;
+    mErrorCallbackCookie = cookie;
+}
+
+void Camera::autoFocusCallback(bool focused)
+{
+    LOGV("autoFocusCallback");
+    if (mAutoFocusCallback) {
+        mAutoFocusCallback(focused, mAutoFocusCallbackCookie);
+    }
+}
+
+void Camera::shutterCallback()
+{
+    LOGV("shutterCallback");
+    if (mShutterCallback) {
+        mShutterCallback(mShutterCallbackCookie);
+    }
+}
+
+void Camera::rawCallback(const sp<IMemory>& picture)
+{
+    LOGV("rawCallback");
+    if (mRawCallback) {
+        mRawCallback(picture, mRawCallbackCookie);
+    }
+}
+
+// callback from camera service when image is ready
+void Camera::jpegCallback(const sp<IMemory>& picture)
+{
+    LOGV("jpegCallback");
+    if (mJpegCallback) {
+        mJpegCallback(picture, mJpegCallbackCookie);
+    }
+}
+
+// callback from camera service when preview frame is ready
+void Camera::previewCallback(const sp<IMemory>& frame)
+{
+    LOGV("frameCallback");
+    if (mPreviewCallback) {
+        mPreviewCallback(frame, mPreviewCallbackCookie);
+    }
+}
+
+// callback from camera service when a recording frame is ready
+void Camera::recordingCallback(const sp<IMemory>& frame)
+{
+    LOGV("recordingCallback");
+    if (mRecordingCallback) {
+        mRecordingCallback(frame, mRecordingCallbackCookie);
+    }
+}
+
+// callback from camera service when an error occurs in preview or takePicture
+void Camera::errorCallback(status_t error)
+{
+    LOGV("errorCallback");
+    if (mErrorCallback) {
+        mErrorCallback(error, mErrorCallbackCookie);
+    }
+}
+
+void Camera::binderDied(const wp<IBinder>& who) {
+    LOGW("ICamera died");
+    if (mErrorCallback) {
+        mErrorCallback(DEAD_OBJECT, mErrorCallbackCookie);
+    }
+}
+
+void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
+    LOGV("binderDied");
+    Mutex::Autolock _l(Camera::mLock);
+    Camera::mCameraService.clear();
+    LOGW("Camera server died!");
+}
+
+}; // namespace android
+
diff --git a/libs/ui/CameraParameters.cpp b/libs/ui/CameraParameters.cpp
new file mode 100644
index 0000000..6c25836
--- /dev/null
+++ b/libs/ui/CameraParameters.cpp
@@ -0,0 +1,273 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     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 "CameraParams"
+#include <utils/Log.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <ui/CameraParameters.h>
+
+namespace android {
+
+static const char* portrait = "portrait";
+static const char* landscape = "landscape";
+
+CameraParameters::CameraParameters()
+                : mMap()
+{
+}
+
+CameraParameters::~CameraParameters()
+{
+}
+
+String8 CameraParameters::flatten() const
+{
+    String8 flattened("");
+    size_t size = mMap.size();
+
+    for (size_t i = 0; i < size; i++) {
+        String8 k, v;
+        k = mMap.keyAt(i);
+        v = mMap.valueAt(i);
+
+        flattened += k;
+        flattened += "=";
+        flattened += v;
+        if (i != size-1)
+            flattened += ";";
+    }
+
+    return flattened;
+}
+
+void CameraParameters::unflatten(const String8 &params)
+{
+    const char *a = params.string();
+    const char *b;
+
+    mMap.clear();
+
+    for (;;) {
+        // Find the bounds of the key name.
+        b = strchr(a, '=');
+        if (b == 0)
+            break;
+
+        // Create the key string.
+        String8 k(a, (size_t)(b-a));
+
+        // Find the value.
+        a = b+1;
+        b = strchr(a, ';');
+        if (b == 0) {
+            // If there's no semicolon, this is the last item.
+            String8 v(a);
+            mMap.add(k, v);
+            break;
+        }
+
+        String8 v(a, (size_t)(b-a));
+        mMap.add(k, v);
+        a = b+1;
+    }
+}
+
+
+void CameraParameters::set(const char *key, const char *value)
+{
+    // XXX i think i can do this with strspn() 
+    if (strchr(key, '=') || strchr(key, ';')) {
+        //XXX LOGE("Key \"%s\"contains invalid character (= or ;)", key);
+        return;
+    }
+
+    if (strchr(value, '=') || strchr(key, ';')) {
+        //XXX LOGE("Value \"%s\"contains invalid character (= or ;)", value);
+        return;
+    }
+
+    mMap.replaceValueFor(String8(key), String8(value));
+}
+
+void CameraParameters::set(const char *key, int value)
+{
+    char str[16];
+    sprintf(str, "%d", value);
+    set(key, str);
+}
+
+const char *CameraParameters::get(const char *key) const
+{
+    String8 v = mMap.valueFor(String8(key));
+    if (v.length() == 0)
+        return 0;
+    return v.string();
+}
+
+int CameraParameters::getInt(const char *key) const
+{
+    const char *v = get(key);
+    if (v == 0)
+        return -1;
+    return strtol(v, 0, 0);
+}
+
+static int parse_size(const char *str, int &width, int &height)
+{
+    // Find the width.
+    char *end;
+    int w = (int)strtol(str, &end, 10);
+    // If an 'x' does not immediately follow, give up.
+    if (*end != 'x')
+        return -1;
+
+    // Find the height, immediately after the 'x'.
+    int h = (int)strtol(end+1, 0, 10);
+
+    width = w;
+    height = h;
+
+    return 0;
+}
+
+void CameraParameters::setPreviewSize(int width, int height)
+{
+    char str[32];
+    sprintf(str, "%dx%d", width, height);
+    set("preview-size", str);
+}
+
+void CameraParameters::getPreviewSize(int *width, int *height) const
+{
+    *width = -1;
+    *height = -1;
+
+    // Get the current string, if it doesn't exist, leave the -1x-1
+    const char *p = get("preview-size");
+    if (p == 0)
+        return;
+
+    int w, h;
+    if (parse_size(p, w, h) == 0) {
+        *width = w;
+        *height = h;
+    }
+}
+
+void CameraParameters::setPreviewFrameRate(int fps)
+{
+    set("preview-frame-rate", fps);
+}
+
+int CameraParameters::getPreviewFrameRate() const
+{
+    return getInt("preview-frame-rate");
+}
+
+void CameraParameters::setPreviewFormat(const char *format)
+{
+    set("preview-format", format);
+}
+
+int CameraParameters::getOrientation() const
+{
+    const char* orientation = get("orientation");
+    if (orientation && !strcmp(orientation, portrait))
+        return CAMERA_ORIENTATION_PORTRAIT;
+    return CAMERA_ORIENTATION_LANDSCAPE;
+}
+
+void CameraParameters::setOrientation(int orientation)
+{
+    if (orientation == CAMERA_ORIENTATION_PORTRAIT) {
+        set("preview-format", portrait);
+    } else {
+        set("preview-format", landscape);
+    }
+}
+
+const char *CameraParameters::getPreviewFormat() const
+{
+    return get("preview-format");
+}
+
+void CameraParameters::setPictureSize(int width, int height)
+{
+    char str[32];
+    sprintf(str, "%dx%d", width, height);
+    set("picture-size", str);
+}
+
+void CameraParameters::getPictureSize(int *width, int *height) const
+{
+    *width = -1;
+    *height = -1;
+
+    // Get the current string, if it doesn't exist, leave the -1x-1
+    const char *p = get("picture-size");
+    if (p == 0)
+        return;
+
+    int w, h;
+    if (parse_size(p, w, h) == 0) {
+        *width = w;
+        *height = h;
+    }
+}
+
+void CameraParameters::setPictureFormat(const char *format)
+{
+    set("picture-format", format);
+}
+
+const char *CameraParameters::getPictureFormat() const
+{
+    return get("picture-format");
+}
+
+void CameraParameters::dump() const
+{
+    LOGD("dump: mMap.size = %d", mMap.size());
+    for (size_t i = 0; i < mMap.size(); i++) {
+        String8 k, v;
+        k = mMap.keyAt(i);
+        v = mMap.valueAt(i);
+        LOGD("%s: %s\n", k.string(), v.string());
+    }
+}
+
+status_t CameraParameters::dump(int fd, const Vector<String16>& args) const
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %d\n", mMap.size());
+    result.append(buffer);
+    for (size_t i = 0; i < mMap.size(); i++) {
+        String8 k, v;
+        k = mMap.keyAt(i);
+        v = mMap.valueAt(i);
+        snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string());
+        result.append(buffer);
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/libs/ui/EGLDisplaySurface.cpp b/libs/ui/EGLDisplaySurface.cpp
new file mode 100644
index 0000000..d06c98b
--- /dev/null
+++ b/libs/ui/EGLDisplaySurface.cpp
@@ -0,0 +1,519 @@
+/*
+ **
+ ** Copyright 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.
+ */
+
+#define LOG_TAG "EGLDisplaySurface"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <cutils/properties.h>
+
+#include <hardware/copybit.h>
+
+#include <ui/SurfaceComposerClient.h>
+#include <ui/DisplayInfo.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+#include <ui/EGLDisplaySurface.h>
+
+#if HAVE_ANDROID_OS
+#include <linux/msm_mdp.h>
+#endif
+
+#include <EGL/egl.h>
+
+#include <pixelflinger/format.h>
+
+
+// ----------------------------------------------------------------------------
+
+egl_native_window_t* android_createDisplaySurface()
+{
+    egl_native_window_t* s = new android::EGLDisplaySurface();
+    s->memory_type = NATIVE_MEMORY_TYPE_GPU;
+    return s;
+}
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+EGLDisplaySurface::EGLDisplaySurface()
+    : EGLNativeSurface<EGLDisplaySurface>()
+{
+    egl_native_window_t::version = sizeof(egl_native_window_t);
+    egl_native_window_t::ident = 0;
+    egl_native_window_t::incRef = &EGLDisplaySurface::hook_incRef;
+    egl_native_window_t::decRef = &EGLDisplaySurface::hook_decRef;
+    egl_native_window_t::swapBuffers = &EGLDisplaySurface::hook_swapBuffers;
+    egl_native_window_t::connect = 0;
+    egl_native_window_t::disconnect = 0;
+
+    mFb[0].data = 0;
+    mFb[1].data = 0;
+    mBlitEngine = 0;
+    egl_native_window_t::fd = mapFrameBuffer();
+    if (egl_native_window_t::fd >= 0) {
+        
+        hw_module_t const* module;
+        if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
+            copybit_open(module, &mBlitEngine);
+        }
+        
+        const float in2mm = 25.4f;
+        float refreshRate = 1000000000000000LLU / (
+                float( mInfo.upper_margin + mInfo.lower_margin + mInfo.yres )
+                * ( mInfo.left_margin  + mInfo.right_margin + mInfo.xres )
+                * mInfo.pixclock);
+
+        const GGLSurface& buffer = mFb[1 - mIndex];
+        egl_native_window_t::width  = buffer.width;
+        egl_native_window_t::height = buffer.height;
+        egl_native_window_t::stride = buffer.stride;
+        egl_native_window_t::format = buffer.format;
+        egl_native_window_t::base   = intptr_t(mFb[0].data);
+        egl_native_window_t::offset =
+            intptr_t(buffer.data) - egl_native_window_t::base;
+        egl_native_window_t::flags  = 0;
+        egl_native_window_t::xdpi = (mInfo.xres * in2mm) / mInfo.width;
+        egl_native_window_t::ydpi = (mInfo.yres * in2mm) / mInfo.height;
+        egl_native_window_t::fps  = refreshRate;
+        egl_native_window_t::memory_type = NATIVE_MEMORY_TYPE_FB;
+        // no error, set the magic word
+        egl_native_window_t::magic = 0x600913;
+    }
+    mSwapCount = -1;
+    mPageFlipCount = 0;
+}
+
+EGLDisplaySurface::~EGLDisplaySurface()
+{
+    magic = 0;
+    copybit_close(mBlitEngine);
+    mBlitEngine = 0;
+    close(egl_native_window_t::fd);
+    munmap(mFb[0].data, mSize);
+    if (!(mFlags & PAGE_FLIP))
+        free((void*)mFb[1].data);
+}
+
+void EGLDisplaySurface::hook_incRef(NativeWindowType window) {
+    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
+    that->incStrong(that);
+}
+void EGLDisplaySurface::hook_decRef(NativeWindowType window) {
+    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
+    that->decStrong(that);
+}
+uint32_t EGLDisplaySurface::hook_swapBuffers(NativeWindowType window) {
+    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
+    return that->swapBuffers();
+}
+
+void EGLDisplaySurface::setSwapRectangle(int l, int t, int w, int h)
+{
+    mInfo.reserved[0] = 0x54445055; // "UPDT";
+    mInfo.reserved[1] = (uint16_t)l | ((uint32_t)t << 16);
+    mInfo.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16);
+}
+
+uint32_t EGLDisplaySurface::swapBuffers()
+{
+#define SHOW_FPS 0
+#if SHOW_FPS
+    nsecs_t now = systemTime();
+    if (mSwapCount == -1) {
+        mTime = now;
+        mSwapCount = 0;
+        mSleep = 0;
+    } else {
+        nsecs_t d = now-mTime;
+        if (d >= seconds(1)) {
+            double fps = (mSwapCount * double(seconds(1))) / double(d);
+            LOGD("%f fps, sleep=%d / frame",
+                    fps, (int)ns2us(mSleep / mSwapCount));
+            mSwapCount = 0;
+            mTime = now;
+            mSleep = 0;
+        } else {
+            mSwapCount++;
+        }
+    }
+#endif
+    /* If we can't do the page_flip, just copy the back buffer to the front */
+    if (!(mFlags & PAGE_FLIP)) {
+        memcpy(mFb[0].data, mFb[1].data, mInfo.xres*mInfo.yres*2);
+        return 0;
+    }
+
+    // do the actual flip
+    mIndex = 1 - mIndex;
+    mInfo.activate = FB_ACTIVATE_VBL;
+    mInfo.yoffset = mIndex ? mInfo.yres : 0;
+    if (ioctl(egl_native_window_t::fd, FBIOPUT_VSCREENINFO, &mInfo) == -1) {
+        LOGE("FBIOPUT_VSCREENINFO failed");
+        return 0;
+    }
+
+    /*
+     * this is a monstrous hack: Because the h/w accelerator is not able
+     * to render directly into the framebuffer, we need to copy its
+     * internal framebuffer out to the fb.
+     * oem[0] is used to access the fd of internal fb.
+     * All this is needed only in standalone mode, in SurfaceFlinger mode
+     * we control where the GPU renders.
+     * We do this only if we have copybit, since this hack is needed only
+     * with msm7k.
+     */
+    if (egl_native_window_t::memory_type == NATIVE_MEMORY_TYPE_GPU && oem[0] && mBlitEngine) {
+        copybit_device_t *copybit = mBlitEngine;
+        copybit_rect_t sdrect = { 0, 0,
+                egl_native_window_t::width, egl_native_window_t::height };
+        copybit_image_t dst = {
+                egl_native_window_t::width,
+                egl_native_window_t::height,
+                egl_native_window_t::format,
+                egl_native_window_t::offset,
+                (void*)egl_native_window_t::base,
+                egl_native_window_t::fd
+        };
+        copybit_image_t src = {
+                egl_native_window_t::width,
+                egl_native_window_t::height,
+                egl_native_window_t::format, // XXX: use proper format
+                egl_native_window_t::offset,
+                (void*)egl_native_window_t::base,  // XXX: use proper base
+                egl_native_window_t::oem[0]
+        };
+        region_iterator it(Region(Rect(
+                egl_native_window_t::width, egl_native_window_t::height)));
+        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
+        copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
+        copybit->stretch(copybit, &dst, &src, &sdrect, &sdrect, &it);
+    }
+
+    // update the address of the buffer to draw to next
+    const GGLSurface& buffer = mFb[1 - mIndex];
+    egl_native_window_t::offset =
+        intptr_t(buffer.data) - egl_native_window_t::base;
+
+#if SHOW_FPS
+    mSleep += systemTime()-now;
+#endif
+
+    mPageFlipCount++;
+
+    // We don't support screen-size changes for now
+    return 0;
+}
+
+int32_t EGLDisplaySurface::getPageFlipCount() const
+{
+    return mPageFlipCount;
+}
+
+void EGLDisplaySurface::copyFrontToBack(const Region& copyback)
+{
+#if HAVE_ANDROID_OS
+    if (mBlitEngine) {
+        copybit_image_t dst = {
+                w:      egl_native_window_t::stride,
+                h:      egl_native_window_t::height,
+                format: egl_native_window_t::format,
+                offset: mFb[1-mIndex].data - mFb[0].data,
+                base:   (void*)egl_native_window_t::base,
+                fd:     egl_native_window_t::fd
+        };
+        copybit_image_t src = {
+                w:      egl_native_window_t::stride,
+                h:      egl_native_window_t::height,
+                format: egl_native_window_t::format,
+                offset: mFb[mIndex].data - mFb[0].data,
+                base:   (void*)egl_native_window_t::base,
+                fd:     egl_native_window_t::fd
+        };
+        region_iterator it(copyback);
+        mBlitEngine->blit(mBlitEngine, &dst, &src, &it);
+    } else
+#endif
+    {
+        /* no extra copy needed since we copied back to front instead of
+         * flipping */
+        if (!(mFlags & PAGE_FLIP)) {
+            return;
+        }
+
+        Region::iterator iterator(copyback);
+        if (iterator) {
+            Rect r;
+            uint8_t* const screen_src = mFb[  mIndex].data;
+            uint8_t* const screen_dst = mFb[1-mIndex].data;
+            const size_t bpp = bytesPerPixel(egl_native_window_t::format);
+            const size_t bpr = egl_native_window_t::stride * bpp;
+            while (iterator.iterate(&r)) {
+                ssize_t h = r.bottom - r.top;
+                if (h) {
+                    size_t size = (r.right - r.left) * bpp;
+                    size_t o = (r.left + egl_native_window_t::stride * r.top) * bpp;
+                    uint8_t* s = screen_src + o;
+                    uint8_t* d = screen_dst + o;
+                    if (size == bpr) {
+                        size *= h;
+                        h = 1;
+                    }
+                    do {
+                        memcpy(d, s, size);
+                        d += bpr;
+                        s += bpr;
+                    } while (--h > 0);
+                }
+            }
+        }
+    }
+}
+
+void EGLDisplaySurface::copyFrontToImage(const copybit_image_t& dst)
+{
+#if HAVE_ANDROID_OS
+    if (mBlitEngine) {
+        copybit_image_t src = {
+                w:      egl_native_window_t::stride,
+                h:      egl_native_window_t::height,
+                format: egl_native_window_t::format,
+                offset: mFb[mIndex].data - mFb[0].data,
+                base:   (void*)egl_native_window_t::base,
+                fd:     egl_native_window_t::fd
+        };
+        region_iterator it(Region(Rect(
+                egl_native_window_t::width, egl_native_window_t::height)));
+        mBlitEngine->blit(mBlitEngine, &dst, &src, &it);
+    } else
+#endif
+    {
+        uint8_t* const screen_src = mFb[  mIndex].data;
+        const size_t bpp = bytesPerPixel(egl_native_window_t::format);
+        const size_t bpr = egl_native_window_t::stride * bpp;
+        memcpy((char*)dst.base + dst.offset, screen_src,
+                bpr*egl_native_window_t::height);
+    }
+}
+
+void EGLDisplaySurface::copyBackToImage(const copybit_image_t& dst)
+{
+#if HAVE_ANDROID_OS
+    if (mBlitEngine) {
+        copybit_image_t src = {
+                w:      egl_native_window_t::stride,
+                h:      egl_native_window_t::height,
+                format: egl_native_window_t::format,
+                offset: mFb[1-mIndex].data - mFb[0].data,
+                base:   (void*)egl_native_window_t::base,
+                fd:     egl_native_window_t::fd
+        };
+        region_iterator it(Region(Rect(
+                egl_native_window_t::width, egl_native_window_t::height)));
+        mBlitEngine->blit(mBlitEngine, &dst, &src, &it);
+    } else
+#endif
+    {
+        uint8_t* const screen_src = mFb[1-mIndex].data;
+        const size_t bpp = bytesPerPixel(egl_native_window_t::format);
+        const size_t bpr = egl_native_window_t::stride * bpp;
+        memcpy((char*)dst.base + dst.offset, screen_src,
+                bpr*egl_native_window_t::height);
+    }
+}
+
+
+status_t EGLDisplaySurface::mapFrameBuffer()
+{
+    char const * const device_template[] = {
+            "/dev/graphics/fb%u",
+            "/dev/fb%u",
+            0 };
+    int fd = -1;
+    int i=0;
+    char name[64];
+    while ((fd==-1) && device_template[i]) {
+        snprintf(name, 64, device_template[i], 0);
+        fd = open(name, O_RDWR, 0);
+        i++;
+    }
+    if (fd < 0)
+        return -errno;
+
+    struct fb_fix_screeninfo finfo;
+    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
+        return -errno;
+
+    struct fb_var_screeninfo info;
+    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
+        return -errno;
+
+    info.reserved[0] = 0;
+    info.reserved[1] = 0;
+    info.reserved[2] = 0;
+    info.xoffset = 0;
+    info.yoffset = 0;
+    info.yres_virtual = info.yres * 2;
+    info.bits_per_pixel = 16;
+    /* Explicitly request 5/6/5 */
+    info.red.offset = 11;
+    info.red.length = 5;
+    info.green.offset = 5;
+    info.green.length = 6;
+    info.blue.offset = 0;
+    info.blue.length = 5;
+    info.transp.offset = 0;
+    info.transp.length = 0;
+    info.activate = FB_ACTIVATE_NOW;
+
+    uint32_t flags = PAGE_FLIP;
+    if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
+        info.yres_virtual = info.yres;
+        flags &= ~PAGE_FLIP;
+        LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
+    }
+
+    if (info.yres_virtual < info.yres * 2) {
+        info.yres_virtual = info.yres;
+        flags &= ~PAGE_FLIP;
+        LOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
+                info.yres_virtual, info.yres*2);
+    }
+
+    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
+        return -errno;
+
+    int refreshRate = 1000000000000000LLU /
+    (
+            uint64_t( info.upper_margin + info.lower_margin + info.yres )
+            * ( info.left_margin  + info.right_margin + info.xres )
+            * info.pixclock
+    );
+
+    if (refreshRate == 0) {
+        // bleagh, bad info from the driver
+        refreshRate = 60*1000;  // 60 Hz
+    }
+    if (int(info.width) <= 0 || int(info.height) <= 0) {
+        // the driver doesn't return that information
+        // default to 160 dpi
+        info.width  = ((info.xres * 25.4f)/160.0f + 0.5f);
+        info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
+    }
+
+    float xdpi = (info.xres * 25.4f) / info.width;
+    float ydpi = (info.yres * 25.4f) / info.height;
+    float fps  = refreshRate / 1000.0f;
+
+    LOGI(   "using (fd=%d)\n"
+            "id           = %s\n"
+            "xres         = %d px\n"
+            "yres         = %d px\n"
+            "xres_virtual = %d px\n"
+            "yres_virtual = %d px\n"
+            "bpp          = %d\n"
+            "r            = %2u:%u\n"
+            "g            = %2u:%u\n"
+            "b            = %2u:%u\n",
+            fd,
+            finfo.id,
+            info.xres,
+            info.yres,
+            info.xres_virtual,
+            info.yres_virtual,
+            info.bits_per_pixel,
+            info.red.offset, info.red.length,
+            info.green.offset, info.green.length,
+            info.blue.offset, info.blue.length
+    );
+
+    LOGI(   "width        = %d mm (%f dpi)\n"
+            "height       = %d mm (%f dpi)\n"
+            "refresh rate = %.2f Hz\n",
+            info.width,  xdpi,
+            info.height, ydpi,
+            fps
+    );
+
+
+    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
+        return -errno;
+
+    if (finfo.smem_len <= 0)
+        return -errno;
+
+    /*
+     * Open and map the display.
+     */
+
+    void* buffer  = (uint16_t*) mmap(
+            0, finfo.smem_len,
+            PROT_READ | PROT_WRITE,
+            MAP_SHARED,
+            fd, 0);
+
+    if (buffer == MAP_FAILED)
+        return -errno;
+
+    // at least for now, always clear the fb
+    memset(buffer, 0, finfo.smem_len);
+
+    uint8_t* offscreen[2];
+    offscreen[0] = (uint8_t*)buffer;
+    if (flags & PAGE_FLIP) {
+        offscreen[1] = (uint8_t*)buffer + finfo.line_length*info.yres;
+    } else {
+        offscreen[1] = (uint8_t*)malloc(finfo.smem_len);
+        if (offscreen[1] == 0) {
+            munmap(buffer, finfo.smem_len);
+            return NO_MEMORY;
+        }
+    }
+
+    mFlags = flags;
+    mInfo = info;
+    mFinfo = finfo;
+    mSize = finfo.smem_len;
+    mIndex = 0;
+    for (int i=0 ; i<2 ; i++) {
+        mFb[i].version = sizeof(GGLSurface);
+        mFb[i].width   = info.xres;
+        mFb[i].height  = info.yres;
+        mFb[i].stride  = finfo.line_length / (info.bits_per_pixel >> 3);
+        mFb[i].data    = (GGLubyte*)(offscreen[i]);
+        mFb[i].format  = GGL_PIXEL_FORMAT_RGB_565;
+    }
+    return fd;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
diff --git a/libs/ui/EGLNativeWindowSurface.cpp b/libs/ui/EGLNativeWindowSurface.cpp
new file mode 100644
index 0000000..f1071cf
--- /dev/null
+++ b/libs/ui/EGLNativeWindowSurface.cpp
@@ -0,0 +1,161 @@
+/* 
+**
+** Copyright 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.
+*/
+
+#define LOG_TAG "EGLNativeWindowSurface"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+
+#include <ui/SurfaceComposerClient.h>
+#include <ui/DisplayInfo.h>
+#include <ui/Rect.h>
+
+#include <EGL/egl.h>
+
+#include <pixelflinger/format.h>
+
+#include <ui/EGLNativeWindowSurface.h>
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+EGLNativeWindowSurface::EGLNativeWindowSurface(const sp<Surface>& surface)
+    : EGLNativeSurface<EGLNativeWindowSurface>(),
+    mSurface(surface), mConnected(false)
+{
+    egl_native_window_t::magic = 0x600913;
+    egl_native_window_t::version = sizeof(egl_native_window_t);
+    egl_native_window_t::ident = 0;
+    egl_native_window_t::incRef = &EGLNativeWindowSurface::hook_incRef;
+    egl_native_window_t::decRef = &EGLNativeWindowSurface::hook_decRef;
+    egl_native_window_t::swapBuffers = &EGLNativeWindowSurface::hook_swapBuffers;
+    egl_native_window_t::connect = &EGLNativeWindowSurface::hook_connect;
+    egl_native_window_t::disconnect = &EGLNativeWindowSurface::hook_disconnect;
+    
+    DisplayInfo dinfo;
+    SurfaceComposerClient::getDisplayInfo(0, &dinfo);
+    egl_native_window_t::xdpi = dinfo.xdpi;
+    egl_native_window_t::ydpi = dinfo.ydpi;
+    egl_native_window_t::fps  = dinfo.fps;
+    egl_native_window_t::flags= EGL_NATIVES_FLAG_DESTROY_BACKBUFFER;
+}
+
+EGLNativeWindowSurface::~EGLNativeWindowSurface()
+{
+    disconnect();
+    mSurface.clear();
+    magic = 0;
+}
+
+void EGLNativeWindowSurface::hook_incRef(NativeWindowType window)
+{
+    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+    that->incStrong(that);
+}
+
+void EGLNativeWindowSurface::hook_decRef(NativeWindowType window)
+{
+    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+    that->decStrong(that);
+}
+
+void EGLNativeWindowSurface::hook_connect(NativeWindowType window)
+{
+    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+    that->connect();
+}
+
+void EGLNativeWindowSurface::hook_disconnect(NativeWindowType window)
+{
+    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+    that->disconnect();
+}
+
+uint32_t EGLNativeWindowSurface::hook_swapBuffers(NativeWindowType window)
+{
+    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+    return that->swapBuffers();
+}
+
+void EGLNativeWindowSurface::setSwapRectangle(int l, int t, int w, int h)
+{
+    mSurface->setSwapRectangle(Rect(l, t, l+w, t+h));
+}
+
+uint32_t EGLNativeWindowSurface::swapBuffers()
+{
+    const int w = egl_native_window_t::width;
+    const int h = egl_native_window_t::height;
+    const sp<Surface>& surface(mSurface);
+    Surface::SurfaceInfo info;
+    surface->unlockAndPost();
+    surface->lock(&info);
+    // update the address of the buffer to draw to next
+    egl_native_window_t::base   = intptr_t(info.base);
+    egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
+    
+    // update size if it changed
+    if (w != int(info.w) || h != int(info.h)) {
+        egl_native_window_t::width  = info.w;
+        egl_native_window_t::height = info.h;
+        egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format);
+        egl_native_window_t::format = info.format;
+        return EGL_NATIVES_FLAG_SIZE_CHANGED;
+    }
+    return 0;
+}
+
+void EGLNativeWindowSurface::connect()
+{   
+    if (!mConnected) {
+        Surface::SurfaceInfo info;
+        mSurface->lock(&info);
+        mSurface->setSwapRectangle(Rect(info.w, info.h));
+        mConnected = true;
+
+        egl_native_window_t::width  = info.w;
+        egl_native_window_t::height = info.h;
+        egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format);
+        egl_native_window_t::format = info.format;
+        egl_native_window_t::base   = intptr_t(info.base);
+        egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
+        // FIXME: egl_native_window_t::memory_type used to be set from
+        // mSurface, but we wanted to break this dependency. We set it to
+        // GPU because the software rendered doesn't care, but the h/w
+        // accelerator needs it. Eventually, this value should go away
+        // completely, since memory will be managed by OpenGL.
+        egl_native_window_t::memory_type = NATIVE_MEMORY_TYPE_GPU; 
+        egl_native_window_t::fd = 0;
+    }
+}
+
+void EGLNativeWindowSurface::disconnect()
+{
+    if (mConnected) {
+        mSurface->unlock();
+        mConnected = false;
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
new file mode 100644
index 0000000..3b29b09
--- /dev/null
+++ b/libs/ui/EventHub.cpp
@@ -0,0 +1,793 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+// Handle events, like key input and vsync.
+//
+// The goal is to provide an optimized solution for Linux, not an
+// implementation that works well across all platforms.  We expect
+// events to arrive on file descriptors, so that we can use a select()
+// select() call to sleep.
+//
+// We can't select() on anything but network sockets in Windows, so we
+// provide an alternative implementation of waitEvent for that platform.
+//
+#define LOG_TAG "EventHub"
+
+//#define LOG_NDEBUG 0
+
+#include <ui/EventHub.h>
+#include <hardware_legacy/power.h>
+
+#include <cutils/properties.h>
+#include <utils/IServiceManager.h>
+#include <utils/Log.h>
+#include <utils/Timers.h>
+#include <utils.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "KeyLayoutMap.h"
+
+#include <string.h>
+#include <stdint.h>
+#include <dirent.h>
+#ifdef HAVE_INOTIFY
+# include <sys/inotify.h>
+#endif
+#ifdef HAVE_ANDROID_OS
+# include <sys/limits.h>        /* not part of Linux */
+#endif
+#include <sys/poll.h>
+#include <sys/ioctl.h>
+
+/* this macro is used to tell if "bit" is set in "array"
+ * it selects a byte from the array, and does a boolean AND
+ * operation with a byte that only has the relevant bit set.
+ * eg. to check for the 12th bit, we do (array[1] & 1<<4)
+ */
+#define test_bit(bit, array)    (array[bit/8] & (1<<(bit%8)))
+
+#define ID_MASK  0x0000ffff
+#define SEQ_MASK 0x7fff0000
+#define SEQ_SHIFT 16
+#define id_to_index(id)         ((id&ID_MASK)+1)
+
+namespace android {
+
+static const char *WAKE_LOCK_ID = "KeyEvents";
+static const char *device_path = "/dev/input";
+
+/* return the larger integer */
+static inline int max(int v1, int v2)
+{
+    return (v1 > v2) ? v1 : v2;
+}
+
+EventHub::device_t::device_t(int32_t _id, const char* _path)
+    : id(_id), path(_path), classes(0)
+    , keyBitmask(NULL), layoutMap(new KeyLayoutMap()), next(NULL) {
+}
+
+EventHub::device_t::~device_t() {
+    delete [] keyBitmask;
+    delete layoutMap;
+}
+
+EventHub::EventHub(void)
+    : mError(NO_INIT), mHaveFirstKeyboard(false), mFirstKeyboardId(0)
+    , mDevicesById(0), mNumDevicesById(0)
+    , mOpeningDevices(0), mClosingDevices(0)
+    , mDevices(0), mFDs(0), mFDCount(0)
+{
+    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+#ifdef EV_SW
+    memset(mSwitches, 0, sizeof(mSwitches));
+#endif
+}
+
+/*
+ * Clean up.
+ */
+EventHub::~EventHub(void)
+{
+    release_wake_lock(WAKE_LOCK_ID);
+    // we should free stuff here...
+}
+
+void EventHub::onFirstRef()
+{
+    mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR;
+}
+
+status_t EventHub::errorCheck() const
+{
+    return mError;
+}
+
+String8 EventHub::getDeviceName(int32_t deviceId) const
+{
+    AutoMutex _l(mLock);
+    device_t* device = getDevice(deviceId);
+    if (device == NULL) return String8();
+    return device->name;
+}
+
+uint32_t EventHub::getDeviceClasses(int32_t deviceId) const
+{
+    AutoMutex _l(mLock);
+    device_t* device = getDevice(deviceId);
+    if (device == NULL) return 0;
+    return device->classes;
+}
+
+int EventHub::getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
+        int* outMaxValue, int* outFlat, int* outFuzz) const
+{
+    AutoMutex _l(mLock);
+    device_t* device = getDevice(deviceId);
+    if (device == NULL) return -1;
+
+    struct input_absinfo info;
+
+    if(ioctl(mFDs[id_to_index(device->id)].fd, EVIOCGABS(axis), &info)) {
+        LOGE("Error reading absolute controller %d for device %s fd %d\n",
+             axis, device->name.string(), mFDs[id_to_index(device->id)].fd);
+        return -1;
+    }
+    *outMinValue = info.minimum;
+    *outMaxValue = info.maximum;
+    *outFlat = info.flat;
+    *outFuzz = info.fuzz;
+    return 0;
+}
+
+int EventHub::getSwitchState(int sw) const
+{
+#ifdef EV_SW
+    if (sw >= 0 && sw <= SW_MAX) {
+        int32_t devid = mSwitches[sw];
+        if (devid != 0) {
+            return getSwitchState(devid, sw);
+        }
+    }
+#endif
+    return -1;
+}
+
+int EventHub::getSwitchState(int32_t deviceId, int sw) const
+{
+#ifdef EV_SW
+    AutoMutex _l(mLock);
+    device_t* device = getDevice(deviceId);
+    if (device == NULL) return -1;
+    
+    if (sw >= 0 && sw <= SW_MAX) {
+        uint8_t sw_bitmask[(SW_MAX+1)/8];
+        memset(sw_bitmask, 0, sizeof(sw_bitmask));
+        if (ioctl(mFDs[id_to_index(device->id)].fd,
+                   EVIOCGSW(sizeof(sw_bitmask)), sw_bitmask) >= 0) {
+            return test_bit(sw, sw_bitmask) ? 1 : 0;
+        }
+    }
+#endif
+    
+    return -1;
+}
+
+int EventHub::getScancodeState(int code) const
+{
+    return getScancodeState(mFirstKeyboardId, code);
+}
+
+int EventHub::getScancodeState(int32_t deviceId, int code) const
+{
+    AutoMutex _l(mLock);
+    device_t* device = getDevice(deviceId);
+    if (device == NULL) return -1;
+    
+    if (code >= 0 && code <= KEY_MAX) {
+        uint8_t key_bitmask[(KEY_MAX+1)/8];
+        memset(key_bitmask, 0, sizeof(key_bitmask));
+        if (ioctl(mFDs[id_to_index(device->id)].fd,
+                   EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
+            return test_bit(code, key_bitmask) ? 1 : 0;
+        }
+    }
+    
+    return -1;
+}
+
+int EventHub::getKeycodeState(int code) const
+{
+    return getKeycodeState(mFirstKeyboardId, code);
+}
+
+int EventHub::getKeycodeState(int32_t deviceId, int code) const
+{
+    AutoMutex _l(mLock);
+    device_t* device = getDevice(deviceId);
+    if (device == NULL || device->layoutMap == NULL) return -1;
+    
+    Vector<int32_t> scanCodes;
+    device->layoutMap->findScancodes(code, &scanCodes);
+    
+    uint8_t key_bitmask[(KEY_MAX+1)/8];
+    memset(key_bitmask, 0, sizeof(key_bitmask));
+    if (ioctl(mFDs[id_to_index(device->id)].fd,
+               EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
+        #if 0
+        for (size_t i=0; i<=KEY_MAX; i++) {
+            LOGI("(Scan code %d: down=%d)", i, test_bit(i, key_bitmask));
+        }
+        #endif
+        const size_t N = scanCodes.size();
+        for (size_t i=0; i<N && i<=KEY_MAX; i++) {
+            int32_t sc = scanCodes.itemAt(i);
+            //LOGI("Code %d: down=%d", sc, test_bit(sc, key_bitmask));
+            if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, key_bitmask)) {
+                return 1;
+            }
+        }
+    }
+    
+    return 0;
+}
+
+EventHub::device_t* EventHub::getDevice(int32_t deviceId) const
+{
+    if (deviceId == 0) deviceId = mFirstKeyboardId;
+    int32_t id = deviceId & ID_MASK;
+    if (id >= mNumDevicesById || id < 0) return NULL;
+    device_t* dev = mDevicesById[id].device;
+    if (dev->id == deviceId) {
+        return dev;
+    }
+    return NULL;
+}
+
+bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType,
+        int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
+        int32_t* outValue, nsecs_t* outWhen)
+{
+    *outDeviceId = 0;
+    *outType = 0;
+    *outScancode = 0;
+    *outKeycode = 0;
+    *outFlags = 0;
+    *outValue = 0;
+    *outWhen = 0;
+
+    status_t err;
+
+    fd_set readfds;
+    int maxFd = -1;
+    int cc;
+    int i;
+    int res;
+    int pollres;
+    struct input_event iev;
+
+    // Note that we only allow one caller to getEvent(), so don't need
+    // to do locking here...  only when adding/removing devices.
+    
+    while(1) {
+
+        // First, report any devices that had last been added/removed.
+        if (mClosingDevices != NULL) {
+            device_t* device = mClosingDevices;
+            LOGV("Reporting device closed: id=0x%x, name=%s\n",
+                 device->id, device->path.string());
+            mClosingDevices = device->next;
+            *outDeviceId = device->id;
+            if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
+            *outType = DEVICE_REMOVED;
+            delete device;
+            return true;
+        }
+        if (mOpeningDevices != NULL) {
+            device_t* device = mOpeningDevices;
+            LOGV("Reporting device opened: id=0x%x, name=%s\n",
+                 device->id, device->path.string());
+            mOpeningDevices = device->next;
+            *outDeviceId = device->id;
+            if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
+            *outType = DEVICE_ADDED;
+            return true;
+        }
+
+        release_wake_lock(WAKE_LOCK_ID);
+
+        pollres = poll(mFDs, mFDCount, -1);
+
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+
+        if (pollres <= 0) {
+            if (errno != EINTR) {
+                LOGW("select failed (errno=%d)\n", errno);
+                usleep(100000);
+            }
+            continue;
+        }
+
+        //printf("poll %d, returned %d\n", mFDCount, pollres);
+
+        // mFDs[0] is used for inotify, so process regular events starting at mFDs[1]
+        for(i = 1; i < mFDCount; i++) {
+            if(mFDs[i].revents) {
+                LOGV("revents for %d = 0x%08x", i, mFDs[i].revents);
+                if(mFDs[i].revents & POLLIN) {
+                    res = read(mFDs[i].fd, &iev, sizeof(iev));
+                    if (res == sizeof(iev)) {
+                        LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d",
+                             mDevices[i]->path.string(),
+                             (int) iev.time.tv_sec, (int) iev.time.tv_usec,
+                             iev.type, iev.code, iev.value);
+                        *outDeviceId = mDevices[i]->id;
+                        if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
+                        *outType = iev.type;
+                        *outScancode = iev.code;
+                        if (iev.type == EV_KEY) {
+                            err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags);
+                            LOGV("iev.code=%d outKeycode=%d outFlags=0x%08x err=%d\n",
+                                iev.code, *outKeycode, *outFlags, err);
+                            if (err != 0) {
+                                *outKeycode = 0;
+                                *outFlags = 0;
+                            }
+                        } else {
+                            *outKeycode = iev.code;
+                        }
+                        *outValue = iev.value;
+                        *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec);
+                        return true;
+                    } else {
+                        if (res<0) {
+                            LOGW("could not get event (errno=%d)", errno);
+                        } else {
+                            LOGE("could not get event (wrong size: %d)", res);
+                        }
+                        continue;
+                    }
+                }
+            }
+        }
+        
+        // read_notify() will modify mFDs and mFDCount, so this must be done after
+        // processing all other events.
+        if(mFDs[0].revents & POLLIN) {
+            read_notify(mFDs[0].fd);
+        }
+    }
+}
+
+/*
+ * Open the platform-specific input device.
+ */
+bool EventHub::openPlatformInput(void)
+{
+    /*
+     * Open platform-specific input device(s).
+     */
+    int res;
+
+    mFDCount = 1;
+    mFDs = (pollfd *)calloc(1, sizeof(mFDs[0]));
+    mDevices = (device_t **)calloc(1, sizeof(mDevices[0]));
+    mFDs[0].events = POLLIN;
+    mDevices[0] = NULL;
+#ifdef HAVE_INOTIFY
+    mFDs[0].fd = inotify_init();
+    res = inotify_add_watch(mFDs[0].fd, device_path, IN_DELETE | IN_CREATE);
+    if(res < 0) {
+        LOGE("could not add watch for %s, %s\n", device_path, strerror(errno));
+    }
+#else
+    /*
+     * The code in EventHub::getEvent assumes that mFDs[0] is an inotify fd.
+     * We allocate space for it and set it to something invalid.
+     */
+    mFDs[0].fd = -1;
+#endif
+
+    res = scan_dir(device_path);
+    if(res < 0) {
+        LOGE("scan dir failed for %s\n", device_path);
+        //open_device("/dev/input/event0");
+    }
+
+    return true;
+}
+
+/*
+ * Inspect the known devices to determine whether physical keys exist for the given
+ * framework-domain key codes.
+ */
+bool EventHub::hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags) {
+    for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
+        outFlags[codeIndex] = 0;
+
+        // check each available hardware device for support for this keycode
+        Vector<int32_t> scanCodes;
+        for (int n = 0; (n < mFDCount) && (outFlags[codeIndex] == 0); n++) {
+            if (mDevices[n]) {
+                status_t err = mDevices[n]->layoutMap->findScancodes(keyCodes[codeIndex], &scanCodes);
+                if (!err) {
+                    // check the possible scan codes identified by the layout map against the
+                    // map of codes actually emitted by the driver
+                    for (size_t sc = 0; sc < scanCodes.size(); sc++) {
+                        if (test_bit(scanCodes[sc], mDevices[n]->keyBitmask)) {
+                            outFlags[codeIndex] = 1;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+// ----------------------------------------------------------------------------
+
+int EventHub::open_device(const char *deviceName)
+{
+    int version;
+    int fd;
+    struct pollfd *new_mFDs;
+    device_t **new_devices;
+    char **new_device_names;
+    char name[80];
+    char location[80];
+    char idstr[80];
+    struct input_id id;
+
+    LOGV("Opening device: %s", deviceName);
+
+    AutoMutex _l(mLock);
+    
+    fd = open(deviceName, O_RDWR);
+    if(fd < 0) {
+        LOGE("could not open %s, %s\n", deviceName, strerror(errno));
+        return -1;
+    }
+
+    if(ioctl(fd, EVIOCGVERSION, &version)) {
+        LOGE("could not get driver version for %s, %s\n", deviceName, strerror(errno));
+        return -1;
+    }
+    if(ioctl(fd, EVIOCGID, &id)) {
+        LOGE("could not get driver id for %s, %s\n", deviceName, strerror(errno));
+        return -1;
+    }
+    name[sizeof(name) - 1] = '\0';
+    location[sizeof(location) - 1] = '\0';
+    idstr[sizeof(idstr) - 1] = '\0';
+    if(ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
+        //fprintf(stderr, "could not get device name for %s, %s\n", deviceName, strerror(errno));
+        name[0] = '\0';
+    }
+    if(ioctl(fd, EVIOCGPHYS(sizeof(location) - 1), &location) < 1) {
+        //fprintf(stderr, "could not get location for %s, %s\n", deviceName, strerror(errno));
+        location[0] = '\0';
+    }
+    if(ioctl(fd, EVIOCGUNIQ(sizeof(idstr) - 1), &idstr) < 1) {
+        //fprintf(stderr, "could not get idstring for %s, %s\n", deviceName, strerror(errno));
+        idstr[0] = '\0';
+    }
+
+    int devid = 0;
+    while (devid < mNumDevicesById) {
+        if (mDevicesById[devid].device == NULL) {
+            break;
+        }
+        devid++;
+    }
+    if (devid >= mNumDevicesById) {
+        device_ent* new_devids = (device_ent*)realloc(mDevicesById,
+                sizeof(mDevicesById[0]) * (devid + 1));
+        if (new_devids == NULL) {
+            LOGE("out of memory");
+            return -1;
+        }
+        mDevicesById = new_devids;
+        mNumDevicesById = devid+1;
+        mDevicesById[devid].device = NULL;
+        mDevicesById[devid].seq = 0;
+    }
+
+    mDevicesById[devid].seq = (mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK;
+    if (mDevicesById[devid].seq == 0) {
+        mDevicesById[devid].seq = 1<<SEQ_SHIFT;
+    }
+
+    new_mFDs = (pollfd*)realloc(mFDs, sizeof(mFDs[0]) * (mFDCount + 1));
+    new_devices = (device_t**)realloc(mDevices, sizeof(mDevices[0]) * (mFDCount + 1));
+    if (new_mFDs == NULL || new_devices == NULL) {
+        LOGE("out of memory");
+        return -1;
+    }
+    mFDs = new_mFDs;
+    mDevices = new_devices;
+
+#if 0
+    LOGI("add device %d: %s\n", mFDCount, deviceName);
+    LOGI("  bus:      %04x\n"
+         "  vendor    %04x\n"
+         "  product   %04x\n"
+         "  version   %04x\n",
+        id.bustype, id.vendor, id.product, id.version);
+    LOGI("  name:     \"%s\"\n", name);
+    LOGI("  location: \"%s\"\n"
+         "  id:       \"%s\"\n", location, idstr);
+    LOGI("  version:  %d.%d.%d\n",
+        version >> 16, (version >> 8) & 0xff, version & 0xff);
+#endif
+
+    device_t* device = new device_t(devid|mDevicesById[devid].seq, deviceName);
+    if (device == NULL) {
+        LOGE("out of memory");
+        return -1;
+    }
+
+    mFDs[mFDCount].fd = fd;
+    mFDs[mFDCount].events = POLLIN;
+
+    // figure out the kinds of events the device reports
+    uint8_t key_bitmask[(KEY_MAX+1)/8];
+    memset(key_bitmask, 0, sizeof(key_bitmask));
+    LOGV("Getting keys...");
+    if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) {
+        //LOGI("MAP\n");
+        //for (int i=0; i<((KEY_MAX+1)/8); i++) {
+        //    LOGI("%d: 0x%02x\n", i, key_bitmask[i]);
+        //}
+        for (int i=0; i<((BTN_MISC+7)/8); i++) {
+            if (key_bitmask[i] != 0) {
+                device->classes |= CLASS_KEYBOARD;
+                // 'Q' key support = cheap test of whether this is an alpha-capable kbd
+                if (test_bit(KEY_Q, key_bitmask)) {
+                    device->classes |= CLASS_ALPHAKEY;
+                }
+                break;
+            }
+        }
+        if ((device->classes & CLASS_KEYBOARD) != 0) {
+            device->keyBitmask = new uint8_t[(KEY_MAX+1)/8];
+            if (device->keyBitmask != NULL) {
+                memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
+            } else {
+                delete device;
+                LOGE("out of memory allocating key bitmask");
+                return -1;
+            }
+        }
+    }
+    if (test_bit(BTN_MOUSE, key_bitmask)) {
+        uint8_t rel_bitmask[(REL_MAX+1)/8];
+        memset(rel_bitmask, 0, sizeof(rel_bitmask));
+        LOGV("Getting relative controllers...");
+        if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0)
+        {
+            if (test_bit(REL_X, rel_bitmask) && test_bit(REL_Y, rel_bitmask)) {
+                device->classes |= CLASS_TRACKBALL;
+            }
+        }
+    }
+    if (test_bit(BTN_TOUCH, key_bitmask)) {
+        uint8_t abs_bitmask[(ABS_MAX+1)/8];
+        memset(abs_bitmask, 0, sizeof(abs_bitmask));
+        LOGV("Getting absolute controllers...");
+        if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0)
+        {
+            if (test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
+                device->classes |= CLASS_TOUCHSCREEN;
+            }
+        }
+    }
+
+#ifdef EV_SW
+    // figure out the switches this device reports
+    uint8_t sw_bitmask[(SW_MAX+1)/8];
+    memset(sw_bitmask, 0, sizeof(sw_bitmask));
+    if (ioctl(fd, EVIOCGBIT(EV_SW, sizeof(sw_bitmask)), sw_bitmask) >= 0) {
+        for (int i=0; i<EV_SW; i++) {
+            //LOGI("Device 0x%x sw %d: has=%d", device->id, i, test_bit(i, sw_bitmask));
+            if (test_bit(i, sw_bitmask)) {
+                if (mSwitches[i] == 0) {
+                    mSwitches[i] = device->id;
+                }
+            }
+        }
+    }
+#endif
+
+    LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
+         deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes);
+
+    if ((device->classes&CLASS_KEYBOARD) != 0) {
+        char devname[101];
+        char tmpfn[101];
+        char keylayoutFilename[300];
+
+        // a more descriptive name
+        ioctl(mFDs[mFDCount].fd, EVIOCGNAME(sizeof(devname)-1), devname);
+        devname[sizeof(devname)-1] = 0;
+        device->name = devname;
+
+        // replace all the spaces with underscores
+        strcpy(tmpfn, devname);
+        for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' '))
+            *p = '_';
+
+        // find the .kl file we need for this device
+        const char* root = getenv("ANDROID_ROOT");
+        snprintf(keylayoutFilename, sizeof(keylayoutFilename),
+                 "%s/usr/keylayout/%s.kl", root, tmpfn);
+        bool defaultKeymap = false;
+        if (access(keylayoutFilename, R_OK)) {
+            snprintf(keylayoutFilename, sizeof(keylayoutFilename),
+                     "%s/usr/keylayout/%s", root, "qwerty.kl");
+            defaultKeymap = true;
+        }
+        device->layoutMap->load(keylayoutFilename);
+
+        // tell the world about the devname (the descriptive name)
+        int32_t publicID;
+        if (!mHaveFirstKeyboard && !defaultKeymap) {
+            publicID = 0;
+            // the built-in keyboard has a well-known device ID of 0,
+            // this device better not go away.
+            mHaveFirstKeyboard = true;
+            mFirstKeyboardId = device->id;
+        } else {
+            publicID = device->id;
+            // ensure mFirstKeyboardId is set to -something-.
+            if (mFirstKeyboardId == 0) {
+                mFirstKeyboardId = device->id;
+            }
+        }
+        char propName[100];
+        sprintf(propName, "hw.keyboards.%u.devname", publicID);
+        property_set(propName, devname);
+
+        LOGI("New keyboard: publicID=%d device->id=%d devname='%s' propName='%s' keylayout='%s'\n",
+                publicID, device->id, devname, propName, keylayoutFilename);
+    }
+
+    LOGV("Adding device %s %p at %d, id = %d, classes = 0x%x\n",
+         deviceName, device, mFDCount, devid, device->classes);
+
+    mDevicesById[devid].device = device;
+    device->next = mOpeningDevices;
+    mOpeningDevices = device;
+    mDevices[mFDCount] = device;
+
+    mFDCount++;
+    return 0;
+}
+
+int EventHub::close_device(const char *deviceName)
+{
+    AutoMutex _l(mLock);
+    
+    int i;
+    for(i = 1; i < mFDCount; i++) {
+        if(strcmp(mDevices[i]->path.string(), deviceName) == 0) {
+            //LOGD("remove device %d: %s\n", i, deviceName);
+            device_t* device = mDevices[i];
+            int count = mFDCount - i - 1;
+            int index = (device->id&ID_MASK);
+            mDevicesById[index].device = NULL;
+            memmove(mDevices + i, mDevices + i + 1, sizeof(mDevices[0]) * count);
+            memmove(mFDs + i, mFDs + i + 1, sizeof(mFDs[0]) * count);
+
+#ifdef EV_SW
+            for (int j=0; j<EV_SW; j++) {
+                if (mSwitches[j] == device->id) {
+                    mSwitches[j] = 0;
+                }
+            }
+#endif
+            
+            device->next = mClosingDevices;
+            mClosingDevices = device;
+
+            mFDCount--;
+
+            uint32_t publicID;
+            if (device->id == mFirstKeyboardId) {
+                LOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
+                        device->path.string(), mFirstKeyboardId);
+                mFirstKeyboardId = 0;
+                publicID = 0;
+            } else {
+                publicID = device->id;
+            }
+            // clear the property
+            char propName[100];
+            sprintf(propName, "hw.keyboards.%u.devname", publicID);
+            property_set(propName, NULL);
+            return 0;
+        }
+    }
+    LOGE("remote device: %s not found\n", deviceName);
+    return -1;
+}
+
+int EventHub::read_notify(int nfd)
+{
+#ifdef HAVE_INOTIFY
+    int res;
+    char devname[PATH_MAX];
+    char *filename;
+    char event_buf[512];
+    int event_size;
+    int event_pos = 0;
+    struct inotify_event *event;
+
+    res = read(nfd, event_buf, sizeof(event_buf));
+    if(res < (int)sizeof(*event)) {
+        if(errno == EINTR)
+            return 0;
+        LOGW("could not get event, %s\n", strerror(errno));
+        return 1;
+    }
+    //printf("got %d bytes of event information\n", res);
+
+    strcpy(devname, device_path);
+    filename = devname + strlen(devname);
+    *filename++ = '/';
+
+    while(res >= (int)sizeof(*event)) {
+        event = (struct inotify_event *)(event_buf + event_pos);
+        //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
+        if(event->len) {
+            strcpy(filename, event->name);
+            if(event->mask & IN_CREATE) {
+                open_device(devname);
+            }
+            else {
+                close_device(devname);
+            }
+        }
+        event_size = sizeof(*event) + event->len;
+        res -= event_size;
+        event_pos += event_size;
+    }
+#endif
+    return 0;
+}
+
+
+int EventHub::scan_dir(const char *dirname)
+{
+    char devname[PATH_MAX];
+    char *filename;
+    DIR *dir;
+    struct dirent *de;
+    dir = opendir(dirname);
+    if(dir == NULL)
+        return -1;
+    strcpy(devname, dirname);
+    filename = devname + strlen(devname);
+    *filename++ = '/';
+    while((de = readdir(dir))) {
+        if(de->d_name[0] == '.' &&
+           (de->d_name[1] == '\0' ||
+            (de->d_name[1] == '.' && de->d_name[2] == '\0')))
+            continue;
+        strcpy(filename, de->d_name);
+        open_device(devname);
+    }
+    closedir(dir);
+    return 0;
+}
+
+}; // namespace android
diff --git a/libs/ui/EventRecurrence.cpp b/libs/ui/EventRecurrence.cpp
new file mode 100644
index 0000000..b436b50
--- /dev/null
+++ b/libs/ui/EventRecurrence.cpp
@@ -0,0 +1,484 @@
+/*
+ *  Copyright 2006 The Android Open Source Project
+ */
+
+#include <pim/EventRecurrence.h>
+#include <utils/String8.h>
+#include <stdio.h>
+#include <limits.h>
+
+namespace android {
+
+#define FAIL_HERE() do { \
+            printf("Parsing failed at line %d\n", __LINE__); \
+            return UNKNOWN_ERROR; \
+        } while(0)
+
+EventRecurrence::EventRecurrence()
+    :freq((freq_t)0),
+     until(),
+     count(0),
+     interval(0),
+     bysecond(0),
+     bysecondCount(0),
+     byminute(0),
+     byminuteCount(0),
+     byhour(0),
+     byhourCount(0),
+     byday(0),
+     bydayNum(0),
+     bydayCount(0),
+     bymonthday(0),
+     bymonthdayCount(0),
+     byyearday(0),
+     byyeardayCount(0),
+     byweekno(0),
+     byweeknoCount(0),
+     bymonth(0),
+     bymonthCount(0),
+     bysetpos(0),
+     bysetposCount(0),
+     wkst(0)
+{
+}
+
+EventRecurrence::~EventRecurrence()
+{
+    delete[] bysecond;
+    delete[] byminute;
+    delete[] byhour;
+    delete[] byday;
+    delete[] bydayNum;
+    delete[] byyearday;
+    delete[] bymonthday;
+    delete[] byweekno;
+    delete[] bymonth;
+    delete[] bysetpos;
+}
+
+enum LHS {
+    NONE_LHS = 0,
+    FREQ,
+    UNTIL,
+    COUNT,
+    INTERVAL,
+    BYSECOND,
+    BYMINUTE,
+    BYHOUR,
+    BYDAY,
+    BYMONTHDAY,
+    BYYEARDAY,
+    BYWEEKNO,
+    BYMONTH,
+    BYSETPOS,
+    WKST
+};
+
+struct LHSProc
+{
+    const char16_t* text;
+    size_t textSize;
+    uint32_t value;
+};
+
+const char16_t FREQ_text[] = { 'F', 'R', 'E', 'Q' };
+const char16_t UNTIL_text[] = { 'U', 'N', 'T', 'I', 'L' };
+const char16_t COUNT_text[] = { 'C', 'O', 'U', 'N', 'T' };
+const char16_t INTERVAL_text[] = { 'I', 'N', 'T', 'E', 'R', 'V', 'A', 'L'};
+const char16_t BYSECOND_text[] = { 'B', 'Y', 'S', 'E', 'C', 'O', 'N', 'D' };
+const char16_t BYMINUTE_text[] = { 'B', 'Y', 'M', 'I', 'N', 'U', 'T', 'E' };
+const char16_t BYHOUR_text[] = { 'B', 'Y', 'H', 'O', 'U', 'R' };
+const char16_t BYDAY_text[] = { 'B', 'Y', 'D', 'A', 'Y' };
+const char16_t BYMONTHDAY_text[] = { 'B','Y','M','O','N','T','H','D','A','Y' };
+const char16_t BYYEARDAY_text[] = { 'B','Y','Y','E','A','R','D','A','Y' };
+const char16_t BYWEEKNO_text[] = { 'B', 'Y', 'W', 'E', 'E', 'K', 'N', 'O' };
+const char16_t BYMONTH_text[] = { 'B', 'Y', 'M', 'O', 'N', 'T', 'H' };
+const char16_t BYSETPOS_text[] = { 'B', 'Y', 'S', 'E', 'T', 'P', 'O', 'S' };
+const char16_t WKST_text[] = { 'W', 'K', 'S', 'T' };
+
+#define SIZ(x) (sizeof(x)/sizeof(x[0]))
+
+const LHSProc LHSPROC[] = {
+    { FREQ_text, SIZ(FREQ_text), FREQ },
+    { UNTIL_text, SIZ(UNTIL_text), UNTIL },
+    { COUNT_text, SIZ(COUNT_text), COUNT },
+    { INTERVAL_text, SIZ(INTERVAL_text), INTERVAL },
+    { BYSECOND_text, SIZ(BYSECOND_text), BYSECOND },
+    { BYMINUTE_text, SIZ(BYMINUTE_text), BYMINUTE },
+    { BYHOUR_text, SIZ(BYHOUR_text), BYHOUR },
+    { BYDAY_text, SIZ(BYDAY_text), BYDAY },
+    { BYMONTHDAY_text, SIZ(BYMONTHDAY_text), BYMONTHDAY },
+    { BYYEARDAY_text, SIZ(BYYEARDAY_text), BYYEARDAY },
+    { BYWEEKNO_text, SIZ(BYWEEKNO_text), BYWEEKNO },
+    { BYMONTH_text, SIZ(BYMONTH_text), BYMONTH },
+    { BYSETPOS_text, SIZ(BYSETPOS_text), BYSETPOS },
+    { WKST_text, SIZ(WKST_text), WKST },
+    { NULL, 0, NONE_LHS },
+};
+
+const char16_t SECONDLY_text[] = { 'S','E','C','O','N','D','L','Y' };
+const char16_t MINUTELY_text[] = { 'M','I','N','U','T','E','L','Y' };
+const char16_t HOURLY_text[] = { 'H','O','U','R','L','Y' };
+const char16_t DAILY_text[] = { 'D','A','I','L','Y' };
+const char16_t WEEKLY_text[] = { 'W','E','E','K','L','Y' };
+const char16_t MONTHLY_text[] = { 'M','O','N','T','H','L','Y' };
+const char16_t YEARLY_text[] = { 'Y','E','A','R','L','Y' };
+
+typedef LHSProc FreqProc;
+
+const FreqProc FREQPROC[] = {
+    { SECONDLY_text, SIZ(SECONDLY_text), EventRecurrence::SECONDLY },
+    { MINUTELY_text, SIZ(MINUTELY_text), EventRecurrence::MINUTELY },
+    { HOURLY_text, SIZ(HOURLY_text), EventRecurrence::HOURLY },
+    { DAILY_text, SIZ(DAILY_text), EventRecurrence::DAILY },
+    { WEEKLY_text, SIZ(WEEKLY_text), EventRecurrence::WEEKLY },
+    { MONTHLY_text, SIZ(MONTHLY_text), EventRecurrence::MONTHLY },
+    { YEARLY_text, SIZ(YEARLY_text), EventRecurrence::YEARLY },
+    { NULL, 0, NONE_LHS },
+};
+
+const char16_t SU_text[] = { 'S','U' };
+const char16_t MO_text[] = { 'M','O' };
+const char16_t TU_text[] = { 'T','U' };
+const char16_t WE_text[] = { 'W','E' };
+const char16_t TH_text[] = { 'T','H' };
+const char16_t FR_text[] = { 'F','R' };
+const char16_t SA_text[] = { 'S','A' };
+
+const FreqProc WEEKDAYPROC[] = {
+    { SU_text, SIZ(SU_text), EventRecurrence::SU },
+    { MO_text, SIZ(MO_text), EventRecurrence::MO },
+    { TU_text, SIZ(TU_text), EventRecurrence::TU },
+    { WE_text, SIZ(WE_text), EventRecurrence::WE },
+    { TH_text, SIZ(TH_text), EventRecurrence::TH },
+    { FR_text, SIZ(FR_text), EventRecurrence::FR },
+    { SA_text, SIZ(SA_text), EventRecurrence::SA },
+    { NULL, 0, NONE_LHS },
+};
+
+// returns the index into LHSPROC for the match or -1 if not found
+inline static int
+match_proc(const LHSProc* p, const char16_t* str, size_t len)
+{
+    int i = 0;
+    while (p->text != NULL) {
+        if (p->textSize == len) {
+            if (0 == memcmp(p->text, str, len*sizeof(char16_t))) {
+                return i;
+            }
+        }
+        p++;
+        i++;
+    }
+    return -1;
+}
+
+// rangeMin and rangeMax are inclusive
+static status_t
+parse_int(const char16_t* str, size_t len, int* out,
+            int rangeMin, int rangeMax, bool zeroOK)
+{
+    char16_t c;
+    size_t i=0;
+
+    if (len == 0) {
+        FAIL_HERE();
+    }
+    bool negative = false;
+    c = str[0];
+    if (c == '-' ) {
+        negative = true;
+        i++;
+    }
+    else if (c == '+') {
+        i++;
+    }
+    int n = 0;
+    for (; i<len; i++) {
+        c = str[i];
+        if (c < '0' || c > '9') {
+            FAIL_HERE();
+        }
+        int prev = n;
+        n *= 10;
+        // the spec doesn't address how big these numbers can be,
+        // so we're not going to worry about not being able to represent
+        // INT_MIN, and if we're going to wrap, we'll just clamp to
+        // INT_MAX instead
+        if (n < prev) {
+            n = INT_MAX;
+        } else {
+            n += c - '0';
+        }
+    }
+    if (negative) {
+        n = -n;
+    }
+    if (n < rangeMin || n > rangeMax) {
+        FAIL_HERE();
+    }
+    if (!zeroOK && n == 0) {
+        FAIL_HERE();
+    }
+    *out = n;
+    return NO_ERROR;
+}
+
+static status_t
+parse_int_list(const char16_t* str, size_t len, int* countOut, int** listOut,
+          int rangeMin, int rangeMax, bool zeroOK,
+          status_t (*func)(const char16_t*,size_t,int*,int,int,bool)=parse_int)
+{
+    status_t err;
+
+    if (len == 0) {
+        *countOut = 0;
+        *listOut = NULL;
+        return NO_ERROR;
+    }
+
+    // make one pass through looking for commas so we know how big to make our
+    // out array.
+    int count = 1;
+    for (size_t i=0; i<len; i++) {
+        if (str[i] == ',') {
+            count++;
+        }
+    }
+
+    int* list = new int[count];
+    const char16_t* p = str;
+    int commaIndex = 0;
+    size_t i;
+
+    for (i=0; i<len; i++) {
+        if (str[i] == ',') {
+            err = func(p, (str+i-p), list+commaIndex, rangeMin,
+                    rangeMax, zeroOK);
+            if (err != NO_ERROR) {
+                goto bail;
+            }
+            commaIndex++;
+            p = str+i+1;
+        }
+    }
+
+    err = func(p, (str+i-p), list+commaIndex, rangeMin, rangeMax, zeroOK);
+    if (err != NO_ERROR) {
+        goto bail;
+    }
+    commaIndex++;
+
+    *countOut = count;
+    *listOut = list;
+
+    return NO_ERROR;
+
+bail:
+    delete[] list;
+    FAIL_HERE();
+}
+
+// the numbers here are small, so we pack them both into one value, and then
+// split it out later.  it lets us reuse all the comma separated list code.
+static status_t
+parse_byday(const char16_t* s, size_t len, int* out,
+            int rangeMin, int rangeMax, bool zeroOK)
+{
+    status_t err;
+    int n = 0;
+    const char16_t* p = s;
+    size_t plen = len;
+
+    if (len > 0) {
+        char16_t c = s[0];
+        if (c == '-' || c == '+' || (c >= '0' && c <= '9')) {
+            if (len > 1) {
+                size_t nlen = 0;
+                c = s[nlen];
+                while (nlen < len
+                        && (c == '-' || c == '+' || (c >= '0' && c <= '9'))) {
+                    c = s[nlen];
+                    nlen++;
+                }
+                if (nlen > 0) {
+                    nlen--;
+                    err = parse_int(s, nlen, &n, rangeMin, rangeMax, zeroOK);
+                    if (err != NO_ERROR) {
+                        FAIL_HERE();
+                    }
+                    p += nlen;
+                    plen -= nlen;
+                }
+            }
+        }
+
+        int index = match_proc(WEEKDAYPROC, p, plen);
+        if (index >= 0) {
+            *out = (0xffff0000 & WEEKDAYPROC[index].value)
+                    | (0x0000ffff & n);
+            return NO_ERROR;
+        }
+    }
+    return UNKNOWN_ERROR;
+}
+
+static void
+postprocess_byday(int count, int* byday, int** bydayNum)
+{
+    int* bdn = new int[count];
+    *bydayNum = bdn;
+    for (int i=0; i<count; i++) {
+        uint32_t v = byday[i];
+        int16_t num = v & 0x0000ffff;
+        byday[i] = v & 0xffff0000;  
+        // will sign extend:
+        bdn[i] = num;
+    }
+}
+
+#define PARSE_INT_LIST_CHECKED(name, rangeMin, rangeMax, zeroOK) \
+    if (name##Count != 0 || NO_ERROR != parse_int_list(s, slen, \
+                         &name##Count, &name, rangeMin, rangeMax, zeroOK)) { \
+        FAIL_HERE(); \
+    }
+status_t
+EventRecurrence::parse(const String16& str)
+{
+    char16_t const* work = str.string();
+    size_t len = str.size();
+
+    int lhsIndex = NONE_LHS;
+    int index;
+    
+    size_t start = 0;
+    for (size_t i=0; i<len; i++) {
+        char16_t c = work[i];
+        if (c != ';' && i == len-1) {
+            c = ';';
+            i++;
+        }
+        if (c == ';' || c == '=') {
+            if (i != start) {
+                const char16_t* s = work+start;
+                const size_t slen = i-start;
+
+                String8 thestring(String16(s, slen));
+
+                switch (c)
+                {
+                    case '=':
+                        if (lhsIndex == NONE_LHS) {
+                            lhsIndex = match_proc(LHSPROC, s, slen);
+                            if (lhsIndex >= 0) {
+                                break;
+                            }
+                        }
+                        FAIL_HERE();
+                    case ';':
+                    {
+                        switch (LHSPROC[lhsIndex].value)
+                        {
+                            case FREQ:
+                                if (this->freq != 0) {
+                                    FAIL_HERE();
+                                }
+                                index = match_proc(FREQPROC, s, slen);
+                                if (index >= 0) {
+                                    this->freq = (freq_t)FREQPROC[index].value;
+                                }
+                                break;
+                            case UNTIL:
+                                // XXX should check that this is a valid time
+                                until.setTo(String16(s, slen));
+                                break;
+                            case COUNT:
+                                if (count != 0
+                                     || NO_ERROR != parse_int(s, slen,
+                                             &count, INT_MIN, INT_MAX, true)) {
+                                    FAIL_HERE();
+                                }
+                                break;
+                            case INTERVAL:
+                                if (interval != 0
+                                     || NO_ERROR != parse_int(s, slen,
+                                         &interval, INT_MIN, INT_MAX, false)) {
+                                    FAIL_HERE();
+                                }
+                                break;
+                            case BYSECOND:
+                                PARSE_INT_LIST_CHECKED(bysecond, 0, 59, true)
+                                break;
+                            case BYMINUTE:
+                                PARSE_INT_LIST_CHECKED(byminute, 0, 59, true)
+                                break;
+                            case BYHOUR:
+                                PARSE_INT_LIST_CHECKED(byhour, 0, 23, true)
+                                break;
+                            case BYDAY:
+                                if (bydayCount != 0 || NO_ERROR != 
+                                        parse_int_list(s, slen, &bydayCount,
+                                              &byday, -53, 53, false,
+                                              parse_byday)) {
+                                    FAIL_HERE();
+                                }
+                                postprocess_byday(bydayCount, byday, &bydayNum);
+                                break;
+                            case BYMONTHDAY:
+                                PARSE_INT_LIST_CHECKED(bymonthday, -31, 31,
+                                                        false)
+                                break;
+                            case BYYEARDAY:
+                                PARSE_INT_LIST_CHECKED(byyearday, -366, 366,
+                                                        false)
+                                break;
+                            case BYWEEKNO:
+                                PARSE_INT_LIST_CHECKED(byweekno, -53, 53,
+                                                        false)
+                                break;
+                            case BYMONTH:
+                                PARSE_INT_LIST_CHECKED(bymonth, 1, 12, false)
+                                break;
+                            case BYSETPOS:
+                                PARSE_INT_LIST_CHECKED(bysetpos,
+                                                        INT_MIN, INT_MAX, true)
+                                break;
+                            case WKST:
+                                if (this->wkst != 0) {
+                                    FAIL_HERE();
+                                }
+                                index = match_proc(WEEKDAYPROC, s, slen);
+                                if (index >= 0) {
+                                    this->wkst = (int)WEEKDAYPROC[index].value;
+                                }
+                                break;
+                            default:
+                                FAIL_HERE();
+                        }
+                        lhsIndex = NONE_LHS;
+                        break;
+                    }
+                }
+
+                start = i+1;
+            }
+        }
+    }
+
+    // enforce that there was a FREQ
+    if (freq == 0) {
+        FAIL_HERE();
+    }
+
+    // default wkst to MO if it wasn't specified
+    if (wkst == 0) {
+        wkst = MO;
+    }
+
+    return NO_ERROR;
+}
+
+
+}; // namespace android
+
+
diff --git a/libs/ui/ICamera.cpp b/libs/ui/ICamera.cpp
new file mode 100644
index 0000000..ab0fef1
--- /dev/null
+++ b/libs/ui/ICamera.cpp
@@ -0,0 +1,346 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     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_NDEBUG 0
+#define LOG_TAG "ICamera"
+#include <utils/Log.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Parcel.h>
+#include <ui/ICamera.h>
+
+namespace android {
+
+enum {
+    DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
+    SET_PREVIEW_DISPLAY,
+    SET_PREVIEW_CALLBACK_FLAG,
+    START_PREVIEW,
+    STOP_PREVIEW,
+    AUTO_FOCUS,
+    TAKE_PICTURE,
+    SET_PARAMETERS,
+    GET_PARAMETERS,
+    CONNECT,
+    LOCK,
+    UNLOCK,
+    PREVIEW_ENABLED,
+    START_RECORDING,
+    STOP_RECORDING,
+    RECORDING_ENABLED,
+    RELEASE_RECORDING_FRAME,
+};
+
+class BpCamera: public BpInterface<ICamera>
+{
+public:
+    BpCamera(const sp<IBinder>& impl)
+        : BpInterface<ICamera>(impl)
+    {
+    }
+
+    // disconnect from camera service
+    void disconnect()
+    {
+        LOGV("disconnect");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(DISCONNECT, data, &reply);
+    }
+
+    // pass the buffered ISurface to the camera service
+    status_t setPreviewDisplay(const sp<ISurface>& surface)
+    {
+        LOGV("setPreviewDisplay");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        data.writeStrongBinder(surface->asBinder());
+        remote()->transact(SET_PREVIEW_DISPLAY, data, &reply);
+        return reply.readInt32();
+    }
+
+    // set the preview callback flag to affect how the received frames from
+    // preview are handled. See Camera.h for details.
+    void setPreviewCallbackFlag(int flag)
+    {
+        LOGV("setPreviewCallbackFlag(%d)", flag);
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        data.writeInt32(flag);
+        remote()->transact(SET_PREVIEW_CALLBACK_FLAG, data, &reply);
+    }
+
+    // start preview mode, must call setPreviewDisplay first
+    status_t startPreview()
+    {
+        LOGV("startPreview");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(START_PREVIEW, data, &reply);
+        return reply.readInt32();
+    }
+
+    // start recording mode, must call setPreviewDisplay first
+    status_t startRecording()
+    {
+        LOGV("startRecording");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(START_RECORDING, data, &reply);
+        return reply.readInt32();
+    }
+
+    // stop preview mode
+    void stopPreview()
+    {
+        LOGV("stopPreview");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(STOP_PREVIEW, data, &reply);
+    }
+
+    // stop recording mode
+    void stopRecording()
+    {
+        LOGV("stopRecording");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(STOP_RECORDING, data, &reply);
+    }
+
+    void releaseRecordingFrame(const sp<IMemory>& mem)
+    {
+        LOGV("releaseRecordingFrame");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        data.writeStrongBinder(mem->asBinder());
+        remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);
+    }
+
+    // check preview state
+    bool previewEnabled()
+    {
+        LOGV("previewEnabled");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(PREVIEW_ENABLED, data, &reply);
+        return reply.readInt32();
+    }
+
+    // check recording state
+    bool recordingEnabled()
+    {
+        LOGV("recordingEnabled");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(RECORDING_ENABLED, data, &reply);
+        return reply.readInt32();
+    }
+
+    // auto focus
+    status_t autoFocus()
+    {
+        LOGV("autoFocus");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(AUTO_FOCUS, data, &reply);
+        status_t ret = reply.readInt32();
+        return ret;
+    }
+
+    // take a picture - returns an IMemory (ref-counted mmap)
+    status_t takePicture()
+    {
+        LOGV("takePicture");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(TAKE_PICTURE, data, &reply);
+        status_t ret = reply.readInt32();
+        return ret;
+    }
+
+    // set preview/capture parameters - key/value pairs
+    status_t setParameters(const String8& params)
+    {
+        LOGV("setParameters");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        data.writeString8(params);
+        remote()->transact(SET_PARAMETERS, data, &reply);
+        return reply.readInt32();
+    }
+
+    // get preview/capture parameters - key/value pairs
+    String8 getParameters() const
+    {
+        LOGV("getParameters");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(GET_PARAMETERS, data, &reply);
+        return reply.readString8();
+    }
+    virtual status_t connect(const sp<ICameraClient>& cameraClient)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        data.writeStrongBinder(cameraClient->asBinder());
+        remote()->transact(CONNECT, data, &reply);
+        return reply.readInt32();
+    }
+    virtual status_t lock()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(LOCK, data, &reply);
+        return reply.readInt32();
+    }
+    virtual status_t unlock()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(UNLOCK, data, &reply);
+        return reply.readInt32();
+    }
+};
+
+IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnCamera::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case DISCONNECT: {
+            LOGV("DISCONNECT");
+            CHECK_INTERFACE(ICamera, data, reply);
+            disconnect();
+            return NO_ERROR;
+        } break;
+        case SET_PREVIEW_DISPLAY: {
+            LOGV("SET_PREVIEW_DISPLAY");
+            CHECK_INTERFACE(ICamera, data, reply);
+            sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
+            reply->writeInt32(setPreviewDisplay(surface));
+            return NO_ERROR;
+        } break;
+        case SET_PREVIEW_CALLBACK_FLAG: {
+            LOGV("SET_PREVIEW_CALLBACK_TYPE");
+            CHECK_INTERFACE(ICamera, data, reply);
+            int callback_flag = data.readInt32();
+            setPreviewCallbackFlag(callback_flag);
+            return NO_ERROR;
+        } break;
+        case START_PREVIEW: {
+            LOGV("START_PREVIEW");
+            CHECK_INTERFACE(ICamera, data, reply);
+            reply->writeInt32(startPreview());
+            return NO_ERROR;
+        } break;
+        case START_RECORDING: {
+            LOGV("START_RECORDING");
+            CHECK_INTERFACE(ICamera, data, reply);
+            reply->writeInt32(startRecording());
+            return NO_ERROR;
+        } break;
+        case STOP_PREVIEW: {
+            LOGV("STOP_PREVIEW");
+            CHECK_INTERFACE(ICamera, data, reply);
+            stopPreview();
+            return NO_ERROR;
+        } break;
+        case STOP_RECORDING: {
+            LOGV("STOP_RECORDING");
+            CHECK_INTERFACE(ICamera, data, reply);
+            stopRecording();
+            return NO_ERROR;
+        } break;
+        case RELEASE_RECORDING_FRAME: {
+            LOGV("RELEASE_RECORDING_FRAME");
+            CHECK_INTERFACE(ICamera, data, reply);
+            sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());
+            releaseRecordingFrame(mem);
+            return NO_ERROR;
+        } break;
+        case PREVIEW_ENABLED: {
+            LOGV("PREVIEW_ENABLED");
+            CHECK_INTERFACE(ICamera, data, reply);
+            reply->writeInt32(previewEnabled());
+            return NO_ERROR;
+        } break;
+        case RECORDING_ENABLED: {
+            LOGV("RECORDING_ENABLED");
+            CHECK_INTERFACE(ICamera, data, reply);
+            reply->writeInt32(recordingEnabled());
+            return NO_ERROR;
+        } break;
+        case AUTO_FOCUS: {
+            LOGV("AUTO_FOCUS");
+            CHECK_INTERFACE(ICamera, data, reply);
+            reply->writeInt32(autoFocus());
+            return NO_ERROR;
+        } break;
+        case TAKE_PICTURE: {
+            LOGV("TAKE_PICTURE");
+            CHECK_INTERFACE(ICamera, data, reply);
+            reply->writeInt32(takePicture());
+            return NO_ERROR;
+        } break;
+        case SET_PARAMETERS: {
+            LOGV("SET_PARAMETERS");
+            CHECK_INTERFACE(ICamera, data, reply);
+            String8 params(data.readString8());
+            reply->writeInt32(setParameters(params));
+            return NO_ERROR;
+         } break;
+        case GET_PARAMETERS: {
+            LOGV("GET_PARAMETERS");
+            CHECK_INTERFACE(ICamera, data, reply);
+             reply->writeString8(getParameters());
+            return NO_ERROR;
+         } break;
+        case CONNECT: {
+            CHECK_INTERFACE(ICamera, data, reply);
+            sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());
+            reply->writeInt32(connect(cameraClient));
+            return NO_ERROR;
+        } break;
+        case LOCK: {
+            CHECK_INTERFACE(ICamera, data, reply);
+            reply->writeInt32(lock());
+            return NO_ERROR;
+        } break;
+        case UNLOCK: {
+            CHECK_INTERFACE(ICamera, data, reply);
+            reply->writeInt32(unlock());
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/libs/ui/ICameraClient.cpp b/libs/ui/ICameraClient.cpp
new file mode 100644
index 0000000..4bec9d2
--- /dev/null
+++ b/libs/ui/ICameraClient.cpp
@@ -0,0 +1,185 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     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_NDEBUG 0
+#define LOG_TAG "ICameraClient"
+#include <utils/Log.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <ui/ICameraClient.h>
+
+namespace android {
+
+enum {
+    SHUTTER_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
+    RAW_CALLBACK,
+    JPEG_CALLBACK,
+    PREVIEW_CALLBACK,
+    ERROR_CALLBACK,
+    AUTOFOCUS_CALLBACK,
+    RECORDING_CALLBACK,
+};
+
+class BpCameraClient: public BpInterface<ICameraClient>
+{
+public:
+    BpCameraClient(const sp<IBinder>& impl)
+        : BpInterface<ICameraClient>(impl)
+    {
+    }
+
+    // callback to let the app know the shutter has closed, ideal for playing the shutter sound
+    void shutterCallback()
+    {
+        LOGV("shutterCallback");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        remote()->transact(SHUTTER_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    // callback from camera service to app with picture data
+    void rawCallback(const sp<IMemory>& picture)
+    {
+        LOGV("rawCallback");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        data.writeStrongBinder(picture->asBinder());
+        remote()->transact(RAW_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    // callback from camera service to app with picture data
+    void jpegCallback(const sp<IMemory>& picture)
+    {
+        LOGV("jpegCallback");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        data.writeStrongBinder(picture->asBinder());
+        remote()->transact(JPEG_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    // callback from camera service to app with preview frame data
+    void previewCallback(const sp<IMemory>& frame)
+    {
+        LOGV("previewCallback");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        data.writeStrongBinder(frame->asBinder());
+        remote()->transact(PREVIEW_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    // callback from camera service to app with recording frame data
+    void recordingCallback(const sp<IMemory>& frame)
+    {
+        LOGV("recordingCallback");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        data.writeStrongBinder(frame->asBinder());
+        remote()->transact(RECORDING_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    // callback from camera service to app to report error
+    void errorCallback(status_t error)
+    {
+        LOGV("errorCallback");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        data.writeInt32(error);
+        remote()->transact(ERROR_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    // callback from camera service to app to report autofocus completion
+    void autoFocusCallback(bool focused)
+    {
+        LOGV("autoFocusCallback");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        data.writeInt32(focused);
+        remote()->transact(AUTOFOCUS_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(CameraClient, "android.hardware.ICameraClient");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnCameraClient::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case SHUTTER_CALLBACK: {
+            LOGV("SHUTTER_CALLBACK");
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            shutterCallback();
+            return NO_ERROR;
+        } break;
+        case RAW_CALLBACK: {
+            LOGV("RAW_CALLBACK");
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            sp<IMemory> picture = interface_cast<IMemory>(data.readStrongBinder());
+            rawCallback(picture);
+            return NO_ERROR;
+        } break;
+        case JPEG_CALLBACK: {
+            LOGV("JPEG_CALLBACK");
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            sp<IMemory> picture = interface_cast<IMemory>(data.readStrongBinder());
+            jpegCallback(picture);
+            return NO_ERROR;
+        } break;
+        case PREVIEW_CALLBACK: {
+            LOGV("PREVIEW_CALLBACK");
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            sp<IMemory> frame = interface_cast<IMemory>(data.readStrongBinder());
+            previewCallback(frame);
+            return NO_ERROR;
+        } break;
+        case RECORDING_CALLBACK: {
+            LOGV("RECORDING_CALLBACK");
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            sp<IMemory> frame = interface_cast<IMemory>(data.readStrongBinder());
+            recordingCallback(frame);
+            return NO_ERROR;
+        } break;
+        case ERROR_CALLBACK: {
+            LOGV("ERROR_CALLBACK");
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            status_t error = data.readInt32();
+            errorCallback(error);
+            return NO_ERROR;
+        } break;
+        case AUTOFOCUS_CALLBACK: {
+            LOGV("AUTOFOCUS_CALLBACK");
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            bool focused = (bool)data.readInt32();
+            autoFocusCallback(focused);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/libs/ui/ICameraService.cpp b/libs/ui/ICameraService.cpp
new file mode 100644
index 0000000..e5687fe
--- /dev/null
+++ b/libs/ui/ICameraService.cpp
@@ -0,0 +1,77 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     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 <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Parcel.h>
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+
+#include <ui/ICameraService.h>
+
+namespace android {
+
+class BpCameraService: public BpInterface<ICameraService>
+{
+public:
+    BpCameraService(const sp<IBinder>& impl)
+        : BpInterface<ICameraService>(impl)
+    {
+    }
+
+    // connect to camera service
+    virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
+        data.writeStrongBinder(cameraClient->asBinder());
+        remote()->transact(BnCameraService::CONNECT, data, &reply);
+        return interface_cast<ICamera>(reply.readStrongBinder());
+    }
+};
+
+IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnCameraService::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case CONNECT: {
+            CHECK_INTERFACE(ICameraService, data, reply);
+            sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());
+            sp<ICamera> camera = connect(cameraClient);
+            reply->writeStrongBinder(camera->asBinder());
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/libs/ui/IOverlay.cpp b/libs/ui/IOverlay.cpp
new file mode 100644
index 0000000..fed47c2
--- /dev/null
+++ b/libs/ui/IOverlay.cpp
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Parcel.h>
+#include <utils/IInterface.h>
+
+#include <ui/IOverlay.h>
+
+namespace android {
+
+enum {
+    DESTROY = IBinder::FIRST_CALL_TRANSACTION, // one-way transaction
+};
+
+class BpOverlay : public BpInterface<IOverlay>
+{
+public:
+    BpOverlay(const sp<IBinder>& impl)
+        : BpInterface<IOverlay>(impl)
+    {
+    }
+
+    virtual void destroy()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOverlay::getInterfaceDescriptor());
+        remote()->transact(DESTROY, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(Overlay, "android.ui.IOverlay");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnOverlay::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case DESTROY: {
+            CHECK_INTERFACE(IOverlay, data, reply);
+            destroy();
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace android
diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp
new file mode 100644
index 0000000..d5e9f81
--- /dev/null
+++ b/libs/ui/ISurface.cpp
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Parcel.h>
+#include <utils/IMemory.h>
+
+#include <ui/ISurface.h>
+#include <ui/Overlay.h>
+
+
+namespace android {
+
+ISurface::BufferHeap::BufferHeap() 
+    : w(0), h(0), hor_stride(0), ver_stride(0), format(0),
+    transform(0), flags(0) 
+{     
+}
+
+ISurface::BufferHeap::BufferHeap(uint32_t w, uint32_t h,
+        int32_t hor_stride, int32_t ver_stride,
+        PixelFormat format, const sp<IMemoryHeap>& heap)
+    : w(w), h(h), hor_stride(hor_stride), ver_stride(ver_stride),
+      format(format), transform(0), flags(0), heap(heap) 
+{
+}
+
+ISurface::BufferHeap::BufferHeap(uint32_t w, uint32_t h,
+        int32_t hor_stride, int32_t ver_stride,
+        PixelFormat format, uint32_t transform, uint32_t flags,
+        const sp<IMemoryHeap>& heap)
+        : w(w), h(h), hor_stride(hor_stride), ver_stride(ver_stride),
+          format(format), transform(transform), flags(flags), heap(heap) 
+{
+}
+
+
+ISurface::BufferHeap::~BufferHeap() 
+{     
+}
+
+class BpSurface : public BpInterface<ISurface>
+{
+public:
+    BpSurface(const sp<IBinder>& impl)
+        : BpInterface<ISurface>(impl)
+    {
+    }
+
+    virtual status_t registerBuffers(const BufferHeap& buffers)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
+        data.writeInt32(buffers.w);
+        data.writeInt32(buffers.h);
+        data.writeInt32(buffers.hor_stride);
+        data.writeInt32(buffers.ver_stride);
+        data.writeInt32(buffers.format);
+        data.writeInt32(buffers.transform);
+        data.writeInt32(buffers.flags);
+        data.writeStrongBinder(buffers.heap->asBinder());
+        remote()->transact(REGISTER_BUFFERS, data, &reply);
+        status_t result = reply.readInt32();
+        return result;
+    }
+
+    virtual void postBuffer(ssize_t offset)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
+        data.writeInt32(offset);
+        remote()->transact(POST_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    virtual void unregisterBuffers()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
+        remote()->transact(UNREGISTER_BUFFERS, data, &reply);
+    }
+
+    virtual sp<OverlayRef> createOverlay(
+             uint32_t w, uint32_t h, int32_t format)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
+        data.writeInt32(w);
+        data.writeInt32(h);
+        data.writeInt32(format);
+        remote()->transact(CREATE_OVERLAY, data, &reply);
+        return OverlayRef::readFromParcel(reply);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(Surface, "android.ui.ISurface");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnSurface::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case REGISTER_BUFFERS: {
+            CHECK_INTERFACE(ISurface, data, reply);
+            BufferHeap buffer;
+            buffer.w = data.readInt32();
+            buffer.h = data.readInt32();
+            buffer.hor_stride = data.readInt32();
+            buffer.ver_stride= data.readInt32();
+            buffer.format = data.readInt32();
+            buffer.transform = data.readInt32();
+            buffer.flags = data.readInt32();
+            buffer.heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
+            status_t err = registerBuffers(buffer);
+            reply->writeInt32(err);
+            return NO_ERROR;
+        } break;
+        case UNREGISTER_BUFFERS: {
+            CHECK_INTERFACE(ISurface, data, reply);
+            unregisterBuffers();
+            return NO_ERROR;
+        } break;
+        case POST_BUFFER: {
+            CHECK_INTERFACE(ISurface, data, reply);
+            ssize_t offset = data.readInt32();
+            postBuffer(offset);
+            return NO_ERROR;
+        } break;
+        case CREATE_OVERLAY: {
+            CHECK_INTERFACE(ISurface, data, reply);
+            int w = data.readInt32();
+            int h = data.readInt32();
+            int f = data.readInt32();
+            sp<OverlayRef> o = createOverlay(w, h, f);
+            return OverlayRef::writeToParcel(reply, o);
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace android
diff --git a/libs/ui/ISurfaceComposer.cpp b/libs/ui/ISurfaceComposer.cpp
new file mode 100644
index 0000000..0fea6f9
--- /dev/null
+++ b/libs/ui/ISurfaceComposer.cpp
@@ -0,0 +1,277 @@
+/*
+ * 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.
+ */
+
+// tag as surfaceflinger
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Parcel.h>
+#include <utils/IMemory.h>
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+
+#include <ui/ISurfaceComposer.h>
+#include <ui/DisplayInfo.h>
+
+// ---------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
+{
+public:
+    BpSurfaceComposer(const sp<IBinder>& impl)
+        : BpInterface<ISurfaceComposer>(impl)
+    {
+    }
+
+    virtual sp<ISurfaceFlingerClient> createConnection()
+    {
+        uint32_t n;
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
+        return interface_cast<ISurfaceFlingerClient>(reply.readStrongBinder());
+    }
+
+    virtual sp<IMemory> getCblk() const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::GET_CBLK, data, &reply);
+        return interface_cast<IMemory>(reply.readStrongBinder());
+    }
+
+    virtual void openGlobalTransaction()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::OPEN_GLOBAL_TRANSACTION, data, &reply);
+    }
+
+    virtual void closeGlobalTransaction()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::CLOSE_GLOBAL_TRANSACTION, data, &reply);
+    }
+
+    virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeInt32(dpy);
+        data.writeInt32(flags);
+        remote()->transact(BnSurfaceComposer::FREEZE_DISPLAY, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeInt32(dpy);
+        data.writeInt32(flags);
+        remote()->transact(BnSurfaceComposer::UNFREEZE_DISPLAY, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual int setOrientation(DisplayID dpy, int orientation)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeInt32(dpy);
+        data.writeInt32(orientation);
+        remote()->transact(BnSurfaceComposer::SET_ORIENTATION, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual void bootFinished()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
+    }
+
+    virtual status_t requestGPU(
+            const sp<IGPUCallback>& callback, gpu_info_t* gpu)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeStrongBinder(callback->asBinder());
+        remote()->transact(BnSurfaceComposer::REQUEST_GPU, data, &reply);
+        gpu->regs = interface_cast<IMemory>(reply.readStrongBinder());
+        gpu->count = reply.readInt32();
+
+        // FIXME: for now, we don't dynamically allocate the regions array
+        size_t maxCount = sizeof(gpu->regions)/sizeof(*gpu->regions);
+        if (gpu->count > maxCount)
+            return BAD_VALUE;
+
+        for (size_t i=0 ; i<gpu->count ; i++) {
+            gpu->regions[i].region = interface_cast<IMemory>(reply.readStrongBinder());
+            gpu->regions[i].reserved = reply.readInt32();
+        }
+        return reply.readInt32();
+    }
+
+    virtual status_t revokeGPU()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::REVOKE_GPU, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual void signal() const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::SIGNAL, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnSurfaceComposer::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    status_t err = BnInterface<ISurfaceComposer>::onTransact(code, data, reply, flags);
+    if (err == NO_ERROR)
+        return err;
+
+    CHECK_INTERFACE(ISurfaceComposer, data, reply);
+
+    switch(code) {
+        case CREATE_CONNECTION: {
+            sp<IBinder> b = createConnection()->asBinder();
+            reply->writeStrongBinder(b);
+        } break;
+        case OPEN_GLOBAL_TRANSACTION: {
+            openGlobalTransaction();
+        } break;
+        case CLOSE_GLOBAL_TRANSACTION: {
+            closeGlobalTransaction();
+        } break;
+        case SET_ORIENTATION: {
+            DisplayID dpy = data.readInt32();
+            int orientation = data.readInt32();
+            reply->writeInt32( setOrientation(dpy, orientation) );
+        } break;
+        case FREEZE_DISPLAY: {
+            DisplayID dpy = data.readInt32();
+            uint32_t flags = data.readInt32();
+            reply->writeInt32( freezeDisplay(dpy, flags) );
+        } break;
+        case UNFREEZE_DISPLAY: {
+            DisplayID dpy = data.readInt32();
+            uint32_t flags = data.readInt32();
+            reply->writeInt32( unfreezeDisplay(dpy, flags) );
+        } break;
+        case BOOT_FINISHED: {
+            bootFinished();
+        } break;
+        case REVOKE_GPU: {
+            reply->writeInt32( revokeGPU() );
+        } break;
+        case SIGNAL: {
+            signal();
+        } break;
+        case GET_CBLK: {
+            sp<IBinder> b = getCblk()->asBinder();
+            reply->writeStrongBinder(b);
+        } break;
+        case REQUEST_GPU: {
+            // TODO: this should be protected by a permission
+            gpu_info_t info;
+            sp<IGPUCallback> callback
+                = interface_cast<IGPUCallback>(data.readStrongBinder());
+            status_t res = requestGPU(callback, &info);
+
+            // FIXME: for now, we don't dynamically allocate the regions array
+            size_t maxCount = sizeof(info.regions)/sizeof(*info.regions);
+            if (info.count > maxCount)
+                return BAD_VALUE;
+
+            reply->writeStrongBinder(info.regs->asBinder());
+            reply->writeInt32(info.count);
+            for (size_t i=0 ; i<info.count ; i++) {
+                reply->writeStrongBinder(info.regions[i].region->asBinder());
+                reply->writeInt32(info.regions[i].reserved);
+            }
+            reply->writeInt32(res);
+        } break;
+        default:
+            return UNKNOWN_TRANSACTION;
+    }
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+enum {
+    // Note: BOOT_FINISHED must remain this value, it is called by ActivityManagerService.
+    GPU_LOST = IBinder::FIRST_CALL_TRANSACTION
+};
+
+class BpGPUCallback : public BpInterface<IGPUCallback>
+{
+public:
+    BpGPUCallback(const sp<IBinder>& impl)
+        : BpInterface<IGPUCallback>(impl)
+    {
+    }
+
+    virtual void gpuLost()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGPUCallback::getInterfaceDescriptor());
+        remote()->transact(GPU_LOST, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(GPUCallback, "android.ui.IGPUCallback");
+
+status_t BnGPUCallback::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case GPU_LOST: {
+            CHECK_INTERFACE(IGPUCallback, data, reply);
+            gpuLost();
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+};
diff --git a/libs/ui/ISurfaceFlingerClient.cpp b/libs/ui/ISurfaceFlingerClient.cpp
new file mode 100644
index 0000000..dd6a798
--- /dev/null
+++ b/libs/ui/ISurfaceFlingerClient.cpp
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ */
+
+// tag as surfaceflinger
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Parcel.h>
+#include <utils/IMemory.h>
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+
+#include <ui/ISurface.h>
+#include <ui/ISurfaceFlingerClient.h>
+#include <ui/Point.h>
+#include <ui/Rect.h>
+
+#include <private/ui/LayerState.h>
+
+// ---------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+enum {
+    GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
+    CREATE_SURFACE,
+    DESTROY_SURFACE,
+    SET_STATE
+};
+
+class BpSurfaceFlingerClient : public BpInterface<ISurfaceFlingerClient>
+{
+public:
+    BpSurfaceFlingerClient(const sp<IBinder>& impl)
+        : BpInterface<ISurfaceFlingerClient>(impl)
+    {
+    }
+
+    virtual void getControlBlocks(sp<IMemory>* ctl) const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
+        remote()->transact(GET_CBLK, data, &reply);
+        *ctl  = interface_cast<IMemory>(reply.readStrongBinder());
+    }
+
+    virtual sp<ISurface> createSurface( surface_data_t* params,
+                                        int pid,
+                                        DisplayID display,
+                                        uint32_t w,
+                                        uint32_t h,
+                                        PixelFormat format,
+                                        uint32_t flags)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
+        data.writeInt32(pid);
+        data.writeInt32(display);
+        data.writeInt32(w);
+        data.writeInt32(h);
+        data.writeInt32(format);
+        data.writeInt32(flags);
+        remote()->transact(CREATE_SURFACE, data, &reply);
+        params->readFromParcel(reply);
+        return interface_cast<ISurface>(reply.readStrongBinder());
+    }
+                                    
+    virtual status_t destroySurface(SurfaceID sid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
+        data.writeInt32(sid);
+        remote()->transact(DESTROY_SURFACE, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t setState(int32_t count, const layer_state_t* states)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
+        data.writeInt32(count);
+        for (int i=0 ; i<count ; i++)
+            states[i].write(data);
+        remote()->transact(SET_STATE, data, &reply);
+        return reply.readInt32();
+    }
+};
+
+IMPLEMENT_META_INTERFACE(SurfaceFlingerClient, "android.ui.ISurfaceFlingerClient");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnSurfaceFlingerClient::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    // codes that don't require permission check
+
+    switch(code) {
+        case GET_CBLK: {
+            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
+            sp<IMemory> ctl;
+            getControlBlocks(&ctl);
+            reply->writeStrongBinder(ctl->asBinder());
+            return NO_ERROR;
+        } break;
+    }
+
+    // these must be checked
+     
+     IPCThreadState* ipc = IPCThreadState::self();
+     const int pid = ipc->getCallingPid();
+     const int self_pid    = getpid();
+     if (UNLIKELY(pid != self_pid)) {
+         // we're called from a different process, do the real check
+         if (!checkCallingPermission(
+                 String16("android.permission.ACCESS_SURFACE_FLINGER")))
+         {
+             const int uid = ipc->getCallingUid();
+             LOGE("Permission Denial: "
+                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
+             return PERMISSION_DENIED;
+         }
+     }
+   
+     switch(code) {
+        case CREATE_SURFACE: {
+            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
+            surface_data_t params;
+            int32_t pid = data.readInt32();
+            DisplayID display = data.readInt32();
+            uint32_t w = data.readInt32();
+            uint32_t h = data.readInt32();
+            PixelFormat format = data.readInt32();
+            uint32_t flags = data.readInt32();
+            sp<ISurface> s = createSurface(&params, pid, display, w, h, format, flags);
+            params.writeToParcel(reply);
+            reply->writeStrongBinder(s->asBinder());
+            return NO_ERROR;
+        } break;
+        case DESTROY_SURFACE: {
+            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
+            reply->writeInt32( destroySurface( data.readInt32() ) );
+            return NO_ERROR;
+        } break;
+        case SET_STATE: {
+            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
+            int32_t count = data.readInt32();
+            layer_state_t* states = new layer_state_t[count];
+            for (int i=0 ; i<count ; i++)
+                states[i].read(data);
+            status_t err = setState(count, states);
+            delete [] states;
+            reply->writeInt32(err);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------
+
+status_t ISurfaceFlingerClient::surface_data_t::readFromParcel(const Parcel& parcel)
+{
+    token = parcel.readInt32();
+    identity  = parcel.readInt32();
+    heap[0] = interface_cast<IMemoryHeap>(parcel.readStrongBinder());
+    heap[1] = interface_cast<IMemoryHeap>(parcel.readStrongBinder());
+    return NO_ERROR;
+}
+
+status_t ISurfaceFlingerClient::surface_data_t::writeToParcel(Parcel* parcel) const
+{
+    parcel->writeInt32(token);
+    parcel->writeInt32(identity);
+    parcel->writeStrongBinder(heap[0]!=0 ? heap[0]->asBinder() : NULL);
+    parcel->writeStrongBinder(heap[1]!=0 ? heap[1]->asBinder() : NULL);
+    return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/libs/ui/KeyCharacterMap.cpp b/libs/ui/KeyCharacterMap.cpp
new file mode 100644
index 0000000..e891181
--- /dev/null
+++ b/libs/ui/KeyCharacterMap.cpp
@@ -0,0 +1,263 @@
+#define LOG_TAG "KeyCharacterMap"
+
+#include <ui/KeyCharacterMap.h>
+#include <cutils/properties.h>
+
+#include <utils/Log.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <string.h>
+
+struct Header
+{
+    char magic[8];
+    unsigned int endian;
+    unsigned int version;
+    unsigned int keycount;
+    unsigned char kbdtype;
+    char padding[11];
+};
+
+KeyCharacterMap::KeyCharacterMap()
+{
+}
+
+KeyCharacterMap::~KeyCharacterMap()
+{
+    free(m_keys);
+}
+
+unsigned short
+KeyCharacterMap::get(int keycode, int meta)
+{
+    Key* k = find_key(keycode);
+    if (k != NULL) {
+        return k->data[meta & META_MASK];
+    }
+    return 0;
+}
+
+unsigned short
+KeyCharacterMap::getNumber(int keycode)
+{
+    Key* k = find_key(keycode);
+    if (k != NULL) {
+        return k->number;
+    }
+    return 0;
+}
+
+unsigned short
+KeyCharacterMap::getMatch(int keycode, const unsigned short* chars,
+                          int charsize, uint32_t modifiers)
+{
+    Key* k = find_key(keycode);
+    modifiers &= 3; // ignore the SYM key because we don't have keymap entries for it
+    if (k != NULL) {
+        const uint16_t* data = k->data;
+        for (int j=0; j<charsize; j++) {
+            uint16_t c = chars[j];
+            for (int i=0; i<(META_MASK + 1); i++) {
+                if ((modifiers == 0) || ((modifiers & i) != 0)) {
+                    if (c == data[i]) {
+                        return c;
+                    }
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+unsigned short
+KeyCharacterMap::getDisplayLabel(int keycode)
+{
+    Key* k = find_key(keycode);
+    if (k != NULL) {
+        return k->display_label;
+    }
+    return 0;
+}
+
+bool
+KeyCharacterMap::getKeyData(int keycode, unsigned short *displayLabel,
+                            unsigned short *number, unsigned short* results)
+{
+    Key* k = find_key(keycode);
+    if (k != NULL) {
+        memcpy(results, k->data, sizeof(short)*(META_MASK + 1));
+        *number = k->number;
+        *displayLabel = k->display_label;
+        return true;
+    } else {
+        return false;
+    }
+}
+
+bool
+KeyCharacterMap::find_char(uint16_t c, uint32_t* key, uint32_t* mods)
+{
+    uint32_t N = m_keyCount;
+    for (int j=0; j<(META_MASK + 1); j++) {
+        Key const* keys = m_keys;
+        for (uint32_t i=0; i<N; i++) {
+            if (keys->data[j] == c) {
+                *key = keys->keycode;
+                *mods = j;
+                return true;
+            }
+            keys++;
+        }
+    }
+    return false;
+}
+
+bool
+KeyCharacterMap::getEvents(uint16_t* chars, size_t len,
+                           Vector<int32_t>* keys, Vector<uint32_t>* modifiers)
+{
+    for (size_t i=0; i<len; i++) {
+        uint32_t k, mods;
+        if (find_char(chars[i], &k, &mods)) {
+            keys->add(k);
+            modifiers->add(mods);
+        } else {
+            return false;
+        }
+    }
+    return true;
+}
+
+KeyCharacterMap::Key*
+KeyCharacterMap::find_key(int keycode)
+{
+    Key* keys = m_keys;
+    int low = 0;
+    int high = m_keyCount - 1;
+    int mid;
+    int n;
+    while (low <= high) {
+        mid = (low + high) / 2;
+        n = keys[mid].keycode;
+        if (keycode < n) {
+            high = mid - 1;
+        } else if (keycode > n) {
+            low = mid + 1;
+        } else {
+            return keys + mid;
+        }
+    }
+    return NULL;
+}
+
+KeyCharacterMap*
+KeyCharacterMap::load(int id)
+{
+    KeyCharacterMap* rv = NULL;
+    char path[PATH_MAX];
+    char propName[100];
+    char dev[PROPERTY_VALUE_MAX];
+    char tmpfn[PROPERTY_VALUE_MAX];
+    int err;
+    const char* root = getenv("ANDROID_ROOT");
+
+    sprintf(propName, "hw.keyboards.%u.devname", id);
+    err = property_get(propName, dev, "");
+    if (err > 0) {
+        // replace all the spaces with underscores
+        strcpy(tmpfn, dev);
+        for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' '))
+            *p = '_';
+        snprintf(path, sizeof(path), "%s/usr/keychars/%s.kcm.bin", root, tmpfn);
+        //LOGD("load: dev='%s' path='%s'\n", dev, path);
+        rv = try_file(path);
+        if (rv != NULL) {
+            return rv;
+        }
+        LOGW("Error loading keycharmap file '%s'. %s='%s'", path, propName, dev);
+    } else {
+        LOGW("No keyboard for id %d", id);
+    }
+
+    snprintf(path, sizeof(path), "%s/usr/keychars/qwerty.kcm.bin", root);
+    rv = try_file(path);
+    if (rv == NULL) {
+        LOGE("Can't find any keycharmaps (also tried %s)", path);
+        return NULL;
+    }
+    LOGW("Using default keymap: %s", path);
+
+    return rv;
+}
+
+KeyCharacterMap*
+KeyCharacterMap::try_file(const char* filename)
+{
+    KeyCharacterMap* rv = NULL;
+    Key* keys;
+    int fd;
+    off_t filesize;
+    Header header;
+    int err;
+    
+    fd = open(filename, O_RDONLY);
+    if (fd == -1) {
+        LOGW("Can't open keycharmap file");
+        return NULL;
+    }
+
+    filesize = lseek(fd, 0, SEEK_END);
+    lseek(fd, 0, SEEK_SET);
+
+    // validate the header
+    if (filesize <= (off_t)sizeof(header)) {
+        LOGW("Bad keycharmap - filesize=%d\n", (int)filesize);
+        goto cleanup1;
+    }
+
+    err = read(fd, &header, sizeof(header));
+    if (err == -1) {
+        LOGW("Error reading keycharmap file");
+        goto cleanup1;
+    }
+
+    if (0 != memcmp(header.magic, "keychar", 8)) {
+        LOGW("Bad keycharmap magic token");
+        goto cleanup1;
+    }
+    if (header.endian != 0x12345678) {
+        LOGW("Bad keycharmap endians");
+        goto cleanup1;
+    }
+    if ((header.version & 0xff) != 2) {
+        LOGW("Only support keycharmap version 2 (got 0x%08x)", header.version);
+        goto cleanup1;
+    }
+    if (filesize < (off_t)(sizeof(Header)+(sizeof(Key)*header.keycount))) {
+        LOGW("Bad keycharmap file size\n");
+        goto cleanup1;
+    }
+
+    // read the key data
+    keys = (Key*)malloc(sizeof(Key)*header.keycount);
+    err = read(fd, keys, sizeof(Key)*header.keycount);
+    if (err == -1) {
+        LOGW("Error reading keycharmap file");
+        free(keys);
+        goto cleanup1;
+    }
+
+    // return the object
+    rv = new KeyCharacterMap;
+    rv->m_keyCount = header.keycount;
+    rv->m_keys = keys;
+    rv->m_type = header.kbdtype;
+
+cleanup1:
+    close(fd);
+
+    return rv;
+}
diff --git a/libs/ui/KeyLayoutMap.cpp b/libs/ui/KeyLayoutMap.cpp
new file mode 100644
index 0000000..15ae54c
--- /dev/null
+++ b/libs/ui/KeyLayoutMap.cpp
@@ -0,0 +1,235 @@
+#define LOG_TAG "KeyLayoutMap"
+
+#include "KeyLayoutMap.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <utils/String8.h>
+#include <stdlib.h>
+#include <ui/KeycodeLabels.h>
+#include <utils/Log.h>
+
+namespace android {
+
+KeyLayoutMap::KeyLayoutMap()
+    :m_status(NO_INIT),
+     m_keys()
+{
+}
+
+KeyLayoutMap::~KeyLayoutMap()
+{
+}
+
+static String8
+next_token(char const** p, int *line)
+{
+    bool begun = false;
+    const char* begin = *p;
+    const char* end = *p;
+    while (true) {
+        if (*end == '\n') {
+            (*line)++;
+        }
+        switch (*end)
+        {
+            case '#':
+                if (begun) {
+                    *p = end;
+                    return String8(begin, end-begin);
+                } else {
+                    do {
+                        begin++;
+                        end++;
+                    } while (*begin != '\0' && *begin != '\n');
+                }
+            case '\0':
+            case ' ':
+            case '\n':
+            case '\r':
+            case '\t':
+                if (begun || (*end == '\0')) {
+                    *p = end;
+                    return String8(begin, end-begin);
+                } else {
+                    begin++;
+                    end++;
+                    break;
+                }
+            default:
+                end++;
+                begun = true;
+        }
+    }
+}
+
+static int32_t
+token_to_value(const char *literal, const KeycodeLabel *list)
+{
+    while (list->literal) {
+        if (0 == strcmp(literal, list->literal)) {
+            return list->value;
+        }
+        list++;
+    }
+    return list->value;
+}
+
+status_t
+KeyLayoutMap::load(const char* filename)
+{
+    int fd = open(filename, O_RDONLY);
+    if (fd < 0) {
+        LOGE("error opening file=%s err=%s\n", filename, strerror(errno));
+        m_status = errno;
+        return errno;
+    }
+
+    off_t len = lseek(fd, 0, SEEK_END);
+    off_t errlen = lseek(fd, 0, SEEK_SET);
+    if (len < 0 || errlen < 0) {
+        close(fd);
+        LOGE("error seeking file=%s err=%s\n", filename, strerror(errno));
+        m_status = errno;
+        return errno;
+    }
+
+    char* buf = (char*)malloc(len+1);
+    if (read(fd, buf, len) != len) {
+        LOGE("error reading file=%s err=%s\n", filename, strerror(errno));
+        m_status = errno != 0 ? errno : ((int)NOT_ENOUGH_DATA);
+        return errno != 0 ? errno : ((int)NOT_ENOUGH_DATA);
+    }
+    errno = 0;
+    buf[len] = '\0';
+
+    int32_t scancode = -1;
+    int32_t keycode = -1;
+    uint32_t flags = 0;
+    uint32_t tmp;
+    char* end;
+    status_t err = NO_ERROR;
+    int line = 1;
+    char const* p = buf;
+    enum { BEGIN, SCANCODE, KEYCODE, FLAG } state = BEGIN;
+    while (true) {
+        String8 token = next_token(&p, &line);
+        if (*p == '\0') {
+            break;
+        }
+        switch (state)
+        {
+            case BEGIN:
+                if (token == "key") {
+                    state = SCANCODE;
+                } else {
+                    LOGE("%s:%d: expected key, got '%s'\n", filename, line,
+                            token.string());
+                    err = BAD_VALUE;
+                    goto done;
+                }
+                break;
+            case SCANCODE:
+                scancode = strtol(token.string(), &end, 0);
+                if (*end != '\0') {
+                    LOGE("%s:%d: expected scancode (a number), got '%s'\n",
+                            filename, line, token.string());
+                    goto done;
+                }
+                //LOGI("%s:%d: got scancode %d\n", filename, line, scancode );
+                state = KEYCODE;
+                break;
+            case KEYCODE:
+                keycode = token_to_value(token.string(), KEYCODES);
+                //LOGI("%s:%d: got keycode %d for %s\n", filename, line, keycode, token.string() );
+                if (keycode == 0) {
+                    LOGE("%s:%d: expected keycode, got '%s'\n",
+                            filename, line, token.string());
+                    goto done;
+                }
+                state = FLAG;
+                break;
+            case FLAG:
+                if (token == "key") {
+                    if (scancode != -1) {
+                        //LOGI("got key decl scancode=%d keycode=%d"
+                        //       " flags=0x%08x\n", scancode, keycode, flags);
+                        Key k = { keycode, flags };
+                        m_keys.add(scancode, k);
+                        state = SCANCODE;
+                        scancode = -1;
+                        keycode = -1;
+                        flags = 0;
+                        break;
+                    }
+                }
+                tmp = token_to_value(token.string(), FLAGS);
+                //LOGI("%s:%d: got flags %x for %s\n", filename, line, tmp, token.string() );
+                if (tmp == 0) {
+                    LOGE("%s:%d: expected flag, got '%s'\n",
+                            filename, line, token.string());
+                    goto done;
+                }
+                flags |= tmp;
+                break;
+        }
+    }
+    if (state == FLAG && scancode != -1 ) {
+        //LOGI("got key decl scancode=%d keycode=%d"
+        //       " flags=0x%08x\n", scancode, keycode, flags);
+        Key k = { keycode, flags };
+        m_keys.add(scancode, k);
+    }
+
+done:
+    free(buf);
+    close(fd);
+
+    m_status = err;
+    return err;
+}
+
+status_t
+KeyLayoutMap::map(int32_t scancode, int32_t *keycode, uint32_t *flags) const
+{
+    if (m_status != NO_ERROR) {
+        return m_status;
+    }
+
+    ssize_t index = m_keys.indexOfKey(scancode);
+    if (index < 0) {
+        //LOGW("couldn't map scancode=%d\n", scancode);
+        return NAME_NOT_FOUND;
+    }
+
+    const Key& k = m_keys.valueAt(index);
+
+    *keycode = k.keycode;
+    *flags = k.flags;
+
+    //LOGD("mapped scancode=%d to keycode=%d flags=0x%08x\n", scancode,
+    //        keycode, flags);
+
+    return NO_ERROR;
+}
+
+status_t
+KeyLayoutMap::findScancodes(int32_t keycode, Vector<int32_t>* outScancodes) const
+{
+    if (m_status != NO_ERROR) {
+        return m_status;
+    }
+    
+    const size_t N = m_keys.size();
+    for (size_t i=0; i<N; i++) {
+        if (m_keys.valueAt(i).keycode == keycode) {
+            outScancodes->add(m_keys.keyAt(i));
+        }
+    }
+    
+    return NO_ERROR;
+}
+
+};
diff --git a/libs/ui/KeyLayoutMap.h b/libs/ui/KeyLayoutMap.h
new file mode 100644
index 0000000..43f84ce
--- /dev/null
+++ b/libs/ui/KeyLayoutMap.h
@@ -0,0 +1,31 @@
+#ifndef KEYLAYOUTMAP_H
+#define KEYLAYOUTMAP_H
+
+#include <utils/KeyedVector.h>
+
+namespace android {
+
+class KeyLayoutMap
+{
+public:
+    KeyLayoutMap();
+    ~KeyLayoutMap();
+
+    status_t load(const char* filename);
+
+    status_t map(int32_t scancode, int32_t *keycode, uint32_t *flags) const;
+    status_t findScancodes(int32_t keycode, Vector<int32_t>* outScancodes) const;
+
+private:
+    struct Key {
+        int32_t keycode;
+        uint32_t flags;
+    };
+
+    status_t m_status;
+    KeyedVector<int32_t,Key> m_keys;
+};
+
+};
+
+#endif // KEYLAYOUTMAP_H
diff --git a/libs/ui/LayerState.cpp b/libs/ui/LayerState.cpp
new file mode 100644
index 0000000..0b6374b
--- /dev/null
+++ b/libs/ui/LayerState.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#include <utils/Errors.h>
+#include <utils/Parcel.h>
+#include <private/ui/LayerState.h>
+
+namespace android {
+
+status_t layer_state_t::write(Parcel& output) const
+{
+    size_t size = sizeof(layer_state_t);
+
+    //output.writeStrongBinder(surface->asBinder());
+    //size -= sizeof(surface);
+
+    transparentRegion.write(output);
+    size -= sizeof(transparentRegion);
+    
+    output.write(this, size);
+    
+    return NO_ERROR;
+}
+
+status_t layer_state_t::read(const Parcel& input)
+{
+    size_t size = sizeof(layer_state_t);
+
+    //surface = interface_cast<ISurface>(input.readStrongBinder());
+    //size -= sizeof(surface);
+
+    transparentRegion.read(input);
+    size -= sizeof(transparentRegion);
+
+    input.read(this, size);
+    
+    return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/libs/ui/MODULE_LICENSE_APACHE2 b/libs/ui/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/ui/MODULE_LICENSE_APACHE2
diff --git a/libs/ui/NOTICE b/libs/ui/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/libs/ui/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp
new file mode 100644
index 0000000..b236edc
--- /dev/null
+++ b/libs/ui/Overlay.cpp
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+
+#include <utils/IMemory.h>
+#include <utils/Parcel.h>
+#include <utils/Errors.h>
+#include <utils/MemoryHeapBase.h>
+
+#include <ui/IOverlay.h>
+#include <ui/Overlay.h>
+
+#include <hardware/overlay.h>
+
+namespace android {
+
+Overlay::Overlay(const sp<OverlayRef>& overlayRef)
+    : mOverlayRef(overlayRef), mOverlayData(0), mStatus(NO_INIT)
+{
+    mOverlayData = NULL;
+    hw_module_t const* module;
+    if (overlayRef != 0) {
+        if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
+            if (overlay_data_open(module, &mOverlayData) == NO_ERROR) {
+                mStatus = mOverlayData->initialize(mOverlayData,
+                        overlayRef->mOverlayHandle);
+            }
+        }
+    }
+}
+
+Overlay::~Overlay() {
+    if (mOverlayData) {
+        overlay_data_close(mOverlayData);
+    }
+}
+
+status_t Overlay::dequeueBuffer(overlay_buffer_t* buffer)
+{
+    if (mStatus != NO_ERROR) return mStatus;
+    return  mOverlayData->dequeueBuffer(mOverlayData, buffer);
+}
+
+status_t Overlay::queueBuffer(overlay_buffer_t buffer)
+{
+    if (mStatus != NO_ERROR) return mStatus;
+    return mOverlayData->queueBuffer(mOverlayData, buffer);
+}
+
+int32_t Overlay::getBufferCount() const
+{
+    if (mStatus != NO_ERROR) return mStatus;
+    return mOverlayData->getBufferCount(mOverlayData);
+}
+
+void* Overlay::getBufferAddress(overlay_buffer_t buffer)
+{
+    if (mStatus != NO_ERROR) return NULL;
+    return mOverlayData->getBufferAddress(mOverlayData, buffer);
+}
+
+void Overlay::destroy() {  
+    if (mStatus != NO_ERROR) return;
+    mOverlayRef->mOverlayChannel->destroy();
+}
+
+status_t Overlay::getStatus() const {
+    return mStatus;
+}
+
+overlay_handle_t Overlay::getHandleRef() const {
+    if (mStatus != NO_ERROR) return NULL;
+    return mOverlayRef->mOverlayHandle;
+}
+
+uint32_t Overlay::getWidth() const {
+    if (mStatus != NO_ERROR) return 0;
+    return mOverlayRef->mWidth;
+}
+
+uint32_t Overlay::getHeight() const {
+    if (mStatus != NO_ERROR) return 0;
+    return mOverlayRef->mHeight;
+}
+
+int32_t Overlay::getFormat() const {
+    if (mStatus != NO_ERROR) return -1;
+    return mOverlayRef->mFormat;
+}
+
+int32_t Overlay::getWidthStride() const {
+    if (mStatus != NO_ERROR) return 0;
+    return mOverlayRef->mWidthStride;
+}
+
+int32_t Overlay::getHeightStride() const {
+    if (mStatus != NO_ERROR) return 0;
+    return mOverlayRef->mHeightStride;
+}
+// ----------------------------------------------------------------------------
+
+OverlayRef::OverlayRef() 
+ : mOverlayHandle(0),
+    mWidth(0), mHeight(0), mFormat(0), mWidthStride(0), mHeightStride(0),
+    mOwnHandle(true)
+{    
+}
+
+OverlayRef::OverlayRef(overlay_handle_t handle, const sp<IOverlay>& channel,
+         uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs)
+    : mOverlayHandle(handle), mOverlayChannel(channel),
+    mWidth(w), mHeight(h), mFormat(f), mWidthStride(ws), mHeightStride(hs),
+    mOwnHandle(false)
+{
+}
+
+OverlayRef::~OverlayRef()
+{
+    if (mOwnHandle) {
+        /* FIXME: handles should be promoted to "real" API and be handled by 
+         * the framework */
+        for (int i=0 ; i<mOverlayHandle->numFds ; i++) {
+            close(mOverlayHandle->data[i]);
+        }
+        free((void*)mOverlayHandle);
+    }
+}
+
+sp<OverlayRef> OverlayRef::readFromParcel(const Parcel& data) {
+    sp<OverlayRef> result;
+    sp<IOverlay> overlay = IOverlay::asInterface(data.readStrongBinder());
+    if (overlay != NULL) {
+        uint32_t w = data.readInt32();
+        uint32_t h = data.readInt32();
+        uint32_t f = data.readInt32();
+        uint32_t ws = data.readInt32();
+        uint32_t hs = data.readInt32();
+        native_handle* handle = data.readNativeHandle(NULL, NULL);
+
+        result = new OverlayRef();
+        result->mOverlayHandle = handle;
+        result->mOverlayChannel = overlay;
+        result->mWidth = w;
+        result->mHeight = h;
+        result->mFormat = f;
+        result->mWidthStride = ws;
+        result->mHeightStride = hs;
+    }
+    return result;
+}
+
+status_t OverlayRef::writeToParcel(Parcel* reply, const sp<OverlayRef>& o) {
+    if (o != NULL) {
+        reply->writeStrongBinder(o->mOverlayChannel->asBinder());
+        reply->writeInt32(o->mWidth);
+        reply->writeInt32(o->mHeight);
+        reply->writeInt32(o->mFormat);
+        reply->writeInt32(o->mWidthStride);
+        reply->writeInt32(o->mHeightStride);
+        reply->writeNativeHandle(*(o->mOverlayHandle));
+    } else {
+        reply->writeStrongBinder(NULL);
+    }
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
new file mode 100644
index 0000000..b65ed97
--- /dev/null
+++ b/libs/ui/PixelFormat.cpp
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+#include <ui/PixelFormat.h>
+#include <pixelflinger/format.h>
+
+namespace android {
+
+size_t PixelFormatInfo::getScanlineSize(unsigned int width) const
+{
+    size_t size;
+    if ((components >= 6) && (components <= 8)) {
+        // YCbCr formats are differents.
+        size = (width * bitsPerPixel)>>3;
+    } else {
+        size = width * bytesPerPixel;
+    }
+    return size;
+}
+
+ssize_t bytesPerPixel(PixelFormat format)
+{
+    PixelFormatInfo info;
+    status_t err = getPixelFormatInfo(format, &info);
+    return (err < 0) ? err : info.bytesPerPixel;
+}
+
+ssize_t bitsPerPixel(PixelFormat format)
+{
+    PixelFormatInfo info;
+    status_t err = getPixelFormatInfo(format, &info);
+    return (err < 0) ? err : info.bitsPerPixel;
+}
+
+status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info)
+{
+    if (format < 0)
+        return BAD_VALUE;
+
+    if (info->version != sizeof(PixelFormatInfo))
+        return INVALID_OPERATION;
+
+    size_t numEntries;
+    const GGLFormat *i = gglGetPixelFormatTable(&numEntries) + format;
+    bool valid = uint32_t(format) < numEntries;
+    if (!valid) {
+        return BAD_INDEX;
+    }
+    
+    #define COMPONENT(name) \ 
+        case GGL_##name: info->components = PixelFormatInfo::name; break;
+    
+    switch (i->components) {
+        COMPONENT(ALPHA)
+        COMPONENT(RGB)
+        COMPONENT(RGBA)
+        COMPONENT(LUMINANCE)
+        COMPONENT(LUMINANCE_ALPHA)
+        COMPONENT(Y_CB_CR_SP)
+        COMPONENT(Y_CB_CR_P)
+        COMPONENT(Y_CB_CR_I)
+        default:
+            return BAD_INDEX;
+    }
+    
+    #undef COMPONENT
+    
+    info->format = format;
+    info->bytesPerPixel = i->size;
+    info->bitsPerPixel  = i->bitsPerPixel;
+    info->h_alpha       = i->ah;
+    info->l_alpha       = i->al;
+    info->h_red         = i->rh;
+    info->l_red         = i->rl;
+    info->h_green       = i->gh;
+    info->l_green       = i->gl;
+    info->h_blue        = i->bh;
+    info->l_blue        = i->bl;
+
+    return NO_ERROR;
+}
+
+}; // namespace android
+
diff --git a/libs/ui/Point.cpp b/libs/ui/Point.cpp
new file mode 100644
index 0000000..438d49f
--- /dev/null
+++ b/libs/ui/Point.cpp
@@ -0,0 +1,11 @@
+/*
+ *  Point.cpp
+ *  Android
+ *
+ *  Created on 11/16/2006.
+ *  Copyright 2005 The Android Open Source Project
+ *
+ */
+
+#include <ui/Point.h>
+
diff --git a/libs/ui/Rect.cpp b/libs/ui/Rect.cpp
new file mode 100644
index 0000000..99e68bb
--- /dev/null
+++ b/libs/ui/Rect.cpp
@@ -0,0 +1,86 @@
+/*
+ *  Rect.cpp
+ *  Android
+ *
+ *  Created on 10/14/05.
+ *  Copyright 2005 The Android Open Source Project
+ *
+ */
+
+#include <ui/Rect.h>
+
+namespace android {
+
+inline int min(int a, int b) {
+    return (a<b) ? a : b;
+}
+
+inline int max(int a, int b) {
+    return (a>b) ? a : b;
+}
+
+void Rect::makeInvalid() {
+    left = 0;
+    top = 0;
+    right = -1;
+    bottom = -1;
+}
+
+bool Rect::operator < (const Rect& rhs) const
+{
+    if (top<rhs.top) {
+        return true;
+    } else if (top == rhs.top) {
+        if (left < rhs.left) {
+            return true;
+        } else if (left == rhs.left) {
+            if (bottom<rhs.bottom) {
+                return true;
+            } else if (bottom == rhs.bottom) {
+                if (right<rhs.right) {
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+Rect& Rect::offsetTo(int x, int y)
+{
+    right -= left - x;
+    bottom -= top - y;
+    left = x;
+    top = y;
+    return *this;
+}
+
+Rect& Rect::offsetBy(int x, int y)
+{
+    left += x;
+    top  += y;
+    right+= x;
+    bottom+=y;
+    return *this;
+}
+
+Rect Rect::operator + (const Point& rhs) const
+{
+    return Rect(left+rhs.x, top+rhs.y, right+rhs.x, bottom+rhs.y); 
+}
+
+Rect Rect::operator - (const Point& rhs) const
+{
+    return Rect(left-rhs.x, top-rhs.y, right-rhs.x, bottom-rhs.y); 
+}
+
+bool Rect::intersect(const Rect& with, Rect* result) const
+{
+    result->left    = max(left, with.left);
+    result->top     = max(top, with.top);
+    result->right   = min(right, with.right);
+    result->bottom  = min(bottom, with.bottom);
+    return !(result->isEmpty());
+}
+
+}; // namespace android
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
new file mode 100644
index 0000000..26e694a
--- /dev/null
+++ b/libs/ui/Region.cpp
@@ -0,0 +1,313 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "Region"
+
+#include <stdio.h>
+#include <utils/Atomic.h>
+#include <utils/Debug.h>
+#include <utils/String8.h>
+#include <ui/Region.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+Region::Region()
+{
+}
+
+Region::Region(const Region& rhs)
+    : mRegion(rhs.mRegion)
+{
+}
+
+Region::Region(const SkRegion& rhs)
+    : mRegion(rhs)
+{
+}
+
+Region::~Region()
+{
+}
+
+Region::Region(const Rect& rhs)
+{
+    set(rhs);
+}
+
+Region::Region(const Parcel& parcel)
+{
+    read(parcel);
+}
+
+Region::Region(const void* buffer)
+{
+    read(buffer);
+}
+
+Region& Region::operator = (const Region& rhs)
+{
+    mRegion = rhs.mRegion;
+    return *this;
+}
+
+const SkRegion& Region::toSkRegion() const
+{
+    return mRegion;
+}
+
+Rect Region::bounds() const
+{
+    const SkIRect& b(mRegion.getBounds());
+    return Rect(b.fLeft, b.fTop, b.fRight, b.fBottom);
+}
+
+void Region::clear()
+{
+    mRegion.setEmpty();
+}
+
+void Region::set(const Rect& r)
+{
+    SkIRect ir;
+    ir.set(r.left, r.top, r.right, r.bottom);
+    mRegion.setRect(ir);
+}
+
+// ----------------------------------------------------------------------------
+
+Region& Region::orSelf(const Rect& r)
+{
+    SkIRect ir;
+    ir.set(r.left, r.top, r.right, r.bottom);
+    mRegion.op(ir, SkRegion::kUnion_Op);
+    return *this;
+}
+
+Region& Region::andSelf(const Rect& r)
+{
+    SkIRect ir;
+    ir.set(r.left, r.top, r.right, r.bottom);
+    mRegion.op(ir, SkRegion::kIntersect_Op);
+    return *this;
+}
+
+// ----------------------------------------------------------------------------
+
+Region& Region::orSelf(const Region& rhs) {
+    mRegion.op(rhs.mRegion, SkRegion::kUnion_Op);
+    return *this;
+}
+
+Region& Region::andSelf(const Region& rhs) {
+    mRegion.op(rhs.mRegion, SkRegion::kIntersect_Op);
+    return *this;
+}
+
+Region& Region::subtractSelf(const Region& rhs) {
+    mRegion.op(rhs.mRegion, SkRegion::kDifference_Op);
+    return *this;
+}
+
+Region& Region::translateSelf(int x, int y) {
+    if (x|y) mRegion.translate(x, y);
+    return *this;
+}
+
+Region Region::merge(const Region& rhs) const {
+    Region result;
+    result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kUnion_Op);
+    return result;
+}
+
+Region Region::intersect(const Region& rhs) const {
+    Region result;
+    result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kIntersect_Op);
+    return result;
+}
+
+Region Region::subtract(const Region& rhs) const {
+    Region result;
+    result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kDifference_Op);
+    return result;
+}
+
+Region Region::translate(int x, int y) const {
+    Region result;
+    mRegion.translate(x, y, &result.mRegion);
+    return result;
+}
+
+// ----------------------------------------------------------------------------
+
+Region& Region::orSelf(const Region& rhs, int dx, int dy) {
+    SkRegion r(rhs.mRegion);
+    r.translate(dx, dy);
+    mRegion.op(r, SkRegion::kUnion_Op);
+    return *this;
+}
+
+Region& Region::andSelf(const Region& rhs, int dx, int dy) {
+    SkRegion r(rhs.mRegion);
+    r.translate(dx, dy);
+    mRegion.op(r, SkRegion::kIntersect_Op);
+    return *this;
+}
+
+Region& Region::subtractSelf(const Region& rhs, int dx, int dy) {
+    SkRegion r(rhs.mRegion);
+    r.translate(dx, dy);
+    mRegion.op(r, SkRegion::kDifference_Op);
+    return *this;
+}
+
+Region Region::merge(const Region& rhs, int dx, int dy) const {
+    Region result;
+    SkRegion r(rhs.mRegion);
+    r.translate(dx, dy);
+    result.mRegion.op(mRegion, r, SkRegion::kUnion_Op);
+    return result;
+}
+
+Region Region::intersect(const Region& rhs, int dx, int dy) const {
+    Region result;
+    SkRegion r(rhs.mRegion);
+    r.translate(dx, dy);
+    result.mRegion.op(mRegion, r, SkRegion::kIntersect_Op);
+    return result;
+}
+
+Region Region::subtract(const Region& rhs, int dx, int dy) const {
+    Region result;
+    SkRegion r(rhs.mRegion);
+    r.translate(dx, dy);
+    result.mRegion.op(mRegion, r, SkRegion::kDifference_Op);
+    return result;
+}
+
+// ----------------------------------------------------------------------------
+
+Region::iterator::iterator(const Region& r)
+    : mIt(r.mRegion)
+{
+}
+
+int Region::iterator::iterate(Rect* rect)
+{
+    if (mIt.done())
+        return 0;
+    const SkIRect& r(mIt.rect());
+    rect->left  = r.fLeft;
+    rect->top   = r.fTop;
+    rect->right = r.fRight;
+    rect->bottom= r.fBottom;
+    mIt.next();
+    return 1;
+}
+
+// ----------------------------------------------------------------------------
+
+// we write a 4byte size ahead of the actual region, so we know how much we'll need for reading
+
+status_t Region::write(Parcel& parcel) const
+{
+    int32_t size = mRegion.flatten(NULL);
+    parcel.writeInt32(size);
+    mRegion.flatten(parcel.writeInplace(size));
+    return NO_ERROR;
+}
+
+status_t Region::read(const Parcel& parcel)
+{
+    size_t size = parcel.readInt32();
+    mRegion.unflatten(parcel.readInplace(size));
+    return NO_ERROR;
+}
+
+ssize_t Region::write(void* buffer, size_t size) const
+{
+    size_t sizeNeeded = mRegion.flatten(NULL);
+    if (sizeNeeded > size) return NO_MEMORY;
+    return mRegion.flatten(buffer);
+}
+
+ssize_t Region::read(const void* buffer)
+{
+    return mRegion.unflatten(buffer);
+}
+
+ssize_t Region::writeEmpty(void* buffer, size_t size)
+{
+    if (size < 4) return NO_MEMORY;
+    // this needs to stay in sync with SkRegion
+    *static_cast<int32_t*>(buffer) = -1;
+    return 4;
+}
+
+bool Region::isEmpty(void* buffer)
+{
+    // this needs to stay in sync with SkRegion
+    return *static_cast<int32_t*>(buffer) == -1;
+}
+
+size_t Region::rects(Vector<Rect>& rectList) const
+{
+    rectList.clear();
+    if (!isEmpty()) {
+        SkRegion::Iterator iterator(mRegion);
+        while( !iterator.done() ) {
+            const SkIRect& ir(iterator.rect());
+            rectList.push(Rect(ir.fLeft, ir.fTop, ir.fRight, ir.fBottom));
+            iterator.next();
+        }
+    }
+    return rectList.size();
+}
+
+void Region::dump(String8& out, const char* what, uint32_t flags) const
+{
+    (void)flags;
+    Vector<Rect> r;
+    rects(r);
+    
+    size_t SIZE = 256;
+    char buffer[SIZE];
+    
+    snprintf(buffer, SIZE, "  Region %s (this=%p, count=%d)\n", what, this, r.size());
+    out.append(buffer);
+    for (size_t i=0 ; i<r.size() ; i++) {
+        snprintf(buffer, SIZE, "    [%3d, %3d, %3d, %3d]\n",
+            r[i].left, r[i].top,r[i].right,r[i].bottom);
+        out.append(buffer);
+    }
+}
+
+void Region::dump(const char* what, uint32_t flags) const
+{
+    (void)flags;
+    Vector<Rect> r;
+    rects(r);
+    LOGD("  Region %s (this=%p, count=%d)\n", what, this, r.size());
+    for (size_t i=0 ; i<r.size() ; i++) {
+        LOGD("    [%3d, %3d, %3d, %3d]\n",
+            r[i].left, r[i].top,r[i].right,r[i].bottom);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
new file mode 100644
index 0000000..4ea9ae2
--- /dev/null
+++ b/libs/ui/Surface.cpp
@@ -0,0 +1,256 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "Surface"
+
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <utils/IPCThreadState.h>
+#include <utils/IMemory.h>
+#include <utils/Log.h>
+
+#include <ui/ISurface.h>
+#include <ui/Surface.h>
+#include <ui/SurfaceComposerClient.h>
+#include <ui/Rect.h>
+
+#include <private/ui/SharedState.h>
+#include <private/ui/LayerState.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+Surface::Surface(const sp<SurfaceComposerClient>& client, 
+        const sp<ISurface>& surface,
+        const ISurfaceFlingerClient::surface_data_t& data,
+        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
+        bool owner)
+    : mClient(client), mSurface(surface),
+      mToken(data.token), mIdentity(data.identity),
+      mFormat(format), mFlags(flags), mOwner(owner)
+{
+    mSwapRectangle.makeInvalid();
+    mSurfaceHeapBase[0] = 0;
+    mSurfaceHeapBase[1] = 0;
+    mHeap[0] = data.heap[0]; 
+    mHeap[1] = data.heap[1];
+}
+
+Surface::Surface(Surface const* rhs)
+    : mOwner(false)
+{
+    mToken   = rhs->mToken;
+    mIdentity= rhs->mIdentity;
+    mClient  = rhs->mClient;
+    mSurface = rhs->mSurface;
+    mHeap[0] = rhs->mHeap[0];
+    mHeap[1] = rhs->mHeap[1];
+    mFormat  = rhs->mFormat;
+    mFlags   = rhs->mFlags;
+    mSurfaceHeapBase[0] = rhs->mSurfaceHeapBase[0];
+    mSurfaceHeapBase[1] = rhs->mSurfaceHeapBase[1];
+    mSwapRectangle.makeInvalid();
+}
+
+Surface::~Surface()
+{
+    if (mOwner && mToken>=0 && mClient!=0) {
+        mClient->destroySurface(mToken);
+    }
+    mClient.clear();
+    mSurface.clear();
+    mHeap[0].clear();
+    mHeap[1].clear();
+    IPCThreadState::self()->flushCommands();
+}
+
+sp<Surface> Surface::dup() const
+{
+    Surface const * r = this;
+    if (this && mOwner) {
+        // the only reason we need to do this is because of Java's garbage
+        // collector: because we're creating a copy of the Surface
+        // instead of a reference, we can garantee that when our last
+        // reference goes away, the real surface will be deleted.
+        // Without this hack (the code is correct too), we'd have to
+        // wait for a GC for the surface to go away.
+        r = new Surface(this);        
+    }
+    return const_cast<Surface*>(r);
+}
+
+status_t Surface::nextBuffer(SurfaceInfo* info) {
+    return mClient->nextBuffer(this, info);
+}
+
+status_t Surface::lock(SurfaceInfo* info, bool blocking) {
+    return Surface::lock(info, NULL, blocking);
+}
+
+status_t Surface::lock(SurfaceInfo* info, Region* dirty, bool blocking) {
+    if (heapBase(0) == 0) return INVALID_OPERATION;
+    if (heapBase(1) == 0) return INVALID_OPERATION;
+    return mClient->lockSurface(this, info, dirty, blocking);
+}
+
+status_t Surface::unlockAndPost() {
+    if (heapBase(0) == 0) return INVALID_OPERATION;
+    if (heapBase(1) == 0) return INVALID_OPERATION;
+    return mClient->unlockAndPostSurface(this);
+}
+
+status_t Surface::unlock() {
+    if (heapBase(0) == 0) return INVALID_OPERATION;
+    if (heapBase(1) == 0) return INVALID_OPERATION;
+    return mClient->unlockSurface(this);
+}
+
+status_t Surface::setLayer(int32_t layer) {
+    return mClient->setLayer(this, layer);
+}
+status_t Surface::setPosition(int32_t x, int32_t y) {
+    return mClient->setPosition(this, x, y);
+}
+status_t Surface::setSize(uint32_t w, uint32_t h) {
+    return mClient->setSize(this, w, h);
+}
+status_t Surface::hide() {
+    return mClient->hide(this);
+}
+status_t Surface::show(int32_t layer) {
+    return mClient->show(this, layer);
+}
+status_t Surface::freeze() {
+    return mClient->freeze(this);
+}
+status_t Surface::unfreeze() {
+    return mClient->unfreeze(this);
+}
+status_t Surface::setFlags(uint32_t flags, uint32_t mask) {
+    return mClient->setFlags(this, flags, mask);
+}
+status_t Surface::setTransparentRegionHint(const Region& transparent) {
+    return mClient->setTransparentRegionHint(this, transparent);
+}
+status_t Surface::setAlpha(float alpha) {
+    return mClient->setAlpha(this, alpha);
+}
+status_t Surface::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+    return mClient->setMatrix(this, dsdx, dtdx, dsdy, dtdy);
+}
+status_t Surface::setFreezeTint(uint32_t tint) {
+    return mClient->setFreezeTint(this, tint);
+}
+
+Region Surface::dirtyRegion() const  {
+    return mDirtyRegion; 
+}
+void Surface::setDirtyRegion(const Region& region) const {
+    mDirtyRegion = region;
+}
+const Rect& Surface::swapRectangle() const {
+    return mSwapRectangle;
+}
+void Surface::setSwapRectangle(const Rect& r) {
+    mSwapRectangle = r;
+}
+
+sp<Surface> Surface::readFromParcel(Parcel* parcel)
+{
+    sp<SurfaceComposerClient> client;
+    ISurfaceFlingerClient::surface_data_t data;
+    sp<IBinder> clientBinder= parcel->readStrongBinder();
+    sp<ISurface> surface    = interface_cast<ISurface>(parcel->readStrongBinder());
+    data.heap[0]            = interface_cast<IMemoryHeap>(parcel->readStrongBinder());
+    data.heap[1]            = interface_cast<IMemoryHeap>(parcel->readStrongBinder());
+    data.token              = parcel->readInt32();
+    data.identity           = parcel->readInt32();
+    PixelFormat format      = parcel->readInt32();
+    uint32_t flags          = parcel->readInt32();
+
+    if (clientBinder != NULL)
+        client = SurfaceComposerClient::clientForConnection(clientBinder);
+
+    return new Surface(client, surface, data, 0, 0, format, flags, false);
+}
+
+status_t Surface::writeToParcel(const sp<Surface>& surface, Parcel* parcel)
+{
+    uint32_t flags=0;
+    uint32_t format=0;
+    SurfaceID token = -1;
+    uint32_t identity = 0;
+    sp<SurfaceComposerClient> client;
+    sp<ISurface> sur;
+    sp<IMemoryHeap> heap[2];
+    if (surface->isValid()) {
+        token = surface->mToken;
+        identity = surface->mIdentity;
+        client = surface->mClient;
+        sur = surface->mSurface;
+        heap[0] = surface->mHeap[0];
+        heap[1] = surface->mHeap[1];
+        format = surface->mFormat;
+        flags = surface->mFlags;
+    }
+    parcel->writeStrongBinder(client!=0  ? client->connection() : NULL);
+    parcel->writeStrongBinder(sur!=0     ? sur->asBinder()      : NULL);
+    parcel->writeStrongBinder(heap[0]!=0 ? heap[0]->asBinder()  : NULL);
+    parcel->writeStrongBinder(heap[1]!=0 ? heap[1]->asBinder()  : NULL);
+    parcel->writeInt32(token);
+    parcel->writeInt32(identity);
+    parcel->writeInt32(format);
+    parcel->writeInt32(flags);
+    return NO_ERROR;
+}
+
+bool Surface::isSameSurface(const sp<Surface>& lhs, const sp<Surface>& rhs) 
+{
+    if (lhs == 0 || rhs == 0)
+        return false;
+    return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
+}
+
+void* Surface::heapBase(int i) const 
+{
+    void* heapBase = mSurfaceHeapBase[i];
+    // map lazily so it doesn't get mapped in clients that don't need it
+    if (heapBase == 0) {
+        const sp<IMemoryHeap>& heap(mHeap[i]);
+        if (heap != 0) {
+            heapBase = static_cast<uint8_t*>(heap->base());
+            if (heapBase == MAP_FAILED) {
+                heapBase = NULL;
+                LOGE("Couldn't map Surface's heap (binder=%p, heap=%p)",
+                        heap->asBinder().get(), heap.get());
+            }
+            mSurfaceHeapBase[i] = heapBase;
+        }
+    }
+    return heapBase;
+}
+
+}; // namespace android
+
diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp
new file mode 100644
index 0000000..9354a7a
--- /dev/null
+++ b/libs/ui/SurfaceComposerClient.cpp
@@ -0,0 +1,1026 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceComposerClient"
+
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <cutils/memory.h>
+
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <utils/KeyedVector.h>
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+#include <utils/IMemory.h>
+#include <utils/Log.h>
+
+#include <ui/ISurfaceComposer.h>
+#include <ui/ISurfaceFlingerClient.h>
+#include <ui/ISurface.h>
+#include <ui/SurfaceComposerClient.h>
+#include <ui/DisplayInfo.h>
+#include <ui/Rect.h>
+#include <ui/Point.h>
+
+#include <private/ui/SharedState.h>
+#include <private/ui/LayerState.h>
+#include <private/ui/SurfaceFlingerSynchro.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include <utils/BpBinder.h>
+
+#define VERBOSE(...)	((void)0)
+//#define VERBOSE			LOGD
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+// Must not be holding SurfaceComposerClient::mLock when acquiring gLock here.
+static Mutex                                                gLock;
+static sp<ISurfaceComposer>                                 gSurfaceManager;
+static DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections;
+static SortedVector<sp<SurfaceComposerClient> >             gOpenTransactions;
+static sp<IMemory>                                          gServerCblkMemory;
+static volatile surface_flinger_cblk_t*                     gServerCblk;
+
+const sp<ISurfaceComposer>& _get_surface_manager()
+{
+    if (gSurfaceManager != 0) {
+        return gSurfaceManager;
+    }
+
+    sp<IBinder> binder;
+    sp<IServiceManager> sm = defaultServiceManager();
+    do {
+        binder = sm->getService(String16("SurfaceFlinger"));
+        if (binder == 0) {
+            LOGW("SurfaceFlinger not published, waiting...");
+            usleep(500000); // 0.5 s
+        }
+    } while(binder == 0);
+    sp<ISurfaceComposer> sc(interface_cast<ISurfaceComposer>(binder));
+
+    Mutex::Autolock _l(gLock);
+    if (gSurfaceManager == 0) {
+        gSurfaceManager = sc;
+    }
+    return gSurfaceManager;
+}
+
+static volatile surface_flinger_cblk_t const * get_cblk()
+{
+    if (gServerCblk == 0) {
+        const sp<ISurfaceComposer>& sm(_get_surface_manager());
+        Mutex::Autolock _l(gLock);
+        if (gServerCblk == 0) {
+            gServerCblkMemory = sm->getCblk();
+            LOGE_IF(gServerCblkMemory==0, "Can't get server control block");
+            gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->pointer();
+            LOGE_IF(gServerCblk==0, "Can't get server control block address");
+        }
+    }
+    return gServerCblk;
+}
+
+// ---------------------------------------------------------------------------
+
+static void copyBlt(const GGLSurface& dst,
+        const GGLSurface& src, const Region& reg)
+{
+    Region::iterator iterator(reg);
+    if (iterator) {
+        // NOTE: dst and src must be the same format
+        Rect r;
+        const size_t bpp = bytesPerPixel(src.format);
+        const size_t dbpr = dst.stride * bpp;
+        const size_t sbpr = src.stride * bpp;
+        while (iterator.iterate(&r)) {
+            ssize_t h = r.bottom - r.top;
+            if (h) {
+                size_t size = (r.right - r.left) * bpp;
+                uint8_t* s = src.data + (r.left + src.stride * r.top) * bpp;
+                uint8_t* d = dst.data + (r.left + dst.stride * r.top) * bpp;
+                if (dbpr==sbpr && size==sbpr) {
+                    size *= h;
+                    h = 1;
+                }
+                do {
+                    memcpy(d, s, size);
+                    d += dbpr;
+                    s += sbpr;
+                } while (--h > 0);
+            }
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+surface_flinger_cblk_t::surface_flinger_cblk_t()
+{
+}
+
+// ---------------------------------------------------------------------------
+
+per_client_cblk_t::per_client_cblk_t()
+{
+}
+
+// these functions are used by the clients
+inline status_t per_client_cblk_t::validate(size_t i) const {
+    if (uint32_t(i) >= NUM_LAYERS_MAX)
+        return BAD_INDEX;
+    if (layers[i].swapState & eInvalidSurface)
+        return NO_MEMORY;
+    return NO_ERROR;
+}
+
+int32_t per_client_cblk_t::lock_layer(size_t i, uint32_t flags)
+{
+    int32_t index;
+    uint32_t state;
+    int timeout = 0;
+    status_t result;
+    layer_cblk_t * const layer = layers + i;
+    const bool blocking = flags & BLOCKING;
+    const bool inspect  = flags & INSPECT;
+
+    do {
+        state = layer->swapState;
+
+        if (UNLIKELY((state&(eFlipRequested|eNextFlipPending)) == eNextFlipPending)) {
+            LOGE("eNextFlipPending set but eFlipRequested not set, "
+                 "layer=%d (lcblk=%p), state=%08x",
+                 int(i), layer, int(state));
+            return INVALID_OPERATION;
+        }
+
+        if (UNLIKELY(state&eLocked)) {
+            LOGE("eLocked set when entering lock_layer(), "
+                 "layer=%d (lcblk=%p), state=%08x",
+                 int(i), layer, int(state));
+            return WOULD_BLOCK;
+        }
+
+
+	    if (state & (eFlipRequested | eNextFlipPending | eResizeRequested
+                        | eInvalidSurface))
+        {
+	        int32_t resizeIndex;
+	        Mutex::Autolock _l(lock);
+	            // might block for a very short amount of time
+	            // will never cause the server to block (trylock())
+
+	        goto start_loop_here;
+
+	        // We block the client if:
+	        // eNextFlipPending:  we've used both buffers already, so we need to
+	        //                    wait for one to become availlable.
+	        // eResizeRequested:  the buffer we're going to acquire is being
+	        //                    resized. Block until it is done.
+	        // eFlipRequested && eBusy: the buffer we're going to acquire is
+	        //                    currently in use by the server.
+	        // eInvalidSurface:   this is a special case, we don't block in this
+	        //                    case, we just return an error.
+
+	        while((state & (eNextFlipPending|eInvalidSurface)) ||
+	              (state & ((resizeIndex) ? eResizeBuffer1 : eResizeBuffer0)) ||
+	              ((state & (eFlipRequested|eBusy)) == (eFlipRequested|eBusy)) )
+	        {
+	            if (state & eInvalidSurface)
+	                return NO_MEMORY;
+
+	            if (!blocking)
+	                return WOULD_BLOCK;
+
+                timeout = 0;
+                result = cv.waitRelative(lock, seconds(1));
+	            if (__builtin_expect(result!=NO_ERROR, false)) {
+                    const int newState = layer->swapState;
+                    LOGW(   "lock_layer timed out (is the CPU pegged?) "
+                            "layer=%d, lcblk=%p, state=%08x (was %08x)",
+                            int(i), layer, newState, int(state));
+                    timeout = newState != int(state);
+                }
+
+	        start_loop_here:
+	            state = layer->swapState;
+	            resizeIndex = (state&eIndex) ^ ((state&eFlipRequested)>>1);
+	        }
+
+            LOGW_IF(timeout,
+                    "lock_layer() timed out but didn't appear to need "
+                    "to be locked and we recovered "
+                    "(layer=%d, lcblk=%p, state=%08x)",
+                    int(i), layer, int(state));
+	    }
+
+	    // eFlipRequested is not set and cannot be set by another thread: it's
+	    // safe to use the first buffer without synchronization.
+
+        // Choose the index depending on eFlipRequested.
+        // When it's set, choose the 'other' buffer.
+        index = (state&eIndex) ^ ((state&eFlipRequested)>>1);
+
+	    // make sure this buffer is valid
+	    if (layer->surface[index].bits_offset < 0) {
+	        return status_t(layer->surface[index].bits_offset);
+	    }
+
+        if (inspect) {
+            // we just want to inspect this layer. don't lock it.
+            goto done;
+        }
+
+	    // last thing before we're done, we need to atomically lock the state
+    } while (android_atomic_cmpxchg(state, state|eLocked, &(layer->swapState)));
+
+    VERBOSE("locked layer=%d (lcblk=%p), buffer=%d, state=0x%08x",
+         int(i), layer, int(index), int(state));
+
+    // store the index of the locked buffer (for client use only)
+    layer->flags &= ~eBufferIndex;
+    layer->flags |= ((index << eBufferIndexShift) & eBufferIndex);
+
+done:
+    return index;
+}
+
+uint32_t per_client_cblk_t::unlock_layer_and_post(size_t i)
+{
+    // atomically set eFlipRequested and clear eLocked and optionnaly
+    // set eNextFlipPending if eFlipRequested was already set
+
+    layer_cblk_t * const layer = layers + i;
+    int32_t oldvalue, newvalue;
+    do {
+        oldvalue = layer->swapState;
+            // get current value
+
+        newvalue = oldvalue & ~eLocked;
+            // clear eLocked
+
+        newvalue |= eFlipRequested;
+            // set eFlipRequested
+
+        if (oldvalue & eFlipRequested)
+            newvalue |= eNextFlipPending;
+            // if eFlipRequested was alread set, set eNextFlipPending
+
+    } while (android_atomic_cmpxchg(oldvalue, newvalue, &(layer->swapState)));
+
+    VERBOSE("request pageflip for layer=%d, buffer=%d, state=0x%08x",
+            int(i), int((layer->flags & eBufferIndex) >> eBufferIndexShift),
+            int(newvalue));
+
+    // from this point, the server can kick in at anytime and use the first
+    // buffer, so we cannot use it anymore, and we must use the 'other'
+    // buffer instead (or wait if it is not availlable yet, see lock_layer).
+
+    return newvalue;
+}
+
+void per_client_cblk_t::unlock_layer(size_t i)
+{
+    layer_cblk_t * const layer = layers + i;
+    android_atomic_and(~eLocked, &layer->swapState);
+}
+
+// ---------------------------------------------------------------------------
+
+static inline int compare_type( const layer_state_t& lhs,
+                                const layer_state_t& rhs) {
+    if (lhs.surface < rhs.surface)  return -1;
+    if (lhs.surface > rhs.surface)  return 1;
+    return 0;
+}
+
+SurfaceComposerClient::SurfaceComposerClient()
+{
+    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    if (sm == 0) {
+        _init(0, 0);
+        return;
+    }
+
+    _init(sm, sm->createConnection());
+
+    if (mClient != 0) {
+        Mutex::Autolock _l(gLock);
+        VERBOSE("Adding client %p to map", this);
+        gActiveConnections.add(mClient->asBinder(), this);
+    }
+}
+
+SurfaceComposerClient::SurfaceComposerClient(
+        const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn)
+{
+    _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
+}
+
+void SurfaceComposerClient::_init(
+        const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
+{
+    VERBOSE("Creating client %p, conn %p", this, conn.get());
+
+    mSignalServer = 0;
+    mPrebuiltLayerState = 0;
+    mTransactionOpen = 0;
+    mStatus = NO_ERROR;
+    mControl = 0;
+
+    mClient = conn;
+    if (mClient == 0) {
+        mStatus = NO_INIT;
+        return;
+    }
+
+    mClient->getControlBlocks(&mControlMemory);
+    mSignalServer = new SurfaceFlingerSynchro(sm);
+    mControl = static_cast<per_client_cblk_t *>(mControlMemory->pointer());
+}
+
+SurfaceComposerClient::~SurfaceComposerClient()
+{
+    VERBOSE("Destroying client %p, conn %p", this, mClient.get());
+    dispose();
+}
+
+status_t SurfaceComposerClient::initCheck() const
+{
+    return mStatus;
+}
+
+status_t SurfaceComposerClient::validateSurface(
+        per_client_cblk_t const* cblk, Surface const * surface)
+{
+    SurfaceID index = surface->ID();
+    if (cblk == 0) {
+        LOGE("cblk is null (surface id=%d, identity=%u)",
+                index, surface->getIdentity());
+        return NO_INIT;
+    }
+
+    status_t err = cblk->validate(index);
+    if (err != NO_ERROR) {
+        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
+                index, surface->getIdentity(), err, strerror(-err));
+        return err;
+    }
+
+    if (surface->getIdentity() != uint32_t(cblk->layers[index].identity)) {
+        LOGE("using an invalid surface id=%d, identity=%u should be %d",
+                index, surface->getIdentity(), cblk->layers[index].identity);
+        return NO_INIT;
+    }
+
+    return NO_ERROR;
+}
+
+sp<IBinder> SurfaceComposerClient::connection() const
+{
+    return (mClient != 0) ? mClient->asBinder() : 0;
+}
+
+sp<SurfaceComposerClient>
+SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
+{
+    sp<SurfaceComposerClient> client;
+
+    { // scope for lock
+        Mutex::Autolock _l(gLock);
+        client = gActiveConnections.valueFor(conn);
+    }
+
+    if (client == 0) {
+        // Need to make a new client.
+        const sp<ISurfaceComposer>& sm(_get_surface_manager());
+        client = new SurfaceComposerClient(sm, conn);
+        if (client != 0 && client->initCheck() == NO_ERROR) {
+            Mutex::Autolock _l(gLock);
+            gActiveConnections.add(conn, client);
+            //LOGD("we have %d connections", gActiveConnections.size());
+        } else {
+            client.clear();
+        }
+    }
+
+    return client;
+}
+
+void SurfaceComposerClient::dispose()
+{
+    // this can be called more than once.
+
+    sp<IMemory>                 controlMemory;
+    sp<ISurfaceFlingerClient>   client;
+    sp<IMemoryHeap>             surfaceHeap;
+
+    {
+        Mutex::Autolock _lg(gLock);
+        Mutex::Autolock _lm(mLock);
+
+        delete mSignalServer;
+        mSignalServer = 0;
+
+        if (mClient != 0) {
+            client = mClient;
+            mClient.clear();
+
+            ssize_t i = gActiveConnections.indexOfKey(client->asBinder());
+            if (i >= 0 && gActiveConnections.valueAt(i) == this) {
+                VERBOSE("Removing client %p from map at %d", this, int(i));
+                gActiveConnections.removeItemsAt(i);
+            }
+        }
+
+        delete mPrebuiltLayerState;
+        mPrebuiltLayerState = 0;
+        controlMemory = mControlMemory;
+        surfaceHeap = mSurfaceHeap;
+        mControlMemory.clear();
+        mSurfaceHeap.clear();
+        mControl = 0;
+        mStatus = NO_INIT;
+    }
+}
+
+status_t SurfaceComposerClient::getDisplayInfo(
+        DisplayID dpy, DisplayInfo* info)
+{
+    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
+        return BAD_VALUE;
+
+    volatile surface_flinger_cblk_t const * cblk = get_cblk();
+    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
+
+    info->w              = dcblk->w;
+    info->h              = dcblk->h;
+    info->orientation    = dcblk->orientation;
+    info->xdpi           = dcblk->xdpi;
+    info->ydpi           = dcblk->ydpi;
+    info->fps            = dcblk->fps;
+    info->density        = dcblk->density;
+    return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
+}
+
+ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
+{
+    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
+        return BAD_VALUE;
+    volatile surface_flinger_cblk_t const * cblk = get_cblk();
+    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
+    return dcblk->w;
+}
+
+ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
+{
+    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
+        return BAD_VALUE;
+    volatile surface_flinger_cblk_t const * cblk = get_cblk();
+    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
+    return dcblk->h;
+}
+
+ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
+{
+    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
+        return BAD_VALUE;
+    volatile surface_flinger_cblk_t const * cblk = get_cblk();
+    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
+    return dcblk->orientation;
+}
+
+ssize_t SurfaceComposerClient::getNumberOfDisplays()
+{
+    volatile surface_flinger_cblk_t const * cblk = get_cblk();
+    uint32_t connected = cblk->connected;
+    int n = 0;
+    while (connected) {
+        if (connected&1) n++;
+        connected >>= 1;
+    }
+    return n;
+}
+
+sp<Surface> SurfaceComposerClient::createSurface(
+        int pid,
+        DisplayID display,
+        uint32_t w,
+        uint32_t h,
+        PixelFormat format,
+        uint32_t flags)
+{
+    sp<Surface> result;
+    if (mStatus == NO_ERROR) {
+        ISurfaceFlingerClient::surface_data_t data;
+        sp<ISurface> surface = mClient->createSurface(&data, pid,
+                display, w, h, format, flags);
+        if (surface != 0) {
+            if (uint32_t(data.token) < NUM_LAYERS_MAX) {
+                result = new Surface(this, surface, data, w, h, format, flags);
+            }
+        }
+    }
+    return result;
+}
+
+status_t SurfaceComposerClient::destroySurface(SurfaceID sid)
+{
+    if (mStatus != NO_ERROR)
+        return mStatus;
+
+    // it's okay to destroy a surface while a transaction is open,
+    // (transactions really are a client-side concept)
+    // however, this indicates probably a misuse of the API or a bug
+    // in the client code.
+    LOGW_IF(mTransactionOpen,
+         "Destroying surface while a transaction is open. "
+         "Client %p: destroying surface %d, mTransactionOpen=%d",
+         this, sid, mTransactionOpen);
+
+    status_t err = mClient->destroySurface(sid);
+    return err;
+}
+
+status_t SurfaceComposerClient::nextBuffer(Surface* surface,
+                        Surface::SurfaceInfo* info)
+{
+    SurfaceID index = surface->ID();
+    per_client_cblk_t* const cblk = mControl;
+    status_t err = validateSurface(cblk, surface);
+    if (err != NO_ERROR)
+        return err;
+
+    int32_t backIdx = surface->mBackbufferIndex;
+    layer_cblk_t* const lcblk = &(cblk->layers[index]);
+    const surface_info_t* const front = lcblk->surface + (1-backIdx);
+        info->w      = front->w;
+        info->h      = front->h;
+        info->format = front->format;
+        info->base   = surface->heapBase(1-backIdx);
+        info->bits   = reinterpret_cast<void*>(intptr_t(info->base) + front->bits_offset);
+        info->bpr    = front->bpr;
+
+    return 0;
+}
+
+status_t SurfaceComposerClient::lockSurface(
+        Surface* surface,
+        Surface::SurfaceInfo* other,
+        Region* dirty,
+        bool blocking)
+{
+    Mutex::Autolock _l(surface->getLock());
+
+    SurfaceID index = surface->ID();
+    per_client_cblk_t* const cblk = mControl;
+    status_t err = validateSurface(cblk, surface);
+    if (err != NO_ERROR)
+        return err;
+
+    int32_t backIdx = cblk->lock_layer(size_t(index),
+            per_client_cblk_t::BLOCKING);
+    if (backIdx >= 0) {
+        surface->mBackbufferIndex = backIdx;
+        layer_cblk_t* const lcblk = &(cblk->layers[index]);
+        const surface_info_t* const back = lcblk->surface + backIdx;
+        const surface_info_t* const front = lcblk->surface + (1-backIdx);
+            other->w      = back->w;
+            other->h      = back->h;
+            other->format = back->format;
+            other->base   = surface->heapBase(backIdx);
+            other->bits   = reinterpret_cast<void*>(intptr_t(other->base) + back->bits_offset);
+            other->bpr    = back->bpr;
+
+        const Rect bounds(other->w, other->h);
+        Region newDirtyRegion;
+
+        if (back->flags & surface_info_t::eBufferDirty) {
+            /* it is safe to write *back here, because we're guaranteed
+             * SurfaceFlinger is not touching it (since it just granted
+             * access to us) */
+            const_cast<surface_info_t*>(back)->flags &=
+                    ~surface_info_t::eBufferDirty;
+
+            // content is meaningless in this case and the whole surface
+            // needs to be redrawn.
+
+            newDirtyRegion.set(bounds);
+            if (dirty) {
+                *dirty = newDirtyRegion;
+            }
+
+            //if (bytesPerPixel(other->format) == 4) {
+            //    android_memset32(
+            //        (uint32_t*)other->bits, 0xFF00FF00, other->h * other->bpr);
+            //} else {
+            //    android_memset16( // fill with green
+            //        (uint16_t*)other->bits, 0x7E0, other->h * other->bpr);
+            //}
+        }
+        else
+        {
+            if (dirty) {
+                dirty->andSelf(Region(bounds));
+                newDirtyRegion = *dirty;
+            } else {
+                newDirtyRegion.set(bounds);
+            }
+
+            Region copyback;
+            if (!(lcblk->flags & eNoCopyBack)) {
+                const Region previousDirtyRegion(surface->dirtyRegion());
+                copyback = previousDirtyRegion.subtract(newDirtyRegion);
+            }
+
+            if (!copyback.isEmpty()) {
+                // copy front to back
+                GGLSurface cb;
+                    cb.version = sizeof(GGLSurface);
+                    cb.width = back->w;
+                    cb.height = back->h;
+                    cb.stride = back->stride;
+                    cb.data = (GGLubyte*)surface->heapBase(backIdx);
+                    cb.data += back->bits_offset;
+                    cb.format = back->format;
+
+                GGLSurface t;
+                    t.version = sizeof(GGLSurface);
+                    t.width = front->w;
+                    t.height = front->h;
+                    t.stride = front->stride;
+                    t.data = (GGLubyte*)surface->heapBase(1-backIdx);
+                    t.data += front->bits_offset;
+                    t.format = front->format;
+
+                //const Region copyback(lcblk->region + 1-backIdx);
+                copyBlt(cb, t, copyback);
+            }
+        }
+
+        // update dirty region
+        surface->setDirtyRegion(newDirtyRegion);
+    }
+    return (backIdx < 0) ? status_t(backIdx) : status_t(NO_ERROR);
+}
+
+void SurfaceComposerClient::_signal_server()
+{
+    mSignalServer->signal();
+}
+
+void SurfaceComposerClient::_send_dirty_region(
+        layer_cblk_t* lcblk, const Region& dirty)
+{
+    const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift;
+    flat_region_t* flat_region = lcblk->region + index;
+    status_t err = dirty.write(flat_region, sizeof(flat_region_t));
+    if (err < NO_ERROR) {
+        // region doesn't fit, use the bounds
+        const Region reg(dirty.bounds());
+        reg.write(flat_region, sizeof(flat_region_t));
+    }
+}
+
+status_t SurfaceComposerClient::unlockAndPostSurface(Surface* surface)
+{
+    Mutex::Autolock _l(surface->getLock());
+
+    SurfaceID index = surface->ID();
+    per_client_cblk_t* const cblk = mControl;
+    status_t err = validateSurface(cblk, surface);
+    if (err != NO_ERROR)
+        return err;
+
+    Region dirty(surface->dirtyRegion());
+    const Rect& swapRect(surface->swapRectangle());
+    if (swapRect.isValid()) {
+        dirty.set(swapRect);
+    }
+
+    // transmit the dirty region
+    layer_cblk_t* const lcblk = &(cblk->layers[index]);
+    _send_dirty_region(lcblk, dirty);
+    uint32_t newstate = cblk->unlock_layer_and_post(size_t(index));
+    if (!(newstate & eNextFlipPending))
+        _signal_server();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::unlockSurface(Surface* surface)
+{
+    Mutex::Autolock _l(surface->getLock());
+
+    SurfaceID index = surface->ID();
+    per_client_cblk_t* const cblk = mControl;
+    status_t err = validateSurface(cblk, surface);
+    if (err != NO_ERROR)
+        return err;
+
+    layer_cblk_t* const lcblk = &(cblk->layers[index]);
+    cblk->unlock_layer(size_t(index));
+    return NO_ERROR;
+}
+
+void SurfaceComposerClient::openGlobalTransaction()
+{
+    Mutex::Autolock _l(gLock);
+
+    if (gOpenTransactions.size()) {
+        LOGE("openGlobalTransaction() called more than once. skipping.");
+        return;
+    }
+
+    const size_t N = gActiveConnections.size();
+    VERBOSE("openGlobalTransaction (%ld clients)", N);
+    for (size_t i=0; i<N; i++) {
+        sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i));
+        if (gOpenTransactions.indexOf(client) < 0) {
+            if (client->openTransaction() == NO_ERROR) {
+                if (gOpenTransactions.add(client) < 0) {
+                    // Ooops!
+                    LOGE(   "Unable to add a SurfaceComposerClient "
+                            "to the global transaction set (out of memory?)");
+                    client->closeTransaction();
+                    // let it go, it'll fail later when the user
+                    // tries to do something with the transaction
+                }
+            } else {
+                LOGE("openTransaction on client %p failed", client.get());
+                // let it go, it'll fail later when the user
+                // tries to do something with the transaction
+            }
+        }
+    }
+}
+
+void SurfaceComposerClient::closeGlobalTransaction()
+{
+    gLock.lock();
+        SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions);
+        gOpenTransactions.clear();
+    gLock.unlock();
+
+    const size_t N = clients.size();
+    VERBOSE("closeGlobalTransaction (%ld clients)", N);
+    if (N == 1) {
+        clients[0]->closeTransaction();
+    } else {
+        const sp<ISurfaceComposer>& sm(_get_surface_manager());
+        sm->openGlobalTransaction();
+        for (size_t i=0; i<N; i++) {
+            clients[i]->closeTransaction();
+        }
+        sm->closeGlobalTransaction();
+    }
+}
+
+status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
+{
+    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    return sm->freezeDisplay(dpy, flags);
+}
+
+status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
+{
+    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    return sm->unfreezeDisplay(dpy, flags);
+}
+
+int SurfaceComposerClient::setOrientation(DisplayID dpy, int orientation)
+{
+    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    return sm->setOrientation(dpy, orientation);
+}
+
+status_t SurfaceComposerClient::openTransaction()
+{
+    if (mStatus != NO_ERROR)
+        return mStatus;
+    Mutex::Autolock _l(mLock);
+    VERBOSE(   "openTransaction (client %p, mTransactionOpen=%d)",
+            this, mTransactionOpen);
+    mTransactionOpen++;
+    if (mPrebuiltLayerState == 0) {
+        mPrebuiltLayerState = new layer_state_t;
+    }
+    return NO_ERROR;
+}
+
+
+status_t SurfaceComposerClient::closeTransaction()
+{
+    if (mStatus != NO_ERROR)
+        return mStatus;
+
+    Mutex::Autolock _l(mLock);
+
+    VERBOSE(   "closeTransaction (client %p, mTransactionOpen=%d)",
+            this, mTransactionOpen);
+
+    if (mTransactionOpen <= 0) {
+        LOGE(   "closeTransaction (client %p, mTransactionOpen=%d) "
+                "called more times than openTransaction()",
+                this, mTransactionOpen);
+        return INVALID_OPERATION;
+    }
+
+    if (mTransactionOpen >= 2) {
+        mTransactionOpen--;
+        return NO_ERROR;
+    }
+
+    mTransactionOpen = 0;
+    const ssize_t count = mStates.size();
+    if (count) {
+        mClient->setState(count, mStates.array());
+        mStates.clear();
+    }
+    return NO_ERROR;
+}
+
+layer_state_t* SurfaceComposerClient::_get_state_l(const sp<Surface>& surface)
+{
+    SurfaceID index = surface->ID();
+    per_client_cblk_t* const cblk = mControl;
+    status_t err = validateSurface(cblk, surface.get());
+    if (err != NO_ERROR)
+        return 0;
+
+    // API usage error, do nothing.
+    if (mTransactionOpen<=0) {
+        LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
+                this, int(index), mTransactionOpen);
+        return 0;
+    }
+
+    // use mPrebuiltLayerState just to find out if we already have it
+    layer_state_t& dummy = *mPrebuiltLayerState;
+    dummy.surface = index;
+    ssize_t i = mStates.indexOf(dummy);
+    if (i < 0) {
+        // we don't have it, add an initialized layer_state to our list
+        i = mStates.add(dummy);
+    }
+    return mStates.editArray() + i;
+}
+
+layer_state_t* SurfaceComposerClient::_lockLayerState(const sp<Surface>& surface)
+{
+    layer_state_t* s;
+    mLock.lock();
+    s = _get_state_l(surface);
+    if (!s) mLock.unlock();
+    return s;
+}
+
+void SurfaceComposerClient::_unlockLayerState()
+{
+    mLock.unlock();
+}
+
+status_t SurfaceComposerClient::setPosition(Surface* surface, int32_t x, int32_t y)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::ePositionChanged;
+    s->x = x;
+    s->y = y;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::setSize(Surface* surface, uint32_t w, uint32_t h)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eSizeChanged;
+    s->w = w;
+    s->h = h;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::setLayer(Surface* surface, int32_t z)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eLayerChanged;
+    s->z = z;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::hide(Surface* surface)
+{
+    return setFlags(surface, ISurfaceComposer::eLayerHidden,
+            ISurfaceComposer::eLayerHidden);
+}
+
+status_t SurfaceComposerClient::show(Surface* surface, int32_t)
+{
+    return setFlags(surface, 0, ISurfaceComposer::eLayerHidden);
+}
+
+status_t SurfaceComposerClient::freeze(Surface* surface)
+{
+    return setFlags(surface, ISurfaceComposer::eLayerFrozen,
+            ISurfaceComposer::eLayerFrozen);
+}
+
+status_t SurfaceComposerClient::unfreeze(Surface* surface)
+{
+    return setFlags(surface, 0, ISurfaceComposer::eLayerFrozen);
+}
+
+status_t SurfaceComposerClient::setFlags(Surface* surface,
+        uint32_t flags, uint32_t mask)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eVisibilityChanged;
+    s->flags &= ~mask;
+    s->flags |= (flags & mask);
+    s->mask |= mask;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+
+status_t SurfaceComposerClient::setTransparentRegionHint(
+        Surface* surface, const Region& transparentRegion)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eTransparentRegionChanged;
+    s->transparentRegion = transparentRegion;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::setAlpha(Surface* surface, float alpha)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eAlphaChanged;
+    s->alpha = alpha;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::setMatrix(
+        Surface* surface,
+        float dsdx, float dtdx,
+        float dsdy, float dtdy )
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eMatrixChanged;
+    layer_state_t::matrix22_t matrix;
+    matrix.dsdx = dsdx;
+    matrix.dtdx = dtdx;
+    matrix.dsdy = dsdy;
+    matrix.dtdy = dtdy;
+    s->matrix = matrix;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::setFreezeTint(Surface* surface, uint32_t tint)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eFreezeTintChanged;
+    s->tint = tint;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+}; // namespace android
+
diff --git a/libs/ui/SurfaceFlingerSynchro.cpp b/libs/ui/SurfaceFlingerSynchro.cpp
new file mode 100644
index 0000000..5cd9755
--- /dev/null
+++ b/libs/ui/SurfaceFlingerSynchro.cpp
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlingerSynchro"
+
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+
+#include <private/ui/SurfaceFlingerSynchro.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+SurfaceFlingerSynchro::Barrier::Barrier()
+    : state(CLOSED) { 
+}
+
+SurfaceFlingerSynchro::Barrier::~Barrier() { 
+}
+
+void SurfaceFlingerSynchro::Barrier::open() {
+    asm volatile ("":::"memory");
+    Mutex::Autolock _l(lock);
+    state = OPENED;
+    cv.broadcast();
+}
+
+void SurfaceFlingerSynchro::Barrier::close() {
+    Mutex::Autolock _l(lock);
+    state = CLOSED;
+}
+
+void SurfaceFlingerSynchro::Barrier::waitAndClose() 
+{
+    Mutex::Autolock _l(lock);
+    while (state == CLOSED) {
+        // we're about to wait, flush the binder command buffer
+        IPCThreadState::self()->flushCommands();
+        cv.wait(lock);
+    }
+    state = CLOSED;
+}
+
+status_t SurfaceFlingerSynchro::Barrier::waitAndClose(nsecs_t timeout) 
+{
+    Mutex::Autolock _l(lock);
+    while (state == CLOSED) {
+        // we're about to wait, flush the binder command buffer
+        IPCThreadState::self()->flushCommands();
+        int err = cv.waitRelative(lock, timeout);
+        if (err != 0)
+            return err;
+    }
+    state = CLOSED;
+    return NO_ERROR;
+}
+
+// ---------------------------------------------------------------------------
+
+SurfaceFlingerSynchro::SurfaceFlingerSynchro(const sp<ISurfaceComposer>& flinger)
+    : mSurfaceComposer(flinger)
+{
+}
+
+SurfaceFlingerSynchro::SurfaceFlingerSynchro()
+{
+}
+
+SurfaceFlingerSynchro::~SurfaceFlingerSynchro()
+{
+}
+
+status_t SurfaceFlingerSynchro::signal()
+{
+    mSurfaceComposer->signal();
+    return NO_ERROR;
+}
+
+status_t SurfaceFlingerSynchro::wait()
+{
+    mBarrier.waitAndClose();
+    return NO_ERROR;
+}
+
+status_t SurfaceFlingerSynchro::wait(nsecs_t timeout)
+{
+    if (timeout == 0)
+        return SurfaceFlingerSynchro::wait();
+    return mBarrier.waitAndClose(timeout);
+}
+
+void SurfaceFlingerSynchro::open()
+{
+    mBarrier.open();
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/libs/ui/Time.cpp b/libs/ui/Time.cpp
new file mode 100644
index 0000000..b553913
--- /dev/null
+++ b/libs/ui/Time.cpp
@@ -0,0 +1,199 @@
+#include <utils/TimeUtils.h>
+#include <stdio.h>
+#include <cutils/tztime.h>
+
+namespace android {
+
+static void
+dump(const Time& t)
+{
+    #ifdef HAVE_TM_GMTOFF
+        long tm_gmtoff = t.t.tm_gmtoff;
+    #else
+        long tm_gmtoff = 0;
+    #endif
+    printf("%04d-%02d-%02d %02d:%02d:%02d (%d,%ld,%d,%d)\n",
+            t.t.tm_year+1900, t.t.tm_mon+1, t.t.tm_mday,
+            t.t.tm_hour, t.t.tm_min, t.t.tm_sec,
+            t.t.tm_isdst, tm_gmtoff, t.t.tm_wday, t.t.tm_yday);
+}
+
+Time::Time()
+{
+    t.tm_sec = 0;
+    t.tm_min = 0;
+    t.tm_hour = 0;
+    t.tm_mday = 0;
+    t.tm_mon = 0;
+    t.tm_year = 0;
+    t.tm_wday = 0;
+    t.tm_yday = 0;
+    t.tm_isdst = -1; // we don't know, so let the C library determine
+    #ifdef HAVE_TM_GMTOFF
+        t.tm_gmtoff = 0;
+    #endif
+}
+
+
+#define COMPARE_FIELD(field) do { \
+        int diff = a.t.field - b.t.field; \
+        if (diff != 0) return diff; \
+    } while(0)
+
+int
+Time::compare(Time& a, Time& b)
+{
+    if (0 == strcmp(a.timezone, b.timezone)) {
+        // if the timezones are the same, we can easily compare the two
+        // times.  Otherwise, convert to milliseconds and compare that.
+        // This requires that object be normalized.
+        COMPARE_FIELD(tm_year);
+        COMPARE_FIELD(tm_mon);
+        COMPARE_FIELD(tm_mday);
+        COMPARE_FIELD(tm_hour);
+        COMPARE_FIELD(tm_min);
+        COMPARE_FIELD(tm_sec);
+        return 0;
+    } else {
+        int64_t am = a.toMillis(false /* use isDst */);
+        int64_t bm = b.toMillis(false /* use isDst */);
+        int64_t diff = am-bm;
+        return (diff < 0) ? -1 : ((diff > 0) ? 1 : 0);
+    }
+}
+
+static const int DAYS_PER_MONTH[] = {
+                        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+                    };
+
+static inline int days_this_month(int year, int month)
+{
+    int n = DAYS_PER_MONTH[month];
+    if (n != 28) {
+        return n;
+    } else {
+        int y = year;
+        return ((y%4)==0&&((y%100)!=0||(y%400)==0)) ? 29 : 28;
+    }
+}
+
+void 
+Time::switchTimezone(const char* timezone)
+{
+    time_t seconds = mktime_tz(&(this->t), this->timezone);
+    localtime_tz(&seconds, &(this->t), timezone);
+}
+
+String8 
+Time::format(const char *format, const struct strftime_locale *locale) const
+{
+    char buf[257];
+    int n = strftime_tz(buf, 257, format, &(this->t), locale);
+    if (n > 0) {
+        return String8(buf);
+    } else {
+        return String8();
+    }
+}
+
+static inline short
+tochar(int n)
+{
+    return (n >= 0 && n <= 9) ? ('0'+n) : ' ';
+}
+
+static inline short
+next_char(int *m, int k)
+{
+    int n = *m / k;
+    *m = *m % k;
+    return tochar(n);
+}
+
+void
+Time::format2445(short* buf, bool hasTime) const
+{
+    int n;
+
+    n = t.tm_year+1900;
+    buf[0] = next_char(&n, 1000);
+    buf[1] = next_char(&n, 100);
+    buf[2] = next_char(&n, 10);
+    buf[3] = tochar(n);
+
+    n = t.tm_mon+1;
+    buf[4] = next_char(&n, 10);
+    buf[5] = tochar(n);
+
+    n = t.tm_mday;
+    buf[6] = next_char(&n, 10);
+    buf[7] = tochar(n);
+
+    if (hasTime) {
+      buf[8] = 'T';
+
+      n = t.tm_hour;
+      buf[9] = next_char(&n, 10);
+      buf[10] = tochar(n);
+      
+      n = t.tm_min;
+      buf[11] = next_char(&n, 10);
+      buf[12] = tochar(n);
+      
+      n = t.tm_sec;
+      buf[13] = next_char(&n, 10);
+      buf[14] = tochar(n);
+      bool inUtc = strcmp("UTC", timezone) == 0;
+      if (inUtc) {
+          buf[15] = 'Z';
+      }
+    }
+}
+
+String8 
+Time::toString() const
+{
+    String8 str;
+    char* s = str.lockBuffer(150);
+    #ifdef HAVE_TM_GMTOFF
+        long tm_gmtoff = t.tm_gmtoff;
+    #else
+        long tm_gmtoff = 0;
+    #endif
+    sprintf(s, "%04d%02d%02dT%02d%02d%02d%s(%d,%d,%ld,%d,%d)", 
+            t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min,
+            t.tm_sec, timezone, t.tm_wday, t.tm_yday, tm_gmtoff, t.tm_isdst,
+            (int)(((Time*)this)->toMillis(false /* use isDst */)/1000));
+    str.unlockBuffer();
+    return str;
+}
+
+void 
+Time::setToNow()
+{
+    time_t seconds;
+    time(&seconds);
+    localtime_tz(&seconds, &(this->t), this->timezone);
+}
+
+int64_t 
+Time::toMillis(bool ignoreDst)
+{
+    if (ignoreDst) {
+        this->t.tm_isdst = -1;
+    }
+    int64_t r = mktime_tz(&(this->t), this->timezone);
+    if (r == -1)
+        return -1;
+    return r * 1000;
+}
+
+void 
+Time::set(int64_t millis)
+{
+    time_t seconds = millis / 1000;
+    localtime_tz(&seconds, &(this->t), this->timezone);
+}
+
+}; // namespace android
+
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
new file mode 100644
index 0000000..cdb8ca2
--- /dev/null
+++ b/libs/utils/Android.mk
@@ -0,0 +1,156 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+# libutils is a little unique: It's built twice, once for the host
+# and once for the device.
+
+commonSources:= \
+	Asset.cpp \
+	AssetDir.cpp \
+	AssetManager.cpp \
+	BufferedTextOutput.cpp \
+	CallStack.cpp \
+	Debug.cpp \
+	FileMap.cpp \
+	RefBase.cpp \
+	ResourceTypes.cpp \
+	SharedBuffer.cpp \
+	Static.cpp \
+	StopWatch.cpp \
+	String8.cpp \
+	String16.cpp \
+	SystemClock.cpp \
+	TextOutput.cpp \
+	Threads.cpp \
+	TimerProbe.cpp \
+	Timers.cpp \
+	VectorImpl.cpp \
+    ZipFileCRO.cpp \
+	ZipFileRO.cpp \
+	ZipUtils.cpp \
+	misc.cpp \
+	ported.cpp \
+	LogSocket.cpp
+
+#
+# The cpp files listed here do not belong in the device
+# build.  Consult with the swetland before even thinking about
+# putting them in commonSources.
+#
+# They're used by the simulator runtime and by host-side tools like
+# aapt and the simulator front-end.
+#
+hostSources:= \
+	InetAddress.cpp \
+	Pipe.cpp \
+	Socket.cpp \
+	ZipEntry.cpp \
+	ZipFile.cpp
+
+# For the host
+# =====================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(commonSources) $(hostSources)
+
+ifeq ($(HOST_OS),linux)
+# Use the futex based mutex and condition variable
+# implementation from android-arm because it's shared mem safe
+	LOCAL_SRC_FILES += \
+		futex_synchro.c \
+		executablepath_linux.cpp
+endif
+ifeq ($(HOST_OS),darwin)
+	LOCAL_SRC_FILES += \
+		executablepath_darwin.cpp
+endif
+
+LOCAL_MODULE:= libutils
+
+LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS)
+LOCAL_C_INCLUDES += external/zlib
+
+ifeq ($(HOST_OS),windows)
+ifeq ($(strip $(USE_CYGWIN),),)
+# Under MinGW, ctype.h doesn't need multi-byte support
+LOCAL_CFLAGS += -DMB_CUR_MAX=1
+endif
+endif
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+
+# we have the common sources, plus some device-specific stuff
+LOCAL_SRC_FILES:= \
+	$(commonSources) \
+	Binder.cpp \
+	BpBinder.cpp \
+	IInterface.cpp \
+	IMemory.cpp \
+	IPCThreadState.cpp \
+	MemoryDealer.cpp \
+    MemoryBase.cpp \
+    MemoryHeapBase.cpp \
+    MemoryHeapPmem.cpp \
+	Parcel.cpp \
+	ProcessState.cpp \
+	IPermissionController.cpp \
+	IServiceManager.cpp \
+	Unicode.cpp
+
+ifeq ($(TARGET_SIMULATOR),true)
+LOCAL_SRC_FILES += $(hostSources)
+endif
+
+ifeq ($(TARGET_OS),linux)
+# Use the futex based mutex and condition variable
+# implementation from android-arm because it's shared mem safe
+LOCAL_SRC_FILES += futex_synchro.c
+LOCAL_LDLIBS += -lrt -ldl
+endif
+
+LOCAL_C_INCLUDES += \
+		external/zlib \
+		external/icu4c/common
+LOCAL_LDLIBS += -lpthread
+
+LOCAL_SHARED_LIBRARIES := \
+	libz \
+	liblog \
+	libcutils
+
+ifneq ($(TARGET_SIMULATOR),true)
+ifeq ($(TARGET_OS)-$(TARGET_ARCH),linux-x86)
+# This is needed on x86 to bring in dl_iterate_phdr for CallStack.cpp
+LOCAL_SHARED_LIBRARIES += \
+	libdl
+endif # linux-x86
+endif # sim
+
+LOCAL_MODULE:= libutils
+
+#LOCAL_CFLAGS+=
+#LOCAL_LDFLAGS:=
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/libs/utils/Asset.cpp b/libs/utils/Asset.cpp
new file mode 100644
index 0000000..91203dd
--- /dev/null
+++ b/libs/utils/Asset.cpp
@@ -0,0 +1,813 @@
+/*
+ * Copyright (C) 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.
+ */
+
+//
+// Provide access to a read-only asset.
+//
+
+#define LOG_TAG "asset"
+//#define NDEBUG 0
+
+#include <utils/Asset.h>
+#include <utils/Atomic.h>
+#include <utils/FileMap.h>
+#include <utils/ZipUtils.h>
+#include <utils/ZipFileRO.h>
+#include <utils/Log.h>
+
+#include <string.h>
+#include <memory.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+static volatile int32_t gCount = 0;
+
+int32_t Asset::getGlobalCount()
+{
+    return gCount;
+}
+
+Asset::Asset(void)
+    : mAccessMode(ACCESS_UNKNOWN)
+{
+    int count = android_atomic_inc(&gCount)+1;
+    //LOGI("Creating Asset %p #%d\n", this, count);
+}
+
+Asset::~Asset(void)
+{
+    int count = android_atomic_dec(&gCount);
+    //LOGI("Destroying Asset in %p #%d\n", this, count);
+}
+
+/*
+ * Create a new Asset from a file on disk.  There is a fair chance that
+ * the file doesn't actually exist.
+ *
+ * We can use "mode" to decide how we want to go about it.
+ */
+/*static*/ Asset* Asset::createFromFile(const char* fileName, AccessMode mode)
+{
+    _FileAsset* pAsset;
+    status_t result;
+    off_t length;
+    int fd;
+
+    fd = open(fileName, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        return NULL;
+
+    /*
+     * Under Linux, the lseek fails if we actually opened a directory.  To
+     * be correct we should test the file type explicitly, but since we
+     * always open things read-only it doesn't really matter, so there's
+     * no value in incurring the extra overhead of an fstat() call.
+     */
+    length = lseek(fd, 0, SEEK_END);
+    if (length < 0) {
+        ::close(fd);
+        return NULL;
+    }
+    (void) lseek(fd, 0, SEEK_SET);
+
+    pAsset = new _FileAsset;
+    result = pAsset->openChunk(fileName, fd, 0, length);
+    if (result != NO_ERROR) {
+        delete pAsset;
+        return NULL;
+    }
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+
+/*
+ * Create a new Asset from a compressed file on disk.  There is a fair chance
+ * that the file doesn't actually exist.
+ *
+ * We currently support gzip files.  We might want to handle .bz2 someday.
+ */
+/*static*/ Asset* Asset::createFromCompressedFile(const char* fileName,
+    AccessMode mode)
+{
+    _CompressedAsset* pAsset;
+    status_t result;
+    off_t fileLen;
+    bool scanResult;
+    long offset;
+    int method;
+    long uncompressedLen, compressedLen;
+    int fd;
+
+    fd = open(fileName, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        return NULL;
+
+    fileLen = lseek(fd, 0, SEEK_END);
+    if (fileLen < 0) {
+        ::close(fd);
+        return NULL;
+    }
+    (void) lseek(fd, 0, SEEK_SET);
+
+    /* want buffered I/O for the file scan; must dup so fclose() is safe */
+    FILE* fp = fdopen(dup(fd), "rb");
+    if (fp == NULL) {
+        ::close(fd);
+        return NULL;
+    }
+
+    unsigned long crc32;
+    scanResult = ZipUtils::examineGzip(fp, &method, &uncompressedLen,
+                    &compressedLen, &crc32);
+    offset = ftell(fp);
+    fclose(fp);
+    if (!scanResult) {
+        LOGD("File '%s' is not in gzip format\n", fileName);
+        ::close(fd);
+        return NULL;
+    }
+
+    pAsset = new _CompressedAsset;
+    result = pAsset->openChunk(fd, offset, method, uncompressedLen,
+                compressedLen);
+    if (result != NO_ERROR) {
+        delete pAsset;
+        return NULL;
+    }
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+
+#if 0
+/*
+ * Create a new Asset from part of an open file.
+ */
+/*static*/ Asset* Asset::createFromFileSegment(int fd, off_t offset,
+    size_t length, AccessMode mode)
+{
+    _FileAsset* pAsset;
+    status_t result;
+
+    pAsset = new _FileAsset;
+    result = pAsset->openChunk(NULL, fd, offset, length);
+    if (result != NO_ERROR)
+        return NULL;
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+/*
+ * Create a new Asset from compressed data in an open file.
+ */
+/*static*/ Asset* Asset::createFromCompressedData(int fd, off_t offset,
+    int compressionMethod, size_t uncompressedLen, size_t compressedLen,
+    AccessMode mode)
+{
+    _CompressedAsset* pAsset;
+    status_t result;
+
+    pAsset = new _CompressedAsset;
+    result = pAsset->openChunk(fd, offset, compressionMethod,
+                uncompressedLen, compressedLen);
+    if (result != NO_ERROR)
+        return NULL;
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+#endif
+
+/*
+ * Create a new Asset from a memory mapping.
+ */
+/*static*/ Asset* Asset::createFromUncompressedMap(FileMap* dataMap,
+    AccessMode mode)
+{
+    _FileAsset* pAsset;
+    status_t result;
+
+    pAsset = new _FileAsset;
+    result = pAsset->openChunk(dataMap);
+    if (result != NO_ERROR)
+        return NULL;
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+/*
+ * Create a new Asset from compressed data in a memory mapping.
+ */
+/*static*/ Asset* Asset::createFromCompressedMap(FileMap* dataMap,
+    int method, size_t uncompressedLen, AccessMode mode)
+{
+    _CompressedAsset* pAsset;
+    status_t result;
+
+    pAsset = new _CompressedAsset;
+    result = pAsset->openChunk(dataMap, method, uncompressedLen);
+    if (result != NO_ERROR)
+        return NULL;
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+
+/*
+ * Do generic seek() housekeeping.  Pass in the offset/whence values from
+ * the seek request, along with the current chunk offset and the chunk
+ * length.
+ *
+ * Returns the new chunk offset, or -1 if the seek is illegal.
+ */
+off_t Asset::handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn)
+{
+    off_t newOffset;
+
+    switch (whence) {
+    case SEEK_SET:
+        newOffset = offset;
+        break;
+    case SEEK_CUR:
+        newOffset = curPosn + offset;
+        break;
+    case SEEK_END:
+        newOffset = maxPosn + offset;
+        break;
+    default:
+        LOGW("unexpected whence %d\n", whence);
+        // this was happening due to an off_t size mismatch
+        assert(false);
+        return (off_t) -1;
+    }
+
+    if (newOffset < 0 || newOffset > maxPosn) {
+        LOGW("seek out of range: want %ld, end=%ld\n",
+            (long) newOffset, (long) maxPosn);
+        return (off_t) -1;
+    }
+
+    return newOffset;
+}
+
+
+/*
+ * ===========================================================================
+ *      _FileAsset
+ * ===========================================================================
+ */
+
+/*
+ * Constructor.
+ */
+_FileAsset::_FileAsset(void)
+    : mStart(0), mLength(0), mOffset(0), mFp(NULL), mFileName(NULL), mMap(NULL), mBuf(NULL)
+{
+}
+
+/*
+ * Destructor.  Release resources.
+ */
+_FileAsset::~_FileAsset(void)
+{
+    close();
+}
+
+/*
+ * Operate on a chunk of an uncompressed file.
+ *
+ * Zero-length chunks are allowed.
+ */
+status_t _FileAsset::openChunk(const char* fileName, int fd, off_t offset, size_t length)
+{
+    assert(mFp == NULL);    // no reopen
+    assert(mMap == NULL);
+    assert(fd >= 0);
+    assert(offset >= 0);
+
+    /*
+     * Seek to end to get file length.
+     */
+    off_t fileLength;
+    fileLength = lseek(fd, 0, SEEK_END);
+    if (fileLength == (off_t) -1) {
+        // probably a bad file descriptor
+        LOGD("failed lseek (errno=%d)\n", errno);
+        return UNKNOWN_ERROR;
+    }
+
+    if ((off_t) (offset + length) > fileLength) {
+        LOGD("start (%ld) + len (%ld) > end (%ld)\n",
+            (long) offset, (long) length, (long) fileLength);
+        return BAD_INDEX;
+    }
+
+    /* after fdopen, the fd will be closed on fclose() */
+    mFp = fdopen(fd, "rb");
+    if (mFp == NULL)
+        return UNKNOWN_ERROR;
+
+    mStart = offset;
+    mLength = length;
+    assert(mOffset == 0);
+
+    /* seek the FILE* to the start of chunk */
+    if (fseek(mFp, mStart, SEEK_SET) != 0) {
+        assert(false);
+    }
+
+    mFileName = fileName != NULL ? strdup(fileName) : NULL;
+    
+    return NO_ERROR;
+}
+
+/*
+ * Create the chunk from the map.
+ */
+status_t _FileAsset::openChunk(FileMap* dataMap)
+{
+    assert(mFp == NULL);    // no reopen
+    assert(mMap == NULL);
+    assert(dataMap != NULL);
+
+    mMap = dataMap;
+    mStart = -1;            // not used
+    mLength = dataMap->getDataLength();
+    assert(mOffset == 0);
+
+    return NO_ERROR;
+}
+
+/*
+ * Read a chunk of data.
+ */
+ssize_t _FileAsset::read(void* buf, size_t count)
+{
+    size_t maxLen;
+    size_t actual;
+
+    assert(mOffset >= 0 && mOffset <= mLength);
+
+    if (getAccessMode() == ACCESS_BUFFER) {
+        /*
+         * On first access, read or map the entire file.  The caller has
+         * requested buffer access, either because they're going to be
+         * using the buffer or because what they're doing has appropriate
+         * performance needs and access patterns.
+         */
+        if (mBuf == NULL)
+            getBuffer(false);
+    }
+
+    /* adjust count if we're near EOF */
+    maxLen = mLength - mOffset;
+    if (count > maxLen)
+        count = maxLen;
+
+    if (!count)
+        return 0;
+
+    if (mMap != NULL) {
+        /* copy from mapped area */
+        //printf("map read\n");
+        memcpy(buf, (char*)mMap->getDataPtr() + mOffset, count);
+        actual = count;
+    } else if (mBuf != NULL) {
+        /* copy from buffer */
+        //printf("buf read\n");
+        memcpy(buf, (char*)mBuf + mOffset, count);
+        actual = count;
+    } else {
+        /* read from the file */
+        //printf("file read\n");
+        if (ftell(mFp) != mStart + mOffset) {
+            LOGE("Hosed: %ld != %ld+%ld\n",
+                ftell(mFp), (long) mStart, (long) mOffset);
+            assert(false);
+        }
+
+        /*
+         * This returns 0 on error or eof.  We need to use ferror() or feof()
+         * to tell the difference, but we don't currently have those on the
+         * device.  However, we know how much data is *supposed* to be in the
+         * file, so if we don't read the full amount we know something is
+         * hosed.
+         */
+        actual = fread(buf, 1, count, mFp);
+        if (actual == 0)        // something failed -- I/O error?
+            return -1;
+
+        assert(actual == count);
+    }
+
+    mOffset += actual;
+    return actual;
+}
+
+/*
+ * Seek to a new position.
+ */
+off_t _FileAsset::seek(off_t offset, int whence)
+{
+    off_t newPosn;
+    long actualOffset;
+
+    // compute new position within chunk
+    newPosn = handleSeek(offset, whence, mOffset, mLength);
+    if (newPosn == (off_t) -1)
+        return newPosn;
+
+    actualOffset = (long) (mStart + newPosn);
+
+    if (mFp != NULL) {
+        if (fseek(mFp, (long) actualOffset, SEEK_SET) != 0)
+            return (off_t) -1;
+    }
+
+    mOffset = actualOffset - mStart;
+    return mOffset;
+}
+
+/*
+ * Close the asset.
+ */
+void _FileAsset::close(void)
+{
+    if (mMap != NULL) {
+        mMap->release();
+        mMap = NULL;
+    }
+    if (mBuf != NULL) {
+        delete[] mBuf;
+        mBuf = NULL;
+    }
+
+    if (mFileName != NULL) {
+        free(mFileName);
+        mFileName = NULL;
+    }
+    
+    if (mFp != NULL) {
+        // can only be NULL when called from destructor
+        // (otherwise we would never return this object)
+        fclose(mFp);
+        mFp = NULL;
+    }
+}
+
+/*
+ * Return a read-only pointer to a buffer.
+ *
+ * We can either read the whole thing in or map the relevant piece of
+ * the source file.  Ideally a map would be established at a higher
+ * level and we'd be using a different object, but we didn't, so we
+ * deal with it here.
+ */
+const void* _FileAsset::getBuffer(bool wordAligned)
+{
+    /* subsequent requests just use what we did previously */
+    if (mBuf != NULL)
+        return mBuf;
+    if (mMap != NULL) {
+        if (!wordAligned) {
+            return  mMap->getDataPtr();
+        }
+        return ensureAlignment(mMap);
+    }
+
+    assert(mFp != NULL);
+
+    if (mLength < kReadVsMapThreshold) {
+        unsigned char* buf;
+        long allocLen;
+
+        /* zero-length files are allowed; not sure about zero-len allocs */
+        /* (works fine with gcc + x86linux) */
+        allocLen = mLength;
+        if (mLength == 0)
+            allocLen = 1;
+
+        buf = new unsigned char[allocLen];
+        if (buf == NULL) {
+            LOGE("alloc of %ld bytes failed\n", (long) allocLen);
+            return NULL;
+        }
+
+        LOGV("Asset %p allocating buffer size %d (smaller than threshold)", this, (int)allocLen);
+        if (mLength > 0) {
+            long oldPosn = ftell(mFp);
+            fseek(mFp, mStart, SEEK_SET);
+            if (fread(buf, 1, mLength, mFp) != (size_t) mLength) {
+                LOGE("failed reading %ld bytes\n", (long) mLength);
+                delete[] buf;
+                return NULL;
+            }
+            fseek(mFp, oldPosn, SEEK_SET);
+        }
+
+        LOGV(" getBuffer: loaded into buffer\n");
+
+        mBuf = buf;
+        return mBuf;
+    } else {
+        FileMap* map;
+
+        map = new FileMap;
+        if (!map->create(NULL, fileno(mFp), mStart, mLength, true)) {
+            map->release();
+            return NULL;
+        }
+
+        LOGV(" getBuffer: mapped\n");
+
+        mMap = map;
+        if (!wordAligned) {
+            return  mMap->getDataPtr();
+        }
+        return ensureAlignment(mMap);
+    }
+}
+
+int _FileAsset::openFileDescriptor(off_t* outStart, off_t* outLength) const
+{
+    if (mMap != NULL) {
+        const char* fname = mMap->getFileName();
+        if (fname == NULL) {
+            fname = mFileName;
+        }
+        if (fname == NULL) {
+            return -1;
+        }
+        *outStart = mMap->getDataOffset();
+        *outLength = mMap->getDataLength();
+        return open(fname, O_RDONLY | O_BINARY);
+    }
+    if (mFileName == NULL) {
+        return -1;
+    }
+    *outStart = mStart;
+    *outLength = mLength;
+    return open(mFileName, O_RDONLY | O_BINARY);
+}
+
+const void* _FileAsset::ensureAlignment(FileMap* map)
+{
+    void* data = map->getDataPtr();
+    if ((((size_t)data)&0x3) == 0) {
+        // We can return this directly if it is aligned on a word
+        // boundary.
+        return data;
+    }
+    // If not aligned on a word boundary, then we need to copy it into
+    // our own buffer.
+    LOGV("Copying FileAsset %p to buffer size %d to make it aligned.", this, (int)mLength);
+    unsigned char* buf = new unsigned char[mLength];
+    if (buf == NULL) {
+        LOGE("alloc of %ld bytes failed\n", (long) mLength);
+        return NULL;
+    }
+    memcpy(buf, data, mLength);
+    mBuf = buf;
+    return buf;
+}
+
+/*
+ * ===========================================================================
+ *      _CompressedAsset
+ * ===========================================================================
+ */
+
+/*
+ * Constructor.
+ */
+_CompressedAsset::_CompressedAsset(void)
+    : mStart(0), mCompressedLen(0), mUncompressedLen(0), mOffset(0),
+      mMap(NULL), mFd(-1), mBuf(NULL)
+{
+}
+
+/*
+ * Destructor.  Release resources.
+ */
+_CompressedAsset::~_CompressedAsset(void)
+{
+    close();
+}
+
+/*
+ * Open a chunk of compressed data inside a file.
+ *
+ * This currently just sets up some values and returns.  On the first
+ * read, we expand the entire file into a buffer and return data from it.
+ */
+status_t _CompressedAsset::openChunk(int fd, off_t offset,
+    int compressionMethod, size_t uncompressedLen, size_t compressedLen)
+{
+    assert(mFd < 0);        // no re-open
+    assert(mMap == NULL);
+    assert(fd >= 0);
+    assert(offset >= 0);
+    assert(compressedLen > 0);
+
+    if (compressionMethod != ZipFileRO::kCompressDeflated) {
+        assert(false);
+        return UNKNOWN_ERROR;
+    }
+
+    mStart = offset;
+    mCompressedLen = compressedLen;
+    mUncompressedLen = uncompressedLen;
+    assert(mOffset == 0);
+    mFd = fd;
+    assert(mBuf == NULL);
+
+    return NO_ERROR;
+}
+
+/*
+ * Open a chunk of compressed data in a mapped region.
+ *
+ * Nothing is expanded until the first read call.
+ */
+status_t _CompressedAsset::openChunk(FileMap* dataMap, int compressionMethod,
+    size_t uncompressedLen)
+{
+    assert(mFd < 0);        // no re-open
+    assert(mMap == NULL);
+    assert(dataMap != NULL);
+
+    if (compressionMethod != ZipFileRO::kCompressDeflated) {
+        assert(false);
+        return UNKNOWN_ERROR;
+    }
+
+    mMap = dataMap;
+    mStart = -1;        // not used
+    mCompressedLen = dataMap->getDataLength();
+    mUncompressedLen = uncompressedLen;
+    assert(mOffset == 0);
+
+    return NO_ERROR;
+}
+
+/*
+ * Read data from a chunk of compressed data.
+ *
+ * [For now, that's just copying data out of a buffer.]
+ */
+ssize_t _CompressedAsset::read(void* buf, size_t count)
+{
+    size_t maxLen;
+    size_t actual;
+
+    assert(mOffset >= 0 && mOffset <= mUncompressedLen);
+
+    // TODO: if mAccessMode == ACCESS_STREAMING, use zlib more cleverly
+
+    if (mBuf == NULL) {
+        if (getBuffer(false) == NULL)
+            return -1;
+    }
+    assert(mBuf != NULL);
+
+    /* adjust count if we're near EOF */
+    maxLen = mUncompressedLen - mOffset;
+    if (count > maxLen)
+        count = maxLen;
+
+    if (!count)
+        return 0;
+
+    /* copy from buffer */
+    //printf("comp buf read\n");
+    memcpy(buf, (char*)mBuf + mOffset, count);
+    actual = count;
+
+    mOffset += actual;
+    return actual;
+}
+
+/*
+ * Handle a seek request.
+ *
+ * If we're working in a streaming mode, this is going to be fairly
+ * expensive, because it requires plowing through a bunch of compressed
+ * data.
+ */
+off_t _CompressedAsset::seek(off_t offset, int whence)
+{
+    off_t newPosn;
+
+    // compute new position within chunk
+    newPosn = handleSeek(offset, whence, mOffset, mUncompressedLen);
+    if (newPosn == (off_t) -1)
+        return newPosn;
+
+    mOffset = newPosn;
+    return mOffset;
+}
+
+/*
+ * Close the asset.
+ */
+void _CompressedAsset::close(void)
+{
+    if (mMap != NULL) {
+        mMap->release();
+        mMap = NULL;
+    }
+    if (mBuf != NULL) {
+        delete[] mBuf;
+        mBuf = NULL;
+    }
+
+    if (mFd > 0) {
+        ::close(mFd);
+        mFd = -1;
+    }
+}
+
+/*
+ * Get a pointer to a read-only buffer of data.
+ *
+ * The first time this is called, we expand the compressed data into a
+ * buffer.
+ */
+const void* _CompressedAsset::getBuffer(bool wordAligned)
+{
+    unsigned char* buf = NULL;
+
+    if (mBuf != NULL)
+        return mBuf;
+
+    if (mUncompressedLen > UNCOMPRESS_DATA_MAX) {
+        LOGD("Data exceeds UNCOMPRESS_DATA_MAX (%ld vs %d)\n",
+            (long) mUncompressedLen, UNCOMPRESS_DATA_MAX);
+        goto bail;
+    }
+
+    /*
+     * Allocate a buffer and read the file into it.
+     */
+    buf = new unsigned char[mUncompressedLen];
+    if (buf == NULL) {
+        LOGW("alloc %ld bytes failed\n", (long) mUncompressedLen);
+        goto bail;
+    }
+
+    if (mMap != NULL) {
+        if (!ZipFileRO::inflateBuffer(buf, mMap->getDataPtr(),
+                mUncompressedLen, mCompressedLen))
+            goto bail;
+    } else {
+        assert(mFd >= 0);
+
+        /*
+         * Seek to the start of the compressed data.
+         */
+        if (lseek(mFd, mStart, SEEK_SET) != mStart)
+            goto bail;
+
+        /*
+         * Expand the data into it.
+         */
+        if (!ZipUtils::inflateToBuffer(mFd, buf, mUncompressedLen,
+                mCompressedLen))
+            goto bail;
+    }
+
+    /* success! */
+    mBuf = buf;
+    buf = NULL;
+
+bail:
+    delete[] buf;
+    return mBuf;
+}
+
diff --git a/libs/utils/AssetDir.cpp b/libs/utils/AssetDir.cpp
new file mode 100644
index 0000000..c5f664e
--- /dev/null
+++ b/libs/utils/AssetDir.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 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.
+ */
+
+//
+// Provide access to a virtual directory in "asset space".  Most of the
+// implementation is in the header file or in friend functions in
+// AssetManager.
+//
+#include <utils/AssetDir.h>
+
+using namespace android;
+
+
+/*
+ * Find a matching entry in a vector of FileInfo.  Because it's sorted, we
+ * can use a binary search.
+ *
+ * Assumes the vector is sorted in ascending order.
+ */
+/*static*/ int AssetDir::FileInfo::findEntry(const SortedVector<FileInfo>* pVector,
+    const String8& fileName)
+{
+    FileInfo tmpInfo;
+
+    tmpInfo.setFileName(fileName);
+    return pVector->indexOf(tmpInfo);
+
+#if 0  // don't need this after all (uses 1/2 compares of SortedVector though)
+    int lo, hi, cur;
+
+    lo = 0;
+    hi = pVector->size() -1;
+    while (lo <= hi) {
+        int cmp;
+
+        cur = (hi + lo) / 2;
+        cmp = strcmp(pVector->itemAt(cur).getFileName(), fileName);
+        if (cmp == 0) {
+            /* match, bail */
+            return cur;
+        } else if (cmp < 0) {
+            /* too low */
+            lo = cur + 1;
+        } else {
+            /* too high */
+            hi = cur -1;
+        }
+    }
+
+    return -1;
+#endif
+}
+
diff --git a/libs/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp
new file mode 100644
index 0000000..447b801
--- /dev/null
+++ b/libs/utils/AssetManager.cpp
@@ -0,0 +1,1637 @@
+/*
+ * Copyright (C) 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.
+ */
+
+//
+// Provide access to read-only assets.
+//
+
+#define LOG_TAG "asset"
+//#define LOG_NDEBUG 0
+
+#include <utils/AssetManager.h>
+#include <utils/AssetDir.h>
+#include <utils/Asset.h>
+#include <utils/Atomic.h>
+#include <utils/String8.h>
+#include <utils/ResourceTypes.h>
+#include <utils/String8.h>
+#include <utils/ZipFileRO.h>
+#include <utils/Log.h>
+#include <utils/Timers.h>
+#include <utils/threads.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+/*
+ * Names for default app, locale, and vendor.  We might want to change
+ * these to be an actual locale, e.g. always use en-US as the default.
+ */
+static const char* kDefaultLocale = "default";
+static const char* kDefaultVendor = "default";
+static const char* kAssetsRoot = "assets";
+static const char* kAppZipName = NULL; //"classes.jar";
+static const char* kSystemAssets = "framework/framework-res.apk";
+
+static const char* kExcludeExtension = ".EXCLUDE";
+
+static Asset* const kExcludedAsset = (Asset*) 0xd000000d;
+
+static volatile int32_t gCount = 0;
+
+
+/*
+ * ===========================================================================
+ *      AssetManager
+ * ===========================================================================
+ */
+
+int32_t AssetManager::getGlobalCount()
+{
+    return gCount;
+}
+
+AssetManager::AssetManager(CacheMode cacheMode)
+    : mLocale(NULL), mVendor(NULL),
+      mResources(NULL), mConfig(new ResTable_config),
+      mCacheMode(cacheMode), mCacheValid(false)
+{
+    int count = android_atomic_inc(&gCount)+1;
+    //LOGI("Creating AssetManager %p #%d\n", this, count);
+    memset(mConfig, 0, sizeof(ResTable_config));
+}
+
+AssetManager::~AssetManager(void)
+{
+    int count = android_atomic_dec(&gCount);
+    //LOGI("Destroying AssetManager in %p #%d\n", this, count);
+
+    delete mConfig;
+    delete mResources;
+
+    // don't have a String class yet, so make sure we clean up
+    delete[] mLocale;
+    delete[] mVendor;
+}
+
+bool AssetManager::addAssetPath(const String8& path, void** cookie)
+{
+    AutoMutex _l(mLock);
+
+    asset_path ap;
+
+    String8 realPath(path);
+    if (kAppZipName) {
+        realPath.appendPath(kAppZipName);
+    }
+    ap.type = ::getFileType(realPath.string());
+    if (ap.type == kFileTypeRegular) {
+        ap.path = realPath;
+    } else {
+        ap.path = path;
+        ap.type = ::getFileType(path.string());
+        if (ap.type != kFileTypeDirectory && ap.type != kFileTypeRegular) {
+            LOGW("Asset path %s is neither a directory nor file (type=%d).",
+                 path.string(), (int)ap.type);
+            return false;
+        }
+    }
+
+    // Skip if we have it already.
+    for (size_t i=0; i<mAssetPaths.size(); i++) {
+        if (mAssetPaths[i].path == ap.path) {
+            if (cookie) {
+                *cookie = (void*)(i+1);
+            }
+            return true;
+        }
+    }
+    
+    LOGV("In %p Asset %s path: %s", this,
+         ap.type == kFileTypeDirectory ? "dir" : "zip", ap.path.string());
+
+    mAssetPaths.add(ap);
+
+    // new paths are always added at the end
+    if (cookie) {
+        *cookie = (void*)mAssetPaths.size();
+    }
+
+    return true;
+}
+
+bool AssetManager::addDefaultAssets()
+{
+    const char* root = getenv("ANDROID_ROOT");
+    LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_ROOT not set");
+
+    String8 path(root);
+    path.appendPath(kSystemAssets);
+
+    return addAssetPath(path, NULL);
+}
+
+void* AssetManager::nextAssetPath(void* cookie) const
+{
+    AutoMutex _l(mLock);
+    size_t next = ((size_t)cookie)+1;
+    return next > mAssetPaths.size() ? NULL : (void*)next;
+}
+
+String8 AssetManager::getAssetPath(void* cookie) const
+{
+    AutoMutex _l(mLock);
+    const size_t which = ((size_t)cookie)-1;
+    if (which < mAssetPaths.size()) {
+        return mAssetPaths[which].path;
+    }
+    return String8();
+}
+
+/*
+ * Set the current locale.  Use NULL to indicate no locale.
+ *
+ * Close and reopen Zip archives as appropriate, and reset cached
+ * information in the locale-specific sections of the tree.
+ */
+void AssetManager::setLocale(const char* locale)
+{
+    AutoMutex _l(mLock);
+    setLocaleLocked(locale);
+}
+
+void AssetManager::setLocaleLocked(const char* locale)
+{
+    if (mLocale != NULL) {
+        /* previously set, purge cached data */
+        purgeFileNameCacheLocked();
+        //mZipSet.purgeLocale();
+        delete[] mLocale;
+    }
+    mLocale = strdupNew(locale);
+    
+    updateResourceParamsLocked();
+}
+
+/*
+ * Set the current vendor.  Use NULL to indicate no vendor.
+ *
+ * Close and reopen Zip archives as appropriate, and reset cached
+ * information in the vendor-specific sections of the tree.
+ */
+void AssetManager::setVendor(const char* vendor)
+{
+    AutoMutex _l(mLock);
+
+    if (mVendor != NULL) {
+        /* previously set, purge cached data */
+        purgeFileNameCacheLocked();
+        //mZipSet.purgeVendor();
+        delete[] mVendor;
+    }
+    mVendor = strdupNew(vendor);
+}
+
+void AssetManager::setConfiguration(const ResTable_config& config, const char* locale)
+{
+    AutoMutex _l(mLock);
+    *mConfig = config;
+    if (locale) {
+        setLocaleLocked(locale);
+    } else if (config.language[0] != 0) {
+        char spec[9];
+        spec[0] = config.language[0];
+        spec[1] = config.language[1];
+        if (config.country[0] != 0) {
+            spec[2] = '_';
+            spec[3] = config.country[0];
+            spec[4] = config.country[1];
+            spec[5] = 0;
+        } else {
+            spec[3] = 0;
+        }
+        setLocaleLocked(spec);
+    } else {
+        updateResourceParamsLocked();
+    }
+}
+
+/*
+ * Open an asset.
+ *
+ * The data could be;
+ *  - In a file on disk (assetBase + fileName).
+ *  - In a compressed file on disk (assetBase + fileName.gz).
+ *  - In a Zip archive, uncompressed or compressed.
+ *
+ * It can be in a number of different directories and Zip archives.
+ * The search order is:
+ *  - [appname]
+ *    - locale + vendor
+ *    - "default" + vendor
+ *    - locale + "default"
+ *    - "default + "default"
+ *  - "common"
+ *    - (same as above)
+ *
+ * To find a particular file, we have to try up to eight paths with
+ * all three forms of data.
+ *
+ * We should probably reject requests for "illegal" filenames, e.g. those
+ * with illegal characters or "../" backward relative paths.
+ */
+Asset* AssetManager::open(const char* fileName, AccessMode mode)
+{
+    AutoMutex _l(mLock);
+
+    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        loadFileNameCacheLocked();
+
+    String8 assetName(kAssetsRoot);
+    assetName.appendPath(fileName);
+
+    /*
+     * For each top-level asset path, search for the asset.
+     */
+
+    size_t i = mAssetPaths.size();
+    while (i > 0) {
+        i--;
+        LOGV("Looking for asset '%s' in '%s'\n",
+                assetName.string(), mAssetPaths.itemAt(i).path.string());
+        Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, mAssetPaths.itemAt(i));
+        if (pAsset != NULL) {
+            return pAsset != kExcludedAsset ? pAsset : NULL;
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Open a non-asset file as if it were an asset.
+ *
+ * The "fileName" is the partial path starting from the application
+ * name.
+ */
+Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode)
+{
+    AutoMutex _l(mLock);
+
+    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        loadFileNameCacheLocked();
+
+    /*
+     * For each top-level asset path, search for the asset.
+     */
+
+    size_t i = mAssetPaths.size();
+    while (i > 0) {
+        i--;
+        LOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.string());
+        Asset* pAsset = openNonAssetInPathLocked(
+            fileName, mode, mAssetPaths.itemAt(i));
+        if (pAsset != NULL) {
+            return pAsset != kExcludedAsset ? pAsset : NULL;
+        }
+    }
+
+    return NULL;
+}
+
+Asset* AssetManager::openNonAsset(void* cookie, const char* fileName, AccessMode mode)
+{
+    const size_t which = ((size_t)cookie)-1;
+
+    AutoMutex _l(mLock);
+
+    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        loadFileNameCacheLocked();
+
+    if (which < mAssetPaths.size()) {
+        LOGV("Looking for non-asset '%s' in '%s'\n", fileName,
+                mAssetPaths.itemAt(which).path.string());
+        Asset* pAsset = openNonAssetInPathLocked(
+            fileName, mode, mAssetPaths.itemAt(which));
+        if (pAsset != NULL) {
+            return pAsset != kExcludedAsset ? pAsset : NULL;
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Get the type of a file in the asset namespace.
+ *
+ * This currently only works for regular files.  All others (including
+ * directories) will return kFileTypeNonexistent.
+ */
+FileType AssetManager::getFileType(const char* fileName)
+{
+    Asset* pAsset = NULL;
+
+    /*
+     * Open the asset.  This is less efficient than simply finding the
+     * file, but it's not too bad (we don't uncompress or mmap data until
+     * the first read() call).
+     */
+    pAsset = open(fileName, Asset::ACCESS_STREAMING);
+    delete pAsset;
+
+    if (pAsset == NULL)
+        return kFileTypeNonexistent;
+    else
+        return kFileTypeRegular;
+}
+
+const ResTable* AssetManager::getResTable(bool required) const
+{
+    ResTable* rt = mResources;
+    if (rt) {
+        return rt;
+    }
+
+    // Iterate through all asset packages, collecting resources from each.
+
+    AutoMutex _l(mLock);
+
+    if (mResources != NULL) {
+        return mResources;
+    }
+
+    if (required) {
+        LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+    }
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        const_cast<AssetManager*>(this)->loadFileNameCacheLocked();
+
+    const size_t N = mAssetPaths.size();
+    for (size_t i=0; i<N; i++) {
+        Asset* ass = NULL;
+        bool shared = true;
+        const asset_path& ap = mAssetPaths.itemAt(i);
+        LOGV("Looking for resource asset in '%s'\n", ap.path.string());
+        if (ap.type != kFileTypeDirectory) {
+            ass = const_cast<AssetManager*>(this)->
+                mZipSet.getZipResourceTable(ap.path);
+            if (ass == NULL) {
+                LOGV("loading resource table %s\n", ap.path.string());
+                ass = const_cast<AssetManager*>(this)->
+                    openNonAssetInPathLocked("resources.arsc",
+                                             Asset::ACCESS_BUFFER,
+                                             ap);
+                if (ass != NULL && ass != kExcludedAsset) {
+                    ass = const_cast<AssetManager*>(this)->
+                        mZipSet.setZipResourceTable(ap.path, ass);
+                }
+            }
+        } else {
+            LOGV("loading resource table %s\n", ap.path.string());
+            Asset* ass = const_cast<AssetManager*>(this)->
+                openNonAssetInPathLocked("resources.arsc",
+                                         Asset::ACCESS_BUFFER,
+                                         ap);
+            shared = false;
+        }
+        if (ass != NULL && ass != kExcludedAsset) {
+            if (rt == NULL) {
+                mResources = rt = new ResTable();
+                updateResourceParamsLocked();
+            }
+            LOGV("Installing resource asset %p in to table %p\n", ass, mResources);
+            rt->add(ass, (void*)(i+1), !shared);
+
+            if (!shared) {
+                delete ass;
+            }
+        }
+    }
+
+    if (required && !rt) LOGW("Unable to find resources file resources.arsc");
+    if (!rt) {
+        mResources = rt = new ResTable();
+    }
+    return rt;
+}
+
+void AssetManager::updateResourceParamsLocked() const
+{
+    ResTable* res = mResources;
+    if (!res) {
+        return;
+    }
+
+    size_t llen = mLocale ? strlen(mLocale) : 0;
+    mConfig->language[0] = 0;
+    mConfig->language[1] = 0;
+    mConfig->country[0] = 0;
+    mConfig->country[1] = 0;
+    if (llen >= 2) {
+        mConfig->language[0] = mLocale[0];
+        mConfig->language[1] = mLocale[1];
+    }
+    if (llen >= 5) {
+        mConfig->country[0] = mLocale[3];
+        mConfig->country[1] = mLocale[4];
+    }
+    mConfig->size = sizeof(*mConfig);
+
+    res->setParameters(mConfig);
+}
+
+const ResTable& AssetManager::getResources(bool required) const
+{
+    const ResTable* rt = getResTable(required);
+    return *rt;
+}
+
+bool AssetManager::isUpToDate()
+{
+    AutoMutex _l(mLock);
+    return mZipSet.isUpToDate();
+}
+
+void AssetManager::getLocales(Vector<String8>* locales) const
+{
+    ResTable* res = mResources;
+    if (res != NULL) {
+        res->getLocales(locales);
+    }
+}
+
+/*
+ * Open a non-asset file as if it were an asset, searching for it in the
+ * specified app.
+ *
+ * Pass in a NULL values for "appName" if the common app directory should
+ * be used.
+ */
+Asset* AssetManager::openNonAssetInPathLocked(const char* fileName, AccessMode mode,
+    const asset_path& ap)
+{
+    Asset* pAsset = NULL;
+
+    /* look at the filesystem on disk */
+    if (ap.type == kFileTypeDirectory) {
+        String8 path(ap.path);
+        path.appendPath(fileName);
+
+        pAsset = openAssetFromFileLocked(path, mode);
+
+        if (pAsset == NULL) {
+            /* try again, this time with ".gz" */
+            path.append(".gz");
+            pAsset = openAssetFromFileLocked(path, mode);
+        }
+
+        if (pAsset != NULL) {
+            //printf("FOUND NA '%s' on disk\n", fileName);
+            pAsset->setAssetSource(path);
+        }
+
+    /* look inside the zip file */
+    } else {
+        String8 path(fileName);
+
+        /* check the appropriate Zip file */
+        ZipFileRO* pZip;
+        ZipEntryRO entry;
+
+        pZip = getZipFileLocked(ap);
+        if (pZip != NULL) {
+            //printf("GOT zip, checking NA '%s'\n", (const char*) path);
+            entry = pZip->findEntryByName(path.string());
+            if (entry != NULL) {
+                //printf("FOUND NA in Zip file for %s\n", appName ? appName : kAppCommon);
+                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
+            }
+        }
+
+        if (pAsset != NULL) {
+            /* create a "source" name, for debug/display */
+            pAsset->setAssetSource(
+                    createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()), String8(""),
+                                                String8(fileName)));
+        }
+    }
+
+    return pAsset;
+}
+
+/*
+ * Open an asset, searching for it in the directory hierarchy for the
+ * specified app.
+ *
+ * Pass in a NULL values for "appName" if the common app directory should
+ * be used.
+ */
+Asset* AssetManager::openInPathLocked(const char* fileName, AccessMode mode,
+    const asset_path& ap)
+{
+    Asset* pAsset = NULL;
+
+    /*
+     * Try various combinations of locale and vendor.
+     */
+    if (mLocale != NULL && mVendor != NULL)
+        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, mVendor);
+    if (pAsset == NULL && mVendor != NULL)
+        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, mVendor);
+    if (pAsset == NULL && mLocale != NULL)
+        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, NULL);
+    if (pAsset == NULL)
+        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, NULL);
+
+    return pAsset;
+}
+
+/*
+ * Open an asset, searching for it in the directory hierarchy for the
+ * specified locale and vendor.
+ *
+ * We also search in "app.jar".
+ *
+ * Pass in NULL values for "appName", "locale", and "vendor" if the
+ * defaults should be used.
+ */
+Asset* AssetManager::openInLocaleVendorLocked(const char* fileName, AccessMode mode,
+    const asset_path& ap, const char* locale, const char* vendor)
+{
+    Asset* pAsset = NULL;
+
+    if (ap.type == kFileTypeDirectory) {
+        if (mCacheMode == CACHE_OFF) {
+            /* look at the filesystem on disk */
+            String8 path(createPathNameLocked(ap, locale, vendor));
+            path.appendPath(fileName);
+    
+            String8 excludeName(path);
+            excludeName.append(kExcludeExtension);
+            if (::getFileType(excludeName.string()) != kFileTypeNonexistent) {
+                /* say no more */
+                //printf("+++ excluding '%s'\n", (const char*) excludeName);
+                return kExcludedAsset;
+            }
+    
+            pAsset = openAssetFromFileLocked(path, mode);
+    
+            if (pAsset == NULL) {
+                /* try again, this time with ".gz" */
+                path.append(".gz");
+                pAsset = openAssetFromFileLocked(path, mode);
+            }
+    
+            if (pAsset != NULL)
+                pAsset->setAssetSource(path);
+        } else {
+            /* find in cache */
+            String8 path(createPathNameLocked(ap, locale, vendor));
+            path.appendPath(fileName);
+    
+            AssetDir::FileInfo tmpInfo;
+            bool found = false;
+    
+            String8 excludeName(path);
+            excludeName.append(kExcludeExtension);
+    
+            if (mCache.indexOf(excludeName) != NAME_NOT_FOUND) {
+                /* go no farther */
+                //printf("+++ Excluding '%s'\n", (const char*) excludeName);
+                return kExcludedAsset;
+            }
+
+            /*
+             * File compression extensions (".gz") don't get stored in the
+             * name cache, so we have to try both here.
+             */
+            if (mCache.indexOf(path) != NAME_NOT_FOUND) {
+                found = true;
+                pAsset = openAssetFromFileLocked(path, mode);
+                if (pAsset == NULL) {
+                    /* try again, this time with ".gz" */
+                    path.append(".gz");
+                    pAsset = openAssetFromFileLocked(path, mode);
+                }
+            }
+
+            if (pAsset != NULL)
+                pAsset->setAssetSource(path);
+
+            /*
+             * Don't continue the search into the Zip files.  Our cached info
+             * said it was a file on disk; to be consistent with openDir()
+             * we want to return the loose asset.  If the cached file gets
+             * removed, we fail.
+             *
+             * The alternative is to update our cache when files get deleted,
+             * or make some sort of "best effort" promise, but for now I'm
+             * taking the hard line.
+             */
+            if (found) {
+                if (pAsset == NULL)
+                    LOGD("Expected file not found: '%s'\n", path.string());
+                return pAsset;
+            }
+        }
+    }
+
+    /*
+     * Either it wasn't found on disk or on the cached view of the disk.
+     * Dig through the currently-opened set of Zip files.  If caching
+     * is disabled, the Zip file may get reopened.
+     */
+    if (pAsset == NULL && ap.type == kFileTypeRegular) {
+        String8 path;
+
+        path.appendPath((locale != NULL) ? locale : kDefaultLocale);
+        path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);
+        path.appendPath(fileName);
+
+        /* check the appropriate Zip file */
+        ZipFileRO* pZip;
+        ZipEntryRO entry;
+
+        pZip = getZipFileLocked(ap);
+        if (pZip != NULL) {
+            //printf("GOT zip, checking '%s'\n", (const char*) path);
+            entry = pZip->findEntryByName(path.string());
+            if (entry != NULL) {
+                //printf("FOUND in Zip file for %s/%s-%s\n",
+                //    appName, locale, vendor);
+                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
+            }
+        }
+
+        if (pAsset != NULL) {
+            /* create a "source" name, for debug/display */
+            pAsset->setAssetSource(createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()),
+                                                             String8(""), String8(fileName)));
+        }
+    }
+
+    return pAsset;
+}
+
+/*
+ * Create a "source name" for a file from a Zip archive.
+ */
+String8 AssetManager::createZipSourceNameLocked(const String8& zipFileName,
+    const String8& dirName, const String8& fileName)
+{
+    String8 sourceName("zip:");
+    sourceName.append(zipFileName);
+    sourceName.append(":");
+    if (dirName.length() > 0) {
+        sourceName.appendPath(dirName);
+    }
+    sourceName.appendPath(fileName);
+    return sourceName;
+}
+
+/*
+ * Create a path to a loose asset (asset-base/app/locale/vendor).
+ */
+String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* locale,
+    const char* vendor)
+{
+    String8 path(ap.path);
+    path.appendPath((locale != NULL) ? locale : kDefaultLocale);
+    path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);
+    return path;
+}
+
+/*
+ * Create a path to a loose asset (asset-base/app/rootDir).
+ */
+String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* rootDir)
+{
+    String8 path(ap.path);
+    if (rootDir != NULL) path.appendPath(rootDir);
+    return path;
+}
+
+/*
+ * Return a pointer to one of our open Zip archives.  Returns NULL if no
+ * matching Zip file exists.
+ *
+ * Right now we have 2 possible Zip files (1 each in app/"common").
+ *
+ * If caching is set to CACHE_OFF, to get the expected behavior we
+ * need to reopen the Zip file on every request.  That would be silly
+ * and expensive, so instead we just check the file modification date.
+ *
+ * Pass in NULL values for "appName", "locale", and "vendor" if the
+ * generics should be used.
+ */
+ZipFileRO* AssetManager::getZipFileLocked(const asset_path& ap)
+{
+    LOGV("getZipFileLocked() in %p\n", this);
+
+    return mZipSet.getZip(ap.path);
+}
+
+/*
+ * Try to open an asset from a file on disk.
+ *
+ * If the file is compressed with gzip, we seek to the start of the
+ * deflated data and pass that in (just like we would for a Zip archive).
+ *
+ * For uncompressed data, we may already have an mmap()ed version sitting
+ * around.  If so, we want to hand that to the Asset instead.
+ *
+ * This returns NULL if the file doesn't exist, couldn't be opened, or
+ * claims to be a ".gz" but isn't.
+ */
+Asset* AssetManager::openAssetFromFileLocked(const String8& pathName,
+    AccessMode mode)
+{
+    Asset* pAsset = NULL;
+
+    if (strcasecmp(pathName.getPathExtension().string(), ".gz") == 0) {
+        //printf("TRYING '%s'\n", (const char*) pathName);
+        pAsset = Asset::createFromCompressedFile(pathName.string(), mode);
+    } else {
+        //printf("TRYING '%s'\n", (const char*) pathName);
+        pAsset = Asset::createFromFile(pathName.string(), mode);
+    }
+
+    return pAsset;
+}
+
+/*
+ * Given an entry in a Zip archive, create a new Asset object.
+ *
+ * If the entry is uncompressed, we may want to create or share a
+ * slice of shared memory.
+ */
+Asset* AssetManager::openAssetFromZipLocked(const ZipFileRO* pZipFile,
+    const ZipEntryRO entry, AccessMode mode, const String8& entryName)
+{
+    Asset* pAsset = NULL;
+
+    // TODO: look for previously-created shared memory slice?
+    int method;
+    long uncompressedLen;
+
+    //printf("USING Zip '%s'\n", pEntry->getFileName());
+
+    //pZipFile->getEntryInfo(entry, &method, &uncompressedLen, &compressedLen,
+    //    &offset);
+    if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, NULL, NULL,
+            NULL, NULL))
+    {
+        LOGW("getEntryInfo failed\n");
+        return NULL;
+    }
+
+    FileMap* dataMap = pZipFile->createEntryFileMap(entry);
+    if (dataMap == NULL) {
+        LOGW("create map from entry failed\n");
+        return NULL;
+    }
+
+    if (method == ZipFileRO::kCompressStored) {
+        pAsset = Asset::createFromUncompressedMap(dataMap, mode);
+        LOGV("Opened uncompressed entry %s in zip %s mode %d: %p", entryName.string(),
+                dataMap->getFileName(), mode, pAsset);
+    } else {
+        pAsset = Asset::createFromCompressedMap(dataMap, method,
+            uncompressedLen, mode);
+        LOGV("Opened compressed entry %s in zip %s mode %d: %p", entryName.string(),
+                dataMap->getFileName(), mode, pAsset);
+    }
+    if (pAsset == NULL) {
+        /* unexpected */
+        LOGW("create from segment failed\n");
+    }
+
+    return pAsset;
+}
+
+
+
+/*
+ * Open a directory in the asset namespace.
+ *
+ * An "asset directory" is simply the combination of all files in all
+ * locations, with ".gz" stripped for loose files.  With app, locale, and
+ * vendor defined, we have 8 directories and 2 Zip archives to scan.
+ *
+ * Pass in "" for the root dir.
+ */
+AssetDir* AssetManager::openDir(const char* dirName)
+{
+    AutoMutex _l(mLock);
+
+    AssetDir* pDir = NULL;
+    SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;
+
+    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+    assert(dirName != NULL);
+
+    //printf("+++ openDir(%s) in '%s'\n", dirName, (const char*) mAssetBase);
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        loadFileNameCacheLocked();
+
+    pDir = new AssetDir;
+
+    /*
+     * Scan the various directories, merging what we find into a single
+     * vector.  We want to scan them in reverse priority order so that
+     * the ".EXCLUDE" processing works correctly.  Also, if we decide we
+     * want to remember where the file is coming from, we'll get the right
+     * version.
+     *
+     * We start with Zip archives, then do loose files.
+     */
+    pMergedInfo = new SortedVector<AssetDir::FileInfo>;
+
+    size_t i = mAssetPaths.size();
+    while (i > 0) {
+        i--;
+        const asset_path& ap = mAssetPaths.itemAt(i);
+        if (ap.type == kFileTypeRegular) {
+            LOGV("Adding directory %s from zip %s", dirName, ap.path.string());
+            scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName);
+        } else {
+            LOGV("Adding directory %s from dir %s", dirName, ap.path.string());
+            scanAndMergeDirLocked(pMergedInfo, ap, kAssetsRoot, dirName);
+        }
+    }
+
+#if 0
+    printf("FILE LIST:\n");
+    for (i = 0; i < (size_t) pMergedInfo->size(); i++) {
+        printf(" %d: (%d) '%s'\n", i,
+            pMergedInfo->itemAt(i).getFileType(),
+            (const char*) pMergedInfo->itemAt(i).getFileName());
+    }
+#endif
+
+    pDir->setFileList(pMergedInfo);
+    return pDir;
+}
+
+/*
+ * Scan the contents of the specified directory and merge them into the
+ * "pMergedInfo" vector, removing previous entries if we find "exclude"
+ * directives.
+ *
+ * Returns "false" if we found nothing to contribute.
+ */
+bool AssetManager::scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const asset_path& ap, const char* rootDir, const char* dirName)
+{
+    SortedVector<AssetDir::FileInfo>* pContents;
+    String8 path;
+
+    assert(pMergedInfo != NULL);
+
+    //printf("scanAndMergeDir: %s %s %s %s\n", appName, locale, vendor,dirName);
+
+    if (mCacheValid) {
+        int i, start, count;
+
+        pContents = new SortedVector<AssetDir::FileInfo>;
+
+        /*
+         * Get the basic partial path and find it in the cache.  That's
+         * the start point for the search.
+         */
+        path = createPathNameLocked(ap, rootDir);
+        if (dirName[0] != '\0')
+            path.appendPath(dirName);
+
+        start = mCache.indexOf(path);
+        if (start == NAME_NOT_FOUND) {
+            //printf("+++ not found in cache: dir '%s'\n", (const char*) path);
+            delete pContents;
+            return false;
+        }
+
+        /*
+         * The match string looks like "common/default/default/foo/bar/".
+         * The '/' on the end ensures that we don't match on the directory
+         * itself or on ".../foo/barfy/".
+         */
+        path.append("/");
+
+        count = mCache.size();
+
+        /*
+         * Pick out the stuff in the current dir by examining the pathname.
+         * It needs to match the partial pathname prefix, and not have a '/'
+         * (fssep) anywhere after the prefix.
+         */
+        for (i = start+1; i < count; i++) {
+            if (mCache[i].getFileName().length() > path.length() &&
+                strncmp(mCache[i].getFileName().string(), path.string(), path.length()) == 0)
+            {
+                const char* name = mCache[i].getFileName().string();
+                // XXX THIS IS BROKEN!  Looks like we need to store the full
+                // path prefix separately from the file path.
+                if (strchr(name + path.length(), '/') == NULL) {
+                    /* grab it, reducing path to just the filename component */
+                    AssetDir::FileInfo tmp = mCache[i];
+                    tmp.setFileName(tmp.getFileName().getPathLeaf());
+                    pContents->add(tmp);
+                }
+            } else {
+                /* no longer in the dir or its subdirs */
+                break;
+            }
+
+        }
+    } else {
+        path = createPathNameLocked(ap, rootDir);
+        if (dirName[0] != '\0')
+            path.appendPath(dirName);
+        pContents = scanDirLocked(path);
+        if (pContents == NULL)
+            return false;
+    }
+
+    // if we wanted to do an incremental cache fill, we would do it here
+
+    /*
+     * Process "exclude" directives.  If we find a filename that ends with
+     * ".EXCLUDE", we look for a matching entry in the "merged" set, and
+     * remove it if we find it.  We also delete the "exclude" entry.
+     */
+    int i, count, exclExtLen;
+
+    count = pContents->size();
+    exclExtLen = strlen(kExcludeExtension);
+    for (i = 0; i < count; i++) {
+        const char* name;
+        int nameLen;
+
+        name = pContents->itemAt(i).getFileName().string();
+        nameLen = strlen(name);
+        if (nameLen > exclExtLen &&
+            strcmp(name + (nameLen - exclExtLen), kExcludeExtension) == 0)
+        {
+            String8 match(name, nameLen - exclExtLen);
+            int matchIdx;
+
+            matchIdx = AssetDir::FileInfo::findEntry(pMergedInfo, match);
+            if (matchIdx > 0) {
+                LOGV("Excluding '%s' [%s]\n",
+                    pMergedInfo->itemAt(matchIdx).getFileName().string(),
+                    pMergedInfo->itemAt(matchIdx).getSourceName().string());
+                pMergedInfo->removeAt(matchIdx);
+            } else {
+                //printf("+++ no match on '%s'\n", (const char*) match);
+            }
+
+            LOGD("HEY: size=%d removing %d\n", (int)pContents->size(), i);
+            pContents->removeAt(i);
+            i--;        // adjust "for" loop
+            count--;    //  and loop limit
+        }
+    }
+
+    mergeInfoLocked(pMergedInfo, pContents);
+
+    delete pContents;
+
+    return true;
+}
+
+/*
+ * Scan the contents of the specified directory, and stuff what we find
+ * into a newly-allocated vector.
+ *
+ * Files ending in ".gz" will have their extensions removed.
+ *
+ * We should probably think about skipping files with "illegal" names,
+ * e.g. illegal characters (/\:) or excessive length.
+ *
+ * Returns NULL if the specified directory doesn't exist.
+ */
+SortedVector<AssetDir::FileInfo>* AssetManager::scanDirLocked(const String8& path)
+{
+    SortedVector<AssetDir::FileInfo>* pContents = NULL;
+    DIR* dir;
+    struct dirent* entry;
+    FileType fileType;
+
+    LOGV("Scanning dir '%s'\n", path.string());
+
+    dir = opendir(path.string());
+    if (dir == NULL)
+        return NULL;
+
+    pContents = new SortedVector<AssetDir::FileInfo>;
+
+    while (1) {
+        entry = readdir(dir);
+        if (entry == NULL)
+            break;
+
+        if (strcmp(entry->d_name, ".") == 0 ||
+            strcmp(entry->d_name, "..") == 0)
+            continue;
+
+#ifdef _DIRENT_HAVE_D_TYPE
+        if (entry->d_type == DT_REG)
+            fileType = kFileTypeRegular;
+        else if (entry->d_type == DT_DIR)
+            fileType = kFileTypeDirectory;
+        else
+            fileType = kFileTypeUnknown;
+#else
+        // stat the file
+        fileType = ::getFileType(path.appendPathCopy(entry->d_name).string());
+#endif
+
+        if (fileType != kFileTypeRegular && fileType != kFileTypeDirectory)
+            continue;
+
+        AssetDir::FileInfo info;
+        info.set(String8(entry->d_name), fileType);
+        if (strcasecmp(info.getFileName().getPathExtension().string(), ".gz") == 0)
+            info.setFileName(info.getFileName().getBasePath());
+        info.setSourceName(path.appendPathCopy(info.getFileName()));
+        pContents->add(info);
+    }
+
+    closedir(dir);
+    return pContents;
+}
+
+/*
+ * Scan the contents out of the specified Zip archive, and merge what we
+ * find into "pMergedInfo".  If the Zip archive in question doesn't exist,
+ * we return immediately.
+ *
+ * Returns "false" if we found nothing to contribute.
+ */
+bool AssetManager::scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const asset_path& ap, const char* rootDir, const char* baseDirName)
+{
+    ZipFileRO* pZip;
+    Vector<String8> dirs;
+    AssetDir::FileInfo info;
+    SortedVector<AssetDir::FileInfo> contents;
+    String8 sourceName, zipName, dirName;
+
+    pZip = mZipSet.getZip(ap.path);
+    if (pZip == NULL) {
+        LOGW("Failure opening zip %s\n", ap.path.string());
+        return false;
+    }
+
+    zipName = ZipSet::getPathName(ap.path.string());
+
+    /* convert "sounds" to "rootDir/sounds" */
+    if (rootDir != NULL) dirName = rootDir;
+    dirName.appendPath(baseDirName);
+
+    /*
+     * Scan through the list of files, looking for a match.  The files in
+     * the Zip table of contents are not in sorted order, so we have to
+     * process the entire list.  We're looking for a string that begins
+     * with the characters in "dirName", is followed by a '/', and has no
+     * subsequent '/' in the stuff that follows.
+     *
+     * What makes this especially fun is that directories are not stored
+     * explicitly in Zip archives, so we have to infer them from context.
+     * When we see "sounds/foo.wav" we have to leave a note to ourselves
+     * to insert a directory called "sounds" into the list.  We store
+     * these in temporary vector so that we only return each one once.
+     *
+     * Name comparisons are case-sensitive to match UNIX filesystem
+     * semantics.
+     */
+    int dirNameLen = dirName.length();
+    for (int i = 0; i < pZip->getNumEntries(); i++) {
+        ZipEntryRO entry;
+        char nameBuf[256];
+
+        entry = pZip->findEntryByIndex(i);
+        if (pZip->getEntryFileName(entry, nameBuf, sizeof(nameBuf)) != 0) {
+            // TODO: fix this if we expect to have long names
+            LOGE("ARGH: name too long?\n");
+            continue;
+        }
+        if (dirNameLen == 0 ||
+            (strncmp(nameBuf, dirName.string(), dirNameLen) == 0 &&
+             nameBuf[dirNameLen] == '/'))
+        {
+            const char* cp;
+            const char* nextSlash;
+
+            cp = nameBuf + dirNameLen;
+            if (dirNameLen != 0)
+                cp++;       // advance past the '/'
+
+            nextSlash = strchr(cp, '/');
+//xxx this may break if there are bare directory entries
+            if (nextSlash == NULL) {
+                /* this is a file in the requested directory */
+
+                info.set(String8(nameBuf).getPathLeaf(), kFileTypeRegular);
+
+                info.setSourceName(
+                    createZipSourceNameLocked(zipName, dirName, info.getFileName()));
+
+                contents.add(info);
+                //printf("FOUND: file '%s'\n", (const char*) info.mFileName);
+            } else {
+                /* this is a subdir; add it if we don't already have it*/
+                String8 subdirName(cp, nextSlash - cp);
+                size_t j;
+                size_t N = dirs.size();
+
+                for (j = 0; j < N; j++) {
+                    if (subdirName == dirs[j]) {
+                        break;
+                    }
+                }
+                if (j == N) {
+                    dirs.add(subdirName);
+                }
+
+                //printf("FOUND: dir '%s'\n", (const char*) subdirName);
+            }
+        }
+    }
+
+    /*
+     * Add the set of unique directories.
+     */
+    for (int i = 0; i < (int) dirs.size(); i++) {
+        info.set(dirs[i], kFileTypeDirectory);
+        info.setSourceName(
+            createZipSourceNameLocked(zipName, dirName, info.getFileName()));
+        contents.add(info);
+    }
+
+    mergeInfoLocked(pMergedInfo, &contents);
+
+    return true;
+}
+
+
+/*
+ * Merge two vectors of FileInfo.
+ *
+ * The merged contents will be stuffed into *pMergedInfo.
+ *
+ * If an entry for a file exists in both "pMergedInfo" and "pContents",
+ * we use the newer "pContents" entry.
+ */
+void AssetManager::mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const SortedVector<AssetDir::FileInfo>* pContents)
+{
+    /*
+     * Merge what we found in this directory with what we found in
+     * other places.
+     *
+     * Two basic approaches:
+     * (1) Create a new array that holds the unique values of the two
+     *     arrays.
+     * (2) Take the elements from pContents and shove them into pMergedInfo.
+     *
+     * Because these are vectors of complex objects, moving elements around
+     * inside the vector requires constructing new objects and allocating
+     * storage for members.  With approach #1, we're always adding to the
+     * end, whereas with #2 we could be inserting multiple elements at the
+     * front of the vector.  Approach #1 requires a full copy of the
+     * contents of pMergedInfo, but approach #2 requires the same copy for
+     * every insertion at the front of pMergedInfo.
+     *
+     * (We should probably use a SortedVector interface that allows us to
+     * just stuff items in, trusting us to maintain the sort order.)
+     */
+    SortedVector<AssetDir::FileInfo>* pNewSorted;
+    int mergeMax, contMax;
+    int mergeIdx, contIdx;
+
+    pNewSorted = new SortedVector<AssetDir::FileInfo>;
+    mergeMax = pMergedInfo->size();
+    contMax = pContents->size();
+    mergeIdx = contIdx = 0;
+
+    while (mergeIdx < mergeMax || contIdx < contMax) {
+        if (mergeIdx == mergeMax) {
+            /* hit end of "merge" list, copy rest of "contents" */
+            pNewSorted->add(pContents->itemAt(contIdx));
+            contIdx++;
+        } else if (contIdx == contMax) {
+            /* hit end of "cont" list, copy rest of "merge" */
+            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));
+            mergeIdx++;
+        } else if (pMergedInfo->itemAt(mergeIdx) == pContents->itemAt(contIdx))
+        {
+            /* items are identical, add newer and advance both indices */
+            pNewSorted->add(pContents->itemAt(contIdx));
+            mergeIdx++;
+            contIdx++;
+        } else if (pMergedInfo->itemAt(mergeIdx) < pContents->itemAt(contIdx))
+        {
+            /* "merge" is lower, add that one */
+            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));
+            mergeIdx++;
+        } else {
+            /* "cont" is lower, add that one */
+            assert(pContents->itemAt(contIdx) < pMergedInfo->itemAt(mergeIdx));
+            pNewSorted->add(pContents->itemAt(contIdx));
+            contIdx++;
+        }
+    }
+
+    /*
+     * Overwrite the "merged" list with the new stuff.
+     */
+    *pMergedInfo = *pNewSorted;
+    delete pNewSorted;
+
+#if 0       // for Vector, rather than SortedVector
+    int i, j;
+    for (i = pContents->size() -1; i >= 0; i--) {
+        bool add = true;
+
+        for (j = pMergedInfo->size() -1; j >= 0; j--) {
+            /* case-sensitive comparisons, to behave like UNIX fs */
+            if (strcmp(pContents->itemAt(i).mFileName,
+                       pMergedInfo->itemAt(j).mFileName) == 0)
+            {
+                /* match, don't add this entry */
+                add = false;
+                break;
+            }
+        }
+
+        if (add)
+            pMergedInfo->add(pContents->itemAt(i));
+    }
+#endif
+}
+
+
+/*
+ * Load all files into the file name cache.  We want to do this across
+ * all combinations of { appname, locale, vendor }, performing a recursive
+ * directory traversal.
+ *
+ * This is not the most efficient data structure.  Also, gathering the
+ * information as we needed it (file-by-file or directory-by-directory)
+ * would be faster.  However, on the actual device, 99% of the files will
+ * live in Zip archives, so this list will be very small.  The trouble
+ * is that we have to check the "loose" files first, so it's important
+ * that we don't beat the filesystem silly looking for files that aren't
+ * there.
+ *
+ * Note on thread safety: this is the only function that causes updates
+ * to mCache, and anybody who tries to use it will call here if !mCacheValid,
+ * so we need to employ a mutex here.
+ */
+void AssetManager::loadFileNameCacheLocked(void)
+{
+    assert(!mCacheValid);
+    assert(mCache.size() == 0);
+
+#ifdef DO_TIMINGS   // need to link against -lrt for this now
+    DurationTimer timer;
+    timer.start();
+#endif
+
+    fncScanLocked(&mCache, "");
+
+#ifdef DO_TIMINGS
+    timer.stop();
+    LOGD("Cache scan took %.3fms\n",
+        timer.durationUsecs() / 1000.0);
+#endif
+
+#if 0
+    int i;
+    printf("CACHED FILE LIST (%d entries):\n", mCache.size());
+    for (i = 0; i < (int) mCache.size(); i++) {
+        printf(" %d: (%d) '%s'\n", i,
+            mCache.itemAt(i).getFileType(),
+            (const char*) mCache.itemAt(i).getFileName());
+    }
+#endif
+
+    mCacheValid = true;
+}
+
+/*
+ * Scan up to 8 versions of the specified directory.
+ */
+void AssetManager::fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const char* dirName)
+{
+    size_t i = mAssetPaths.size();
+    while (i > 0) {
+        i--;
+        const asset_path& ap = mAssetPaths.itemAt(i);
+        fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, NULL, dirName);
+        if (mLocale != NULL)
+            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, NULL, dirName);
+        if (mVendor != NULL)
+            fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, mVendor, dirName);
+        if (mLocale != NULL && mVendor != NULL)
+            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, mVendor, dirName);
+    }
+}
+
+/*
+ * Recursively scan this directory and all subdirs.
+ *
+ * This is similar to scanAndMergeDir, but we don't remove the .EXCLUDE
+ * files, and we prepend the extended partial path to the filenames.
+ */
+bool AssetManager::fncScanAndMergeDirLocked(
+    SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const asset_path& ap, const char* locale, const char* vendor,
+    const char* dirName)
+{
+    SortedVector<AssetDir::FileInfo>* pContents;
+    String8 partialPath;
+    String8 fullPath;
+
+    // XXX This is broken -- the filename cache needs to hold the base
+    // asset path separately from its filename.
+    
+    partialPath = createPathNameLocked(ap, locale, vendor);
+    if (dirName[0] != '\0') {
+        partialPath.appendPath(dirName);
+    }
+
+    fullPath = partialPath;
+    pContents = scanDirLocked(fullPath);
+    if (pContents == NULL) {
+        return false;       // directory did not exist
+    }
+
+    /*
+     * Scan all subdirectories of the current dir, merging what we find
+     * into "pMergedInfo".
+     */
+    for (int i = 0; i < (int) pContents->size(); i++) {
+        if (pContents->itemAt(i).getFileType() == kFileTypeDirectory) {
+            String8 subdir(dirName);
+            subdir.appendPath(pContents->itemAt(i).getFileName());
+
+            fncScanAndMergeDirLocked(pMergedInfo, ap, locale, vendor, subdir.string());
+        }
+    }
+
+    /*
+     * To be consistent, we want entries for the root directory.  If
+     * we're the root, add one now.
+     */
+    if (dirName[0] == '\0') {
+        AssetDir::FileInfo tmpInfo;
+
+        tmpInfo.set(String8(""), kFileTypeDirectory);
+        tmpInfo.setSourceName(createPathNameLocked(ap, locale, vendor));
+        pContents->add(tmpInfo);
+    }
+
+    /*
+     * We want to prepend the extended partial path to every entry in
+     * "pContents".  It's the same value for each entry, so this will
+     * not change the sorting order of the vector contents.
+     */
+    for (int i = 0; i < (int) pContents->size(); i++) {
+        const AssetDir::FileInfo& info = pContents->itemAt(i);
+        pContents->editItemAt(i).setFileName(partialPath.appendPathCopy(info.getFileName()));
+    }
+
+    mergeInfoLocked(pMergedInfo, pContents);
+    return true;
+}
+
+/*
+ * Trash the cache.
+ */
+void AssetManager::purgeFileNameCacheLocked(void)
+{
+    mCacheValid = false;
+    mCache.clear();
+}
+
+/*
+ * ===========================================================================
+ *      AssetManager::SharedZip
+ * ===========================================================================
+ */
+
+
+Mutex AssetManager::SharedZip::gLock;
+DefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen;
+
+AssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen)
+    : mPath(path), mZipFile(NULL), mModWhen(modWhen), mResourceTableAsset(NULL)
+{
+    //LOGI("Creating SharedZip %p %s\n", this, (const char*)mPath);
+    mZipFile = new ZipFileRO;
+    LOGV("+++ opening zip '%s'\n", mPath.string());
+    if (mZipFile->open(mPath.string()) != NO_ERROR) {
+        LOGD("failed to open Zip archive '%s'\n", mPath.string());
+        delete mZipFile;
+        mZipFile = NULL;
+    }
+}
+
+sp<AssetManager::SharedZip> AssetManager::SharedZip::get(const String8& path)
+{
+    AutoMutex _l(gLock);
+    time_t modWhen = getFileModDate(path);
+    sp<SharedZip> zip = gOpen.valueFor(path).promote();
+    if (zip != NULL && zip->mModWhen == modWhen) {
+        return zip;
+    }
+    zip = new SharedZip(path, modWhen);
+    gOpen.add(path, zip);
+    return zip;
+
+}
+
+ZipFileRO* AssetManager::SharedZip::getZip()
+{
+    return mZipFile;
+}
+
+Asset* AssetManager::SharedZip::getResourceTableAsset()
+{
+    LOGV("Getting from SharedZip %p resource asset %p\n", this, mResourceTableAsset);
+    return mResourceTableAsset;
+}
+
+Asset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset)
+{
+    {
+        AutoMutex _l(gLock);
+        if (mResourceTableAsset == NULL) {
+            mResourceTableAsset = asset;
+            // This is not thread safe the first time it is called, so
+            // do it here with the global lock held.
+            asset->getBuffer(true);
+            return asset;
+        }
+    }
+    delete asset;
+    return mResourceTableAsset;
+}
+
+bool AssetManager::SharedZip::isUpToDate()
+{
+    time_t modWhen = getFileModDate(mPath.string());
+    return mModWhen == modWhen;
+}
+
+AssetManager::SharedZip::~SharedZip()
+{
+    //LOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath);
+    if (mResourceTableAsset != NULL) {
+        delete mResourceTableAsset;
+    }
+    if (mZipFile != NULL) {
+        delete mZipFile;
+        LOGV("Closed '%s'\n", mPath.string());
+    }
+}
+
+/*
+ * ===========================================================================
+ *      AssetManager::ZipSet
+ * ===========================================================================
+ */
+
+/*
+ * Constructor.
+ */
+AssetManager::ZipSet::ZipSet(void)
+{
+}
+
+/*
+ * Destructor.  Close any open archives.
+ */
+AssetManager::ZipSet::~ZipSet(void)
+{
+    size_t N = mZipFile.size();
+    for (size_t i = 0; i < N; i++)
+        closeZip(i);
+}
+
+/*
+ * Close a Zip file and reset the entry.
+ */
+void AssetManager::ZipSet::closeZip(int idx)
+{
+    mZipFile.editItemAt(idx) = NULL;
+}
+
+
+/*
+ * Retrieve the appropriate Zip file from the set.
+ */
+ZipFileRO* AssetManager::ZipSet::getZip(const String8& path)
+{
+    int idx = getIndex(path);
+    sp<SharedZip> zip = mZipFile[idx];
+    if (zip == NULL) {
+        zip = SharedZip::get(path);
+        mZipFile.editItemAt(idx) = zip;
+    }
+    return zip->getZip();
+}
+
+Asset* AssetManager::ZipSet::getZipResourceTable(const String8& path)
+{
+    int idx = getIndex(path);
+    sp<SharedZip> zip = mZipFile[idx];
+    if (zip == NULL) {
+        zip = SharedZip::get(path);
+        mZipFile.editItemAt(idx) = zip;
+    }
+    return zip->getResourceTableAsset();
+}
+
+Asset* AssetManager::ZipSet::setZipResourceTable(const String8& path,
+                                                 Asset* asset)
+{
+    int idx = getIndex(path);
+    sp<SharedZip> zip = mZipFile[idx];
+    // doesn't make sense to call before previously accessing.
+    return zip->setResourceTableAsset(asset);
+}
+
+/*
+ * Generate the partial pathname for the specified archive.  The caller
+ * gets to prepend the asset root directory.
+ *
+ * Returns something like "common/en-US-noogle.jar".
+ */
+/*static*/ String8 AssetManager::ZipSet::getPathName(const char* zipPath)
+{
+    return String8(zipPath);
+}
+
+bool AssetManager::ZipSet::isUpToDate()
+{
+    const size_t N = mZipFile.size();
+    for (size_t i=0; i<N; i++) {
+        if (mZipFile[i] != NULL && !mZipFile[i]->isUpToDate()) {
+            return false;
+        }
+    }
+    return true;
+}
+
+/*
+ * Compute the zip file's index.
+ *
+ * "appName", "locale", and "vendor" should be set to NULL to indicate the
+ * default directory.
+ */
+int AssetManager::ZipSet::getIndex(const String8& zip) const
+{
+    const size_t N = mZipPath.size();
+    for (size_t i=0; i<N; i++) {
+        if (mZipPath[i] == zip) {
+            return i;
+        }
+    }
+
+    mZipPath.add(zip);
+    mZipFile.add(NULL);
+
+    return mZipPath.size()-1;
+}
+
diff --git a/libs/utils/Binder.cpp b/libs/utils/Binder.cpp
new file mode 100644
index 0000000..37e4685
--- /dev/null
+++ b/libs/utils/Binder.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2005 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 <utils/Binder.h>
+
+#include <utils/Atomic.h>
+#include <utils/BpBinder.h>
+#include <utils/IInterface.h>
+#include <utils/Parcel.h>
+
+#include <stdio.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor)
+{
+    return NULL;
+}
+
+BBinder* IBinder::localBinder()
+{
+    return NULL;
+}
+
+BpBinder* IBinder::remoteBinder()
+{
+    return NULL;
+}
+
+bool IBinder::checkSubclass(const void* /*subclassID*/) const
+{
+    return false;
+}
+
+// ---------------------------------------------------------------------------
+
+class BBinder::Extras
+{
+public:
+    Mutex mLock;
+    BpBinder::ObjectManager mObjects;
+};
+
+// ---------------------------------------------------------------------------
+
+BBinder::BBinder()
+    : mExtras(NULL)
+{
+}
+
+bool BBinder::isBinderAlive() const
+{
+    return true;
+}
+
+status_t BBinder::pingBinder()
+{
+    return NO_ERROR;
+}
+
+String16 BBinder::getInterfaceDescriptor() const
+{
+    LOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this);
+    return String16();
+}
+
+status_t BBinder::transact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    data.setDataPosition(0);
+
+    status_t err = NO_ERROR;
+    switch (code) {
+        case PING_TRANSACTION:
+            reply->writeInt32(pingBinder());
+            break;
+        default:
+            err = onTransact(code, data, reply, flags);
+            break;
+    }
+
+    if (reply != NULL) {
+        reply->setDataPosition(0);
+    }
+
+    return err;
+}
+
+status_t BBinder::linkToDeath(
+    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
+{
+    return INVALID_OPERATION;
+}
+
+status_t BBinder::unlinkToDeath(
+    const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
+    wp<DeathRecipient>* outRecipient)
+{
+    return INVALID_OPERATION;
+}
+
+status_t BBinder::dump(int fd, const Vector<String16>& args)
+{
+    return NO_ERROR;
+}
+
+void BBinder::attachObject(
+    const void* objectID, void* object, void* cleanupCookie,
+    object_cleanup_func func)
+{
+    Extras* e = mExtras;
+
+    if (!e) {
+        e = new Extras;
+        if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e),
+                reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) {
+            delete e;
+            e = mExtras;
+        }
+        if (e == 0) return; // out of memory
+    }
+
+    AutoMutex _l(e->mLock);
+    e->mObjects.attach(objectID, object, cleanupCookie, func);
+}
+
+void* BBinder::findObject(const void* objectID) const
+{
+    Extras* e = mExtras;
+    if (!e) return NULL;
+
+    AutoMutex _l(e->mLock);
+    return e->mObjects.find(objectID);
+}
+
+void BBinder::detachObject(const void* objectID)
+{
+    Extras* e = mExtras;
+    if (!e) return;
+
+    AutoMutex _l(e->mLock);
+    e->mObjects.detach(objectID);
+}
+
+BBinder* BBinder::localBinder()
+{
+    return this;
+}
+
+BBinder::~BBinder()
+{
+    if (mExtras) delete mExtras;
+}
+
+
+status_t BBinder::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case INTERFACE_TRANSACTION:
+            reply->writeString16(getInterfaceDescriptor());
+            return NO_ERROR;
+
+        case DUMP_TRANSACTION: {
+            int fd = data.readFileDescriptor();
+            int argc = data.readInt32();
+            Vector<String16> args;
+            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
+               args.add(data.readString16());
+            }
+            return dump(fd, args);
+        }
+        default:
+            return UNKNOWN_TRANSACTION;
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+enum {
+    // This is used to transfer ownership of the remote binder from
+    // the BpRefBase object holding it (when it is constructed), to the
+    // owner of the BpRefBase object when it first acquires that BpRefBase.
+    kRemoteAcquired = 0x00000001
+};
+
+BpRefBase::BpRefBase(const sp<IBinder>& o)
+    : mRemote(o.get()), mRefs(NULL), mState(0)
+{
+    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
+
+    if (mRemote) {
+        mRemote->incStrong(this);           // Removed on first IncStrong().
+        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
+    }
+}
+
+BpRefBase::~BpRefBase()
+{
+    if (mRemote) {
+        if (!(mState&kRemoteAcquired)) {
+            mRemote->decStrong(this);
+        }
+        mRefs->decWeak(this);
+    }
+}
+
+void BpRefBase::onFirstRef()
+{
+    android_atomic_or(kRemoteAcquired, &mState);
+}
+
+void BpRefBase::onLastStrongRef(const void* id)
+{
+    if (mRemote) {
+        mRemote->decStrong(this);
+    }
+}
+
+bool BpRefBase::onIncStrongAttempted(uint32_t flags, const void* id)
+{
+    return mRemote ? mRefs->attemptIncStrong(this) : false;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/utils/BpBinder.cpp b/libs/utils/BpBinder.cpp
new file mode 100644
index 0000000..69ab195
--- /dev/null
+++ b/libs/utils/BpBinder.cpp
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2005 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 "BpBinder"
+//#define LOG_NDEBUG 0
+
+#include <utils/BpBinder.h>
+
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+
+#include <stdio.h>
+
+//#undef LOGV
+//#define LOGV(...) fprintf(stderr, __VA_ARGS__)
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+BpBinder::ObjectManager::ObjectManager()
+{
+}
+
+BpBinder::ObjectManager::~ObjectManager()
+{
+    kill();
+}
+
+void BpBinder::ObjectManager::attach(
+    const void* objectID, void* object, void* cleanupCookie,
+    IBinder::object_cleanup_func func)
+{
+    entry_t e;
+    e.object = object;
+    e.cleanupCookie = cleanupCookie;
+    e.func = func;
+
+    if (mObjects.indexOfKey(objectID) >= 0) {
+        LOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
+                objectID, this,  object);
+        return;
+    }
+
+    mObjects.add(objectID, e);
+}
+
+void* BpBinder::ObjectManager::find(const void* objectID) const
+{
+    const ssize_t i = mObjects.indexOfKey(objectID);
+    if (i < 0) return NULL;
+    return mObjects.valueAt(i).object;
+}
+
+void BpBinder::ObjectManager::detach(const void* objectID)
+{
+    mObjects.removeItem(objectID);
+}
+
+void BpBinder::ObjectManager::kill()
+{
+    const size_t N = mObjects.size();
+    LOGV("Killing %d objects in manager %p", N, this);
+    for (size_t i=0; i<N; i++) {
+        const entry_t& e = mObjects.valueAt(i);
+        if (e.func != NULL) {
+            e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
+        }
+    }
+
+    mObjects.clear();
+}
+
+// ---------------------------------------------------------------------------
+
+BpBinder::BpBinder(int32_t handle)
+    : mHandle(handle)
+    , mAlive(1)
+    , mObitsSent(0)
+    , mObituaries(NULL)
+{
+    LOGV("Creating BpBinder %p handle %d\n", this, mHandle);
+
+    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
+    IPCThreadState::self()->incWeakHandle(handle);
+}
+
+String16 BpBinder::getInterfaceDescriptor() const
+{
+    String16 res;
+    Parcel send, reply;
+    status_t err = const_cast<BpBinder*>(this)->transact(
+            INTERFACE_TRANSACTION, send, &reply);
+    if (err == NO_ERROR) {
+        res = reply.readString16();
+    }
+    return res;
+}
+
+bool BpBinder::isBinderAlive() const
+{
+    return mAlive != 0;
+}
+
+status_t BpBinder::pingBinder()
+{
+    Parcel send;
+    Parcel reply;
+    status_t err = transact(PING_TRANSACTION, send, &reply);
+    if (err != NO_ERROR) return err;
+    if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA;
+    return (status_t)reply.readInt32();
+}
+
+status_t BpBinder::dump(int fd, const Vector<String16>& args)
+{
+    Parcel send;
+    Parcel reply;
+    send.writeFileDescriptor(fd);
+    const size_t numArgs = args.size();
+    send.writeInt32(numArgs);
+    for (size_t i = 0; i < numArgs; i++) {
+        send.writeString16(args[i]);
+    }
+    status_t err = transact(DUMP_TRANSACTION, send, &reply);
+    return err;
+}
+
+status_t BpBinder::transact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    // Once a binder has died, it will never come back to life.
+    if (mAlive) {
+        status_t status = IPCThreadState::self()->transact(
+            mHandle, code, data, reply, flags);
+        if (status == DEAD_OBJECT) mAlive = 0;
+        return status;
+    }
+
+    return DEAD_OBJECT;
+}
+
+status_t BpBinder::linkToDeath(
+    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
+{
+    Obituary ob;
+    ob.recipient = recipient;
+    ob.cookie = cookie;
+    ob.flags = flags;
+
+    LOG_ALWAYS_FATAL_IF(recipient == NULL,
+                        "linkToDeath(): recipient must be non-NULL");
+
+    {
+        AutoMutex _l(mLock);
+
+        if (!mObitsSent) {
+            if (!mObituaries) {
+                mObituaries = new Vector<Obituary>;
+                if (!mObituaries) {
+                    return NO_MEMORY;
+                }
+                LOGV("Requesting death notification: %p handle %d\n", this, mHandle);
+                getWeakRefs()->incWeak(this);
+                IPCThreadState* self = IPCThreadState::self();
+                self->requestDeathNotification(mHandle, this);
+                self->flushCommands();
+            }
+            ssize_t res = mObituaries->add(ob);
+            return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
+        }
+    }
+
+    return DEAD_OBJECT;
+}
+
+status_t BpBinder::unlinkToDeath(
+    const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
+    wp<DeathRecipient>* outRecipient)
+{
+    AutoMutex _l(mLock);
+
+    if (mObitsSent) {
+        return DEAD_OBJECT;
+    }
+
+    const size_t N = mObituaries ? mObituaries->size() : 0;
+    for (size_t i=0; i<N; i++) {
+        const Obituary& obit = mObituaries->itemAt(i);
+        if ((obit.recipient == recipient
+                    || (recipient == NULL && obit.cookie == cookie))
+                && obit.flags == flags) {
+            const uint32_t allFlags = obit.flags|flags;
+            if (outRecipient != NULL) {
+                *outRecipient = mObituaries->itemAt(i).recipient;
+            }
+            mObituaries->removeAt(i);
+            if (mObituaries->size() == 0) {
+                LOGV("Clearing death notification: %p handle %d\n", this, mHandle);
+                IPCThreadState* self = IPCThreadState::self();
+                self->clearDeathNotification(mHandle, this);
+                self->flushCommands();
+                delete mObituaries;
+                mObituaries = NULL;
+            }
+            return NO_ERROR;
+        }
+    }
+
+    return NAME_NOT_FOUND;
+}
+
+void BpBinder::sendObituary()
+{
+    LOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
+        this, mHandle, mObitsSent ? "true" : "false");
+
+    mAlive = 0;
+    if (mObitsSent) return;
+
+    mLock.lock();
+    Vector<Obituary>* obits = mObituaries;
+    if(obits != NULL) {
+        LOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
+        IPCThreadState* self = IPCThreadState::self();
+        self->clearDeathNotification(mHandle, this);
+        self->flushCommands();
+        mObituaries = NULL;
+    }
+    mObitsSent = 1;
+    mLock.unlock();
+
+    LOGV("Reporting death of proxy %p for %d recipients\n",
+        this, obits ? obits->size() : 0);
+
+    if (obits != NULL) {
+        const size_t N = obits->size();
+        for (size_t i=0; i<N; i++) {
+            reportOneDeath(obits->itemAt(i));
+        }
+
+        delete obits;
+    }
+}
+
+void BpBinder::reportOneDeath(const Obituary& obit)
+{
+    sp<DeathRecipient> recipient = obit.recipient.promote();
+    LOGV("Reporting death to recipient: %p\n", recipient.get());
+    if (recipient == NULL) return;
+
+    recipient->binderDied(this);
+}
+
+
+void BpBinder::attachObject(
+    const void* objectID, void* object, void* cleanupCookie,
+    object_cleanup_func func)
+{
+    AutoMutex _l(mLock);
+    LOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
+    mObjects.attach(objectID, object, cleanupCookie, func);
+}
+
+void* BpBinder::findObject(const void* objectID) const
+{
+    AutoMutex _l(mLock);
+    return mObjects.find(objectID);
+}
+
+void BpBinder::detachObject(const void* objectID)
+{
+    AutoMutex _l(mLock);
+    mObjects.detach(objectID);
+}
+
+BpBinder* BpBinder::remoteBinder()
+{
+    return this;
+}
+
+BpBinder::~BpBinder()
+{
+    LOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
+
+    IPCThreadState* ipc = IPCThreadState::self();
+
+    mLock.lock();
+    Vector<Obituary>* obits = mObituaries;
+    if(obits != NULL) {
+        if (ipc) ipc->clearDeathNotification(mHandle, this);
+        mObituaries = NULL;
+    }
+    mLock.unlock();
+
+    if (obits != NULL) {
+        // XXX Should we tell any remaining DeathRecipient
+        // objects that the last strong ref has gone away, so they
+        // are no longer linked?
+        delete obits;
+    }
+
+    if (ipc) {
+        ipc->expungeHandle(mHandle, this);
+        ipc->decWeakHandle(mHandle);
+    }
+}
+
+void BpBinder::onFirstRef()
+{
+    LOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
+    IPCThreadState* ipc = IPCThreadState::self();
+    if (ipc) ipc->incStrongHandle(mHandle);
+}
+
+void BpBinder::onLastStrongRef(const void* id)
+{
+    LOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
+    IF_LOGV() {
+        printRefs();
+    }
+    IPCThreadState* ipc = IPCThreadState::self();
+    if (ipc) ipc->decStrongHandle(mHandle);
+}
+
+bool BpBinder::onIncStrongAttempted(uint32_t flags, const void* id)
+{
+    LOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
+    IPCThreadState* ipc = IPCThreadState::self();
+    return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/utils/BufferedTextOutput.cpp b/libs/utils/BufferedTextOutput.cpp
new file mode 100644
index 0000000..989662e
--- /dev/null
+++ b/libs/utils/BufferedTextOutput.cpp
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#include <utils/BufferedTextOutput.h>
+
+#include <utils/Atomic.h>
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <cutils/threads.h>
+
+#include <private/utils/Static.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+struct BufferedTextOutput::BufferState : public RefBase
+{
+    BufferState(int32_t _seq)
+        : seq(_seq)
+        , buffer(NULL)
+        , bufferPos(0)
+        , bufferSize(0)
+        , atFront(true)
+        , indent(0)
+        , bundle(0) {
+    }
+    ~BufferState() {
+        free(buffer);
+    }
+    
+    status_t append(const char* txt, size_t len) {
+        if ((len+bufferPos) > bufferSize) {
+            void* b = realloc(buffer, ((len+bufferPos)*3)/2);
+            if (!b) return NO_MEMORY;
+            buffer = (char*)b;
+        }
+        memcpy(buffer+bufferPos, txt, len);
+        bufferPos += len;
+        return NO_ERROR;
+    }
+    
+    void restart() {
+        bufferPos = 0;
+        atFront = true;
+        if (bufferSize > 256) {
+            void* b = realloc(buffer, 256);
+            if (b) {
+                buffer = (char*)b;
+                bufferSize = 256;
+            }
+        }
+    }
+    
+    const int32_t seq;
+    char* buffer;
+    size_t bufferPos;
+    size_t bufferSize;
+    bool atFront;
+    int32_t indent;
+    int32_t bundle;
+};
+
+struct BufferedTextOutput::ThreadState
+{
+    Vector<sp<BufferedTextOutput::BufferState> > states;
+};
+
+static mutex_t          gMutex;
+
+static thread_store_t   tls;
+
+BufferedTextOutput::ThreadState* BufferedTextOutput::getThreadState()
+{
+    ThreadState*  ts = (ThreadState*) thread_store_get( &tls );
+    if (ts) return ts;
+    ts = new ThreadState;
+    thread_store_set( &tls, ts, threadDestructor );
+    return ts;
+}
+
+void BufferedTextOutput::threadDestructor(void *st)
+{
+    delete ((ThreadState*)st);
+}
+
+static volatile int32_t gSequence = 0;
+
+static volatile int32_t gFreeBufferIndex = -1;
+
+static int32_t allocBufferIndex()
+{
+    int32_t res = -1;
+    
+    mutex_lock(&gMutex);
+    
+    if (gFreeBufferIndex >= 0) {
+        res = gFreeBufferIndex;
+        gFreeBufferIndex = gTextBuffers[res];
+        gTextBuffers.editItemAt(res) = -1;
+
+    } else {
+        res = gTextBuffers.size();
+        gTextBuffers.add(-1);
+    }
+
+    mutex_unlock(&gMutex);
+    
+    return res;
+}
+
+static void freeBufferIndex(int32_t idx)
+{
+    mutex_lock(&gMutex);
+    gTextBuffers.editItemAt(idx) = gFreeBufferIndex;
+    gFreeBufferIndex = idx;
+    mutex_unlock(&gMutex);
+}
+
+// ---------------------------------------------------------------------------
+
+BufferedTextOutput::BufferedTextOutput(uint32_t flags)
+    : mFlags(flags)
+    , mSeq(android_atomic_inc(&gSequence))
+    , mIndex(allocBufferIndex())
+{
+    mGlobalState = new BufferState(mSeq);
+    if (mGlobalState) mGlobalState->incStrong(this);
+}
+    
+BufferedTextOutput::~BufferedTextOutput()
+{
+    if (mGlobalState) mGlobalState->decStrong(this);
+    freeBufferIndex(mIndex);
+}
+
+status_t BufferedTextOutput::print(const char* txt, size_t len)
+{
+    //printf("BufferedTextOutput: printing %d\n", len);
+    
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    
+    const char* const end = txt+len;
+    
+    status_t err;
+
+    while (txt < end) {
+        // Find the next line.
+        const char* first = txt;
+        while (txt < end && *txt != '\n') txt++;
+        
+        // Include this and all following empty lines.
+        while (txt < end && *txt == '\n') txt++;
+        
+        // Special cases for first data on a line.
+        if (b->atFront) {
+            if (b->indent > 0) {
+                // If this is the start of a line, add the indent.
+                const char* prefix = stringForIndent(b->indent);
+                err = b->append(prefix, strlen(prefix));
+                if (err != NO_ERROR) return err;
+                
+            } else if (*(txt-1) == '\n' && !b->bundle) {
+                // Fast path: if we are not indenting or bundling, and
+                // have been given one or more complete lines, just write
+                // them out without going through the buffer.
+                
+                // Slurp up all of the lines.
+                const char* lastLine = txt+1;
+                while (txt < end) {
+                    if (*txt++ == '\n') lastLine = txt;
+                }
+                struct iovec vec;
+                vec.iov_base = (void*)first;
+                vec.iov_len = lastLine-first;
+                //printf("Writing %d bytes of data!\n", vec.iov_len);
+                writeLines(vec, 1);
+                txt = lastLine;
+                continue;
+            }
+        }
+        
+        // Append the new text to the buffer.
+        err = b->append(first, txt-first);
+        if (err != NO_ERROR) return err;
+        b->atFront = *(txt-1) == '\n';
+        
+        // If we have finished a line and are not bundling, write
+        // it out.
+        //printf("Buffer is now %d bytes\n", b->bufferPos);
+        if (b->atFront && !b->bundle) {
+            struct iovec vec;
+            vec.iov_base = b->buffer;
+            vec.iov_len = b->bufferPos;
+            //printf("Writing %d bytes of data!\n", vec.iov_len);
+            writeLines(vec, 1);
+            b->restart();
+        }
+    }
+    
+    return NO_ERROR;
+}
+
+void BufferedTextOutput::moveIndent(int delta)
+{
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    b->indent += delta;
+    if (b->indent < 0) b->indent = 0;
+}
+
+void BufferedTextOutput::pushBundle()
+{
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    b->bundle++;
+}
+
+void BufferedTextOutput::popBundle()
+{
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    b->bundle--;
+    LOG_FATAL_IF(b->bundle < 0,
+        "TextOutput::popBundle() called more times than pushBundle()");
+    if (b->bundle < 0) b->bundle = 0;
+    
+    if (b->bundle == 0) {
+        // Last bundle, write out data if it is complete.  If it is not
+        // complete, don't write until the last line is done... this may
+        // or may not be the write thing to do, but it's the easiest.
+        if (b->bufferPos > 0 && b->atFront) {
+            struct iovec vec;
+            vec.iov_base = b->buffer;
+            vec.iov_len = b->bufferPos;
+            writeLines(vec, 1);
+            b->restart();
+        }
+    }
+}
+
+BufferedTextOutput::BufferState* BufferedTextOutput::getBuffer() const
+{
+    if ((mFlags&MULTITHREADED) != 0) {
+        ThreadState* ts = getThreadState();
+        if (ts) {
+            while (ts->states.size() <= (size_t)mIndex) ts->states.add(NULL);
+            BufferState* bs = ts->states[mIndex].get();
+            if (bs != NULL && bs->seq == mSeq) return bs;
+            
+            ts->states.editItemAt(mIndex) = new BufferState(mIndex);
+            bs = ts->states[mIndex].get();
+            if (bs != NULL) return bs;
+        }
+    }
+    
+    return mGlobalState;
+}
+
+}; // namespace android
diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp
new file mode 100644
index 0000000..26fb22a
--- /dev/null
+++ b/libs/utils/CallStack.cpp
@@ -0,0 +1,335 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "CallStack"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#if HAVE_DLADDR
+#include <dlfcn.h>
+#endif
+
+#if HAVE_CXXABI
+#include <cxxabi.h>
+#endif
+
+#include <unwind.h>
+
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/CallStack.h>
+#include <utils/threads.h>
+
+
+/*****************************************************************************/
+namespace android {
+
+
+typedef struct {
+    size_t count;
+    size_t ignore;
+    const void** addrs;
+} stack_crawl_state_t;
+
+static
+_Unwind_Reason_Code trace_function(_Unwind_Context *context, void *arg)
+{
+    stack_crawl_state_t* state = (stack_crawl_state_t*)arg;
+    if (state->count) {
+        void* ip = (void*)_Unwind_GetIP(context);
+        if (ip) {
+            if (state->ignore) {
+                state->ignore--;
+            } else {
+                state->addrs[0] = ip; 
+                state->addrs++;
+                state->count--;
+            }
+        }
+    }
+    return _URC_NO_REASON;
+}
+
+static
+int backtrace(const void** addrs, size_t ignore, size_t size)
+{
+    stack_crawl_state_t state;
+    state.count = size;
+    state.ignore = ignore;
+    state.addrs = addrs;
+    _Unwind_Backtrace(trace_function, (void*)&state);
+    return size - state.count;
+}
+
+/*****************************************************************************/
+
+static 
+const char *lookup_symbol(const void* addr, void **offset, char* name, size_t bufSize)
+{
+#if HAVE_DLADDR
+    Dl_info info;
+    if (dladdr(addr, &info)) {
+        *offset = info.dli_saddr;
+        return info.dli_sname;
+    }
+#endif
+    return NULL;
+}
+
+static 
+int32_t linux_gcc_demangler(const char *mangled_name, char *unmangled_name, size_t buffersize)
+{
+    size_t out_len = 0;
+#if HAVE_CXXABI
+    int status = 0;
+    char *demangled = abi::__cxa_demangle(mangled_name, 0, &out_len, &status);
+    if (status == 0) {
+        // OK
+        if (out_len < buffersize) memcpy(unmangled_name, demangled, out_len);
+        else out_len = 0;
+        free(demangled);
+    } else {
+        out_len = 0;
+    }
+#endif
+    return out_len;
+}
+
+/*****************************************************************************/
+
+class MapInfo {
+    struct mapinfo {
+        struct mapinfo *next;
+        uint64_t start;
+        uint64_t end;
+        char name[];
+    };
+
+    const char *map_to_name(uint64_t pc, const char* def) {
+        mapinfo* mi = getMapInfoList();
+        while(mi) {
+            if ((pc >= mi->start) && (pc < mi->end))
+                return mi->name;
+            mi = mi->next;
+        }
+        return def;
+    }
+
+    mapinfo *parse_maps_line(char *line) {
+        mapinfo *mi;
+        int len = strlen(line);
+        if (len < 1) return 0;
+        line[--len] = 0;
+        if (len < 50) return 0;
+        if (line[20] != 'x') return 0;
+        mi = (mapinfo*)malloc(sizeof(mapinfo) + (len - 47));
+        if (mi == 0) return 0;
+        mi->start = strtoull(line, 0, 16);
+        mi->end = strtoull(line + 9, 0, 16);
+        mi->next = 0;
+        strcpy(mi->name, line + 49);
+        return mi;
+    }
+
+    mapinfo* getMapInfoList() {
+        Mutex::Autolock _l(mLock);
+        if (milist == 0) {
+            char data[1024];
+            FILE *fp;
+            sprintf(data, "/proc/%d/maps", getpid());
+            fp = fopen(data, "r");
+            if (fp) {
+                while(fgets(data, 1024, fp)) {
+                    mapinfo *mi = parse_maps_line(data);
+                    if(mi) {
+                        mi->next = milist;
+                        milist = mi;
+                    }
+                }
+                fclose(fp);
+            }
+        }
+        return milist;
+    }
+    mapinfo*    milist;
+    Mutex       mLock;
+    static MapInfo sMapInfo;
+
+public:
+    MapInfo()
+     : milist(0) {
+    }
+
+    ~MapInfo() {
+        while (milist) {
+            mapinfo *next = milist->next;
+            free(milist);
+            milist = next;
+        }
+    }
+    
+    static const char *mapAddressToName(const void* pc, const char* def) {
+        return sMapInfo.map_to_name((uint64_t)pc, def);
+    }
+
+};
+
+/*****************************************************************************/
+
+MapInfo MapInfo::sMapInfo;
+
+/*****************************************************************************/
+
+CallStack::CallStack()
+    : mCount(0)
+{
+}
+
+CallStack::CallStack(const CallStack& rhs)
+    : mCount(rhs.mCount)
+{
+    if (mCount) {
+        memcpy(mStack, rhs.mStack, mCount*sizeof(void*));
+    }
+}
+
+CallStack::~CallStack()
+{
+}
+
+CallStack& CallStack::operator = (const CallStack& rhs)
+{
+    mCount = rhs.mCount;
+    if (mCount) {
+        memcpy(mStack, rhs.mStack, mCount*sizeof(void*));
+    }
+    return *this;
+}
+
+bool CallStack::operator == (const CallStack& rhs) const {
+    if (mCount != rhs.mCount)
+        return false;
+    return !mCount || (memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) == 0);
+}
+
+bool CallStack::operator != (const CallStack& rhs) const {
+    return !operator == (rhs);
+}
+
+bool CallStack::operator < (const CallStack& rhs) const {
+    if (mCount != rhs.mCount)
+        return mCount < rhs.mCount;
+    return memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) < 0;
+}
+
+bool CallStack::operator >= (const CallStack& rhs) const {
+    return !operator < (rhs);
+}
+
+bool CallStack::operator > (const CallStack& rhs) const {
+    if (mCount != rhs.mCount)
+        return mCount > rhs.mCount;
+    return memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) > 0;
+}
+
+bool CallStack::operator <= (const CallStack& rhs) const {
+    return !operator > (rhs);
+}
+
+const void* CallStack::operator [] (int index) const {
+    if (index >= int(mCount))
+        return 0;
+    return mStack[index];
+}
+
+
+void CallStack::clear()
+{
+    mCount = 0;
+}
+
+void CallStack::update(int32_t ignoreDepth, int32_t maxDepth)
+{
+    if (maxDepth > MAX_DEPTH)
+        maxDepth = MAX_DEPTH;
+    mCount = backtrace(mStack, ignoreDepth, maxDepth);
+}
+
+// Return the stack frame name on the designated level
+String8 CallStack::toStringSingleLevel(const char* prefix, int32_t level) const
+{
+    String8 res;
+    char namebuf[1024];
+    char tmp[256];
+    char tmp1[32];
+    char tmp2[32];
+    void *offs;
+
+    const void* ip = mStack[level];
+    if (!ip) return res;
+
+    if (prefix) res.append(prefix);
+    snprintf(tmp1, 32, "#%02d  ", level);
+    res.append(tmp1);
+
+    const char* name = lookup_symbol(ip, &offs, namebuf, sizeof(namebuf));
+    if (name) {
+        if (linux_gcc_demangler(name, tmp, 256) != 0)
+            name = tmp;
+        snprintf(tmp1, 32, "0x%p: <", ip);
+        snprintf(tmp2, 32, ">+0x%p", offs);
+        res.append(tmp1);
+        res.append(name);
+        res.append(tmp2);
+    } else { 
+        name = MapInfo::mapAddressToName(ip, "<unknown>");
+        snprintf(tmp, 256, "pc %p  %s", ip, name);
+        res.append(tmp);
+    }
+    res.append("\n");
+
+    return res;
+}
+
+// Dump a stack trace to the log
+void CallStack::dump(const char* prefix) const
+{
+    /* 
+     * Sending a single long log may be truncated since the stack levels can
+     * get very deep. So we request function names of each frame individually.
+     */
+    for (int i=0; i<int(mCount); i++) {
+        LOGD("%s", toStringSingleLevel(prefix, i).string());
+    }
+}
+
+// Return a string (possibly very long) containing the complete stack trace
+String8 CallStack::toString(const char* prefix) const
+{
+    String8 res;
+
+    for (int i=0; i<int(mCount); i++) {
+        res.append(toStringSingleLevel(prefix, i).string());
+    }
+
+    return res;
+}
+
+/*****************************************************************************/
+
+}; // namespace android
diff --git a/libs/utils/Debug.cpp b/libs/utils/Debug.cpp
new file mode 100644
index 0000000..f7988ec
--- /dev/null
+++ b/libs/utils/Debug.cpp
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2005 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 <utils/Debug.h>
+
+#include <utils/misc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------
+
+static const char indentStr[] =
+"                                                                            "
+"                                                                            ";
+
+const char* stringForIndent(int32_t indentLevel)
+{
+    ssize_t off = sizeof(indentStr)-1-(indentLevel*2);
+    return indentStr + (off < 0 ? 0 : off);
+}
+
+// ---------------------------------------------------------------------
+
+static void defaultPrintFunc(void* cookie, const char* txt)
+{
+    printf("%s", txt);
+}
+
+// ---------------------------------------------------------------------
+
+static inline int isident(int c)
+{
+    return isalnum(c) || c == '_';
+}
+
+static inline bool isasciitype(char c)
+{
+    if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true;
+    return false;
+}
+
+static inline char makehexdigit(uint32_t val)
+{
+    return "0123456789abcdef"[val&0xF];
+}
+
+static char* appendhexnum(uint32_t val, char* out)
+{
+    for( int32_t i=28; i>=0; i-=4 ) {
+        *out++ = makehexdigit( val>>i );
+    }
+    *out = 0;
+    return out;
+}
+
+static inline char makeupperhexdigit(uint32_t val)
+{
+    return "0123456789ABCDEF"[val&0xF];
+}
+
+static char* appendupperhexnum(uint32_t val, char* out)
+{
+    for( int32_t i=28; i>=0; i-=4 ) {
+        *out++ = makeupperhexdigit( val>>i );
+    }
+    *out = 0;
+    return out;
+}
+
+static char* appendcharornum(char c, char* out, bool skipzero = true)
+{
+    if (skipzero && c == 0) return out;
+
+    if (isasciitype(c)) {
+        *out++ = c;
+        return out;
+    }
+
+    *out++ = '\\';
+    *out++ = 'x';
+    *out++ = makehexdigit(c>>4);
+    *out++ = makehexdigit(c);
+    return out;
+}
+
+static char* typetostring(uint32_t type, char* out,
+                          bool fullContext = true,
+                          bool strict = false)
+{
+    char* pos = out;
+    char c[4];
+    c[0] = (char)((type>>24)&0xFF);
+    c[1] = (char)((type>>16)&0xFF);
+    c[2] = (char)((type>>8)&0xFF);
+    c[3] = (char)(type&0xFF);
+    bool valid;
+    if( !strict ) {
+        // now even less strict!
+        // valid = isasciitype(c[3]);
+        valid = true;
+        int32_t i = 0;
+        bool zero = true;
+        while (valid && i<3) {
+            if (c[i] == 0) {
+                if (!zero) valid = false;
+            } else {
+                zero = false;
+                //if (!isasciitype(c[i])) valid = false;
+            }
+            i++;
+        }
+        // if all zeros, not a valid type code.
+        if (zero) valid = false;
+    } else {
+        valid = isident(c[3]) ? true : false;
+        int32_t i = 0;
+        bool zero = true;
+        while (valid && i<3) {
+            if (c[i] == 0) {
+                if (!zero) valid = false;
+            } else {
+                zero = false;
+                if (!isident(c[i])) valid = false;
+            }
+            i++;
+        }
+    }
+    if( valid && (!fullContext || c[0] != '0' || c[1] != 'x') ) {
+        if( fullContext ) *pos++ = '\'';
+        pos = appendcharornum(c[0], pos);
+        pos = appendcharornum(c[1], pos);
+        pos = appendcharornum(c[2], pos);
+        pos = appendcharornum(c[3], pos);
+        if( fullContext ) *pos++ = '\'';
+        *pos = 0;
+        return pos;
+    }
+    
+    if( fullContext ) {
+        *pos++ = '0';
+        *pos++ = 'x';
+    }
+    return appendhexnum(type, pos);
+}
+
+void printTypeCode(uint32_t typeCode, debugPrintFunc func, void* cookie)
+{
+    char buffer[32];
+    char* end = typetostring(typeCode, buffer);
+    *end = 0;
+    func ? (*func)(cookie, buffer) : defaultPrintFunc(cookie, buffer);
+}
+
+void printHexData(int32_t indent, const void *buf, size_t length,
+    size_t bytesPerLine, int32_t singleLineBytesCutoff,
+    size_t alignment, bool cStyle,
+    debugPrintFunc func, void* cookie)
+{
+    if (alignment == 0) {
+        if (bytesPerLine >= 16) alignment = 4;
+        else if (bytesPerLine >= 8) alignment = 2;
+        else alignment = 1;
+    }
+    if (func == NULL) func = defaultPrintFunc;
+
+    size_t offset;
+    
+    unsigned char *pos = (unsigned char *)buf;
+    
+    if (pos == NULL) {
+        if (singleLineBytesCutoff < 0) func(cookie, "\n");
+        func(cookie, "(NULL)");
+        return;
+    }
+    
+    if (length == 0) {
+        if (singleLineBytesCutoff < 0) func(cookie, "\n");
+        func(cookie, "(empty)");
+        return;
+    }
+    
+    if ((int32_t)length < 0) {
+        if (singleLineBytesCutoff < 0) func(cookie, "\n");
+        char buf[64];
+        sprintf(buf, "(bad length: %d)", length);
+        func(cookie, buf);
+        return;
+    }
+    
+    char buffer[256];
+    static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
+    
+    if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
+    
+    const bool oneLine = (int32_t)length <= singleLineBytesCutoff;
+    bool newLine = false;
+    if (cStyle) {
+        indent++;
+        func(cookie, "{\n");
+        newLine = true;
+    } else if (!oneLine) {
+        func(cookie, "\n");
+        newLine = true;
+    }
+    
+    for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
+        long remain = length;
+
+        char* c = buffer;
+        if (!oneLine && !cStyle) {
+            sprintf(c, "0x%08x: ", (int)offset);
+            c += 12;
+        }
+
+        size_t index;
+        size_t word;
+        
+        for (word = 0; word < bytesPerLine; ) {
+
+#ifdef HAVE_LITTLE_ENDIAN
+            const size_t startIndex = word+(alignment-(alignment?1:0));
+            const ssize_t dir = -1;
+#else
+            const size_t startIndex = word;
+            const ssize_t dir = 1;
+#endif
+
+            for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
+            
+                if (!cStyle) {
+                    if (index == 0 && word > 0 && alignment > 0) {
+                        *c++ = ' ';
+                    }
+                
+                    if (remain-- > 0) {
+                        const unsigned char val = *(pos+startIndex+(index*dir));
+                        *c++ = makehexdigit(val>>4);
+                        *c++ = makehexdigit(val);
+                    } else if (!oneLine) {
+                        *c++ = ' ';
+                        *c++ = ' ';
+                    }
+                } else {
+                    if (remain > 0) {
+                        if (index == 0 && word > 0) {
+                            *c++ = ',';
+                            *c++ = ' ';
+                        }
+                        if (index == 0) {
+                            *c++ = '0';
+                            *c++ = 'x';
+                        }
+                        const unsigned char val = *(pos+startIndex+(index*dir));
+                        *c++ = makehexdigit(val>>4);
+                        *c++ = makehexdigit(val);
+                        remain--;
+                    }
+                }
+            }
+            
+            word += index;
+        }
+
+        if (!cStyle) {
+            remain = length;
+            *c++ = ' ';
+            *c++ = '\'';
+            for (index = 0; index < bytesPerLine; index++) {
+
+                if (remain-- > 0) {
+                    const unsigned char val = pos[index];
+                    *c++ = (val >= ' ' && val < 127) ? val : '.';
+                } else if (!oneLine) {
+                    *c++ = ' ';
+                }
+            }
+            
+            *c++ = '\'';
+            if (length > bytesPerLine) *c++ = '\n';
+        } else {
+            if (remain > 0) *c++ = ',';
+            *c++ = '\n';
+        }
+
+        if (newLine && indent) func(cookie, stringForIndent(indent));
+        *c = 0;
+        func(cookie, buffer);
+        newLine = true;
+        
+        if (length <= bytesPerLine) break;
+        length -= bytesPerLine;
+    }
+
+    if (cStyle) {
+        if (indent > 0) func(cookie, stringForIndent(indent-1));
+        func(cookie, "};");
+    }
+}
+
+}; // namespace android
+
diff --git a/libs/utils/FileMap.cpp b/libs/utils/FileMap.cpp
new file mode 100644
index 0000000..e1ba9b2
--- /dev/null
+++ b/libs/utils/FileMap.cpp
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 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.
+ */
+
+//
+// Shared file mapping class.
+//
+
+#define LOG_TAG "filemap"
+
+#include <utils/FileMap.h>
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_POSIX_FILEMAP
+#include <sys/mman.h>
+#endif
+
+#include <string.h>
+#include <memory.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+/*static*/ long FileMap::mPageSize = -1;
+
+
+/*
+ * Constructor.  Create an empty object.
+ */
+FileMap::FileMap(void)
+    : mRefCount(1), mFileName(NULL), mBasePtr(NULL), mBaseLength(0),
+      mDataPtr(NULL), mDataLength(0)
+{
+}
+
+/*
+ * Destructor.
+ */
+FileMap::~FileMap(void)
+{
+    assert(mRefCount == 0);
+
+    //printf("+++ removing FileMap %p %u\n", mDataPtr, mDataLength);
+
+    mRefCount = -100;       // help catch double-free
+    if (mFileName != NULL) {
+        free(mFileName);
+    }
+#ifdef HAVE_POSIX_FILEMAP    
+    if (munmap(mBasePtr, mBaseLength) != 0) {
+        LOGD("munmap(%p, %d) failed\n", mBasePtr, (int) mBaseLength);
+    }
+#endif
+#ifdef HAVE_WIN32_FILEMAP
+    if ( UnmapViewOfFile(mBasePtr) == 0) {
+        LOGD("UnmapViewOfFile(%p) failed, error = %ld\n", mBasePtr, 
+              GetLastError() );
+    }
+    CloseHandle(mFileMapping);
+    CloseHandle(mFileHandle);
+#endif
+}
+
+
+/*
+ * Create a new mapping on an open file.
+ *
+ * Closing the file descriptor does not unmap the pages, so we don't
+ * claim ownership of the fd.
+ *
+ * Returns "false" on failure.
+ */
+bool FileMap::create(const char* origFileName, int fd, off_t offset, size_t length, bool readOnly)
+{
+#ifdef HAVE_WIN32_FILEMAP
+    int     adjust;
+    off_t   adjOffset;
+    size_t  adjLength;
+
+    if (mPageSize == -1) {
+        SYSTEM_INFO  si;
+        
+        GetSystemInfo( &si );
+        mPageSize = si.dwAllocationGranularity;
+    }
+
+    DWORD  protect = readOnly ? PAGE_READONLY : PAGE_READWRITE;
+    
+    mFileHandle  = (HANDLE) _get_osfhandle(fd);
+    mFileMapping = CreateFileMapping( mFileHandle, NULL, protect, 0, 0, NULL);
+    if (mFileMapping == NULL) {
+        LOGE("CreateFileMapping(%p, %lx) failed with error %ld\n",
+              mFileHandle, protect, GetLastError() );
+        return false;
+    }
+    
+    adjust    = offset % mPageSize;
+    adjOffset = offset - adjust;
+    adjLength = length + adjust;
+    
+    mBasePtr = MapViewOfFile( mFileMapping, 
+                              readOnly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS,
+                              0,
+                              (DWORD)(adjOffset),
+                              adjLength );
+    if (mBasePtr == NULL) {
+        LOGE("MapViewOfFile(%ld, %ld) failed with error %ld\n",
+              adjOffset, adjLength, GetLastError() );
+        CloseHandle(mFileMapping);
+        mFileMapping = INVALID_HANDLE_VALUE;
+        return false;
+    }
+#endif
+#ifdef HAVE_POSIX_FILEMAP
+    int     prot, flags, adjust;
+    off_t   adjOffset;
+    size_t  adjLength;
+
+    void* ptr;
+
+    assert(mRefCount == 1);
+    assert(fd >= 0);
+    assert(offset >= 0);
+    assert(length > 0);
+
+    /* init on first use */
+    if (mPageSize == -1) {
+#if NOT_USING_KLIBC
+        mPageSize = sysconf(_SC_PAGESIZE);
+        if (mPageSize == -1) {
+            LOGE("could not get _SC_PAGESIZE\n");
+            return false;
+        }
+#else
+        /* this holds for Linux, Darwin, Cygwin, and doesn't pain the ARM */
+        mPageSize = 4096;
+#endif
+    }
+
+    adjust   = offset % mPageSize;
+try_again:
+    adjOffset = offset - adjust;
+    adjLength = length + adjust;
+
+    flags = MAP_SHARED;
+    prot = PROT_READ;
+    if (!readOnly)
+        prot |= PROT_WRITE;
+
+    ptr = mmap(NULL, adjLength, prot, flags, fd, adjOffset);
+    if (ptr == MAP_FAILED) {
+    	// Cygwin does not seem to like file mapping files from an offset.
+    	// So if we fail, try again with offset zero
+    	if (adjOffset > 0) {
+    		adjust = offset;
+    		goto try_again;
+    	}
+    
+        LOGE("mmap(%ld,%ld) failed: %s\n",
+            (long) adjOffset, (long) adjLength, strerror(errno));
+        return false;
+    }
+    mBasePtr = ptr;
+#endif /* HAVE_POSIX_FILEMAP */
+
+    mFileName = origFileName != NULL ? strdup(origFileName) : NULL;
+    mBaseLength = adjLength;
+    mDataOffset = offset;
+    mDataPtr = (char*) mBasePtr + adjust;
+    mDataLength = length;
+
+    assert(mBasePtr != NULL);
+
+    LOGV("MAP: base %p/%d data %p/%d\n",
+        mBasePtr, (int) mBaseLength, mDataPtr, (int) mDataLength);
+
+    return true;
+}
+
+/*
+ * Provide guidance to the system.
+ */
+int FileMap::advise(MapAdvice advice)
+{
+#if HAVE_MADVISE
+    int cc, sysAdvice;
+
+    switch (advice) {
+        case NORMAL:        sysAdvice = MADV_NORMAL;        break;
+        case RANDOM:        sysAdvice = MADV_RANDOM;        break;
+        case SEQUENTIAL:    sysAdvice = MADV_SEQUENTIAL;    break;
+        case WILLNEED:      sysAdvice = MADV_WILLNEED;      break;
+        case DONTNEED:      sysAdvice = MADV_DONTNEED;      break;
+        default:
+                            assert(false);
+                            return -1;
+    }
+
+    cc = madvise(mBasePtr, mBaseLength, sysAdvice);
+    if (cc != 0)
+        LOGW("madvise(%d) failed: %s\n", sysAdvice, strerror(errno));
+    return cc;
+#else
+	return -1;
+#endif // HAVE_MADVISE
+}
diff --git a/libs/utils/IDataConnection.cpp b/libs/utils/IDataConnection.cpp
new file mode 100644
index 0000000..c6d49aa
--- /dev/null
+++ b/libs/utils/IDataConnection.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Parcel.h>
+
+#include <utils/IDataConnection.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+enum
+{
+    CONNECT_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
+    DISCONNECT_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1
+};
+
+class BpDataConnection : public BpInterface<IDataConnection>
+{
+public:
+    BpDataConnection::BpDataConnection(const sp<IBinder>& impl)
+        : BpInterface<IDataConnection>(impl)
+    {
+    }
+
+	virtual void connect()
+	{
+		Parcel data, reply;
+        data.writeInterfaceToken(IDataConnection::descriptor());
+		remote()->transact(CONNECT_TRANSACTION, data, &reply);
+	}
+	
+	virtual void disconnect()
+	{
+		Parcel data, reply;
+		remote()->transact(DISCONNECT_TRANSACTION, data, &reply);
+	}
+};
+
+IMPLEMENT_META_INTERFACE(DataConnection, "android.utils.IDataConnection");
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnDataConnection::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code)
+    {
+		case CONNECT_TRANSACTION:
+		{                   
+            CHECK_INTERFACE(IDataConnection, data, reply);
+			connect();
+			return NO_ERROR;
+		}    
+		
+		case DISCONNECT_TRANSACTION:
+		{                   
+            CHECK_INTERFACE(IDataConnection, data, reply);
+			disconnect();
+			return NO_ERROR;
+		}
+       
+		default:
+			return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/utils/IInterface.cpp b/libs/utils/IInterface.cpp
new file mode 100644
index 0000000..6ea8178
--- /dev/null
+++ b/libs/utils/IInterface.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2005 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 <utils/IInterface.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+sp<IBinder> IInterface::asBinder()
+{
+    return this ? onAsBinder() : NULL;
+}
+
+sp<const IBinder> IInterface::asBinder() const
+{
+    return this ? const_cast<IInterface*>(this)->onAsBinder() : NULL;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/utils/IMemory.cpp b/libs/utils/IMemory.cpp
new file mode 100644
index 0000000..429bc2b
--- /dev/null
+++ b/libs/utils/IMemory.cpp
@@ -0,0 +1,486 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "IMemory"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <utils/IMemory.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/Atomic.h>
+#include <utils/Parcel.h>
+#include <utils/CallStack.h>
+
+#define VERBOSE   0
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class HeapCache : public IBinder::DeathRecipient
+{
+public:
+    HeapCache();
+    virtual ~HeapCache();
+    
+    virtual void binderDied(const wp<IBinder>& who);
+
+    sp<IMemoryHeap> find_heap(const sp<IBinder>& binder); 
+    void pin_heap(const sp<IBinder>& binder); 
+    void free_heap(const sp<IBinder>& binder); 
+    sp<IMemoryHeap> get_heap(const sp<IBinder>& binder);
+    void dump_heaps();
+
+private:
+    // For IMemory.cpp
+    struct heap_info_t {
+        sp<IMemoryHeap> heap;
+        int32_t         count;
+    };
+
+    void free_heap(const wp<IBinder>& binder); 
+
+    Mutex mHeapCacheLock;
+    KeyedVector< wp<IBinder>, heap_info_t > mHeapCache;
+};
+
+static sp<HeapCache> gHeapCache = new HeapCache();
+
+/******************************************************************************/
+
+enum {
+    HEAP_ID = IBinder::FIRST_CALL_TRANSACTION
+};
+
+class BpMemoryHeap : public BpInterface<IMemoryHeap>
+{
+public:
+    BpMemoryHeap(const sp<IBinder>& impl);
+    virtual ~BpMemoryHeap();
+
+    virtual int getHeapID() const;
+    virtual void* getBase() const;
+    virtual size_t getSize() const;
+    virtual uint32_t getFlags() const;
+
+private:
+    friend class IMemory;
+    friend class HeapCache;
+    
+    // for debugging in this module
+    static inline sp<IMemoryHeap> find_heap(const sp<IBinder>& binder) {
+        return gHeapCache->find_heap(binder);
+    }
+    static inline void free_heap(const sp<IBinder>& binder) {
+        gHeapCache->free_heap(binder);
+    }
+    static inline sp<IMemoryHeap> get_heap(const sp<IBinder>& binder) {
+        return gHeapCache->get_heap(binder);
+    }
+    static inline void dump_heaps() {
+        gHeapCache->dump_heaps();       
+    }
+    void inline pin_heap() const {
+        gHeapCache->pin_heap(const_cast<BpMemoryHeap*>(this)->asBinder());
+    }
+
+    void assertMapped() const;
+    void assertReallyMapped() const;
+    void pinHeap() const;
+
+    mutable volatile int32_t mHeapId;
+    mutable void*       mBase;
+    mutable size_t      mSize;
+    mutable uint32_t    mFlags;
+    mutable bool        mRealHeap;
+    mutable Mutex       mLock;
+};
+
+// ----------------------------------------------------------------------------
+
+enum {
+    GET_MEMORY = IBinder::FIRST_CALL_TRANSACTION
+};
+
+class BpMemory : public BpInterface<IMemory>
+{
+public:
+    BpMemory(const sp<IBinder>& impl);
+    virtual ~BpMemory();
+    virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const;
+    
+private:
+    mutable sp<IMemoryHeap> mHeap;
+    mutable ssize_t mOffset;
+    mutable size_t mSize;
+};
+
+/******************************************************************************/
+
+void* IMemory::fastPointer(const sp<IBinder>& binder, ssize_t offset) const
+{
+    sp<IMemoryHeap> realHeap = BpMemoryHeap::get_heap(binder);
+    void* const base = realHeap->base();
+    if (base == MAP_FAILED)
+        return 0;
+    return static_cast<char*>(base) + offset;
+}
+
+void* IMemory::pointer() const {
+    ssize_t offset;
+    sp<IMemoryHeap> heap = getMemory(&offset);
+    void* const base = heap!=0 ? heap->base() : MAP_FAILED;
+    if (base == MAP_FAILED)
+        return 0;
+    return static_cast<char*>(base) + offset;
+}
+
+size_t IMemory::size() const {
+    size_t size;
+    getMemory(NULL, &size);
+    return size;
+}
+
+ssize_t IMemory::offset() const {
+    ssize_t offset;
+    getMemory(&offset);
+    return offset;
+}
+
+/******************************************************************************/
+
+BpMemory::BpMemory(const sp<IBinder>& impl)
+    : BpInterface<IMemory>(impl), mOffset(0), mSize(0)
+{
+}
+
+BpMemory::~BpMemory()
+{
+}
+
+sp<IMemoryHeap> BpMemory::getMemory(ssize_t* offset, size_t* size) const
+{
+    if (mHeap == 0) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMemory::getInterfaceDescriptor());
+        if (remote()->transact(GET_MEMORY, data, &reply) == NO_ERROR) {
+            sp<IBinder> heap = reply.readStrongBinder();
+            ssize_t o = reply.readInt32();
+            size_t s = reply.readInt32();
+            if (heap != 0) {
+                mHeap = interface_cast<IMemoryHeap>(heap);
+                if (mHeap != 0) {
+                    mOffset = o;
+                    mSize = s;
+                }
+            }
+        }
+    }
+    if (offset) *offset = mOffset;
+    if (size) *size = mSize;
+    return mHeap;
+}
+
+// ---------------------------------------------------------------------------
+
+IMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory");
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnMemory::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case GET_MEMORY: {
+            CHECK_INTERFACE(IMemory, data, reply);
+            ssize_t offset;
+            size_t size;
+            reply->writeStrongBinder( getMemory(&offset, &size)->asBinder() );
+            reply->writeInt32(offset);
+            reply->writeInt32(size);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+
+/******************************************************************************/
+
+BpMemoryHeap::BpMemoryHeap(const sp<IBinder>& impl)
+    : BpInterface<IMemoryHeap>(impl),
+        mHeapId(-1), mBase(MAP_FAILED), mSize(0), mFlags(0), mRealHeap(false)
+{
+}
+
+BpMemoryHeap::~BpMemoryHeap() {
+    if (mHeapId != -1) {
+        close(mHeapId);
+        if (mRealHeap) {
+            // by construction we're the last one
+            if (mBase != MAP_FAILED) {
+                sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
+
+                if (VERBOSE) {
+                    LOGD("UNMAPPING binder=%p, heap=%p, size=%d, fd=%d", 
+                            binder.get(), this, mSize, mHeapId);
+                    CallStack stack;
+                    stack.update();
+                    stack.dump("callstack");
+                }
+
+                munmap(mBase, mSize);
+            }
+        } else {
+            // remove from list only if it was mapped before
+            sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
+            free_heap(binder);
+        }
+    }
+}
+
+void BpMemoryHeap::assertMapped() const
+{
+    if (mHeapId == -1) {
+        sp<IBinder> binder(const_cast<BpMemoryHeap*>(this)->asBinder());
+        sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get()));
+        heap->assertReallyMapped();
+        if (heap->mBase != MAP_FAILED) {
+            Mutex::Autolock _l(mLock);
+            if (mHeapId == -1) {
+                mBase   = heap->mBase;
+                mSize   = heap->mSize;
+                android_atomic_write( dup( heap->mHeapId ), &mHeapId );
+            }
+        } else {
+            // something went wrong
+            free_heap(binder);
+        }
+    }
+}
+
+void BpMemoryHeap::assertReallyMapped() const
+{
+    if (mHeapId == -1) {
+
+        // remote call without mLock held, worse case scenario, we end up
+        // calling transact() from multiple threads, but that's not a problem,
+        // only mmap below must be in the critical section.
+        
+        Parcel data, reply;
+        data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor());
+        status_t err = remote()->transact(HEAP_ID, data, &reply);
+        int parcel_fd = reply.readFileDescriptor();
+        ssize_t size = reply.readInt32();
+        uint32_t flags = reply.readInt32();
+
+        LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%d, err=%d (%s)",
+                asBinder().get(), parcel_fd, size, err, strerror(-err));
+
+        int fd = dup( parcel_fd );
+        LOGE_IF(fd==-1, "cannot dup fd=%d, size=%d, err=%d (%s)",
+                parcel_fd, size, err, strerror(errno));
+
+        int access = PROT_READ;
+        if (!(flags & READ_ONLY)) {
+            access |= PROT_WRITE;
+        }
+
+        Mutex::Autolock _l(mLock);
+        if (mHeapId == -1) {
+            mRealHeap = true;
+            mBase = mmap(0, size, access, MAP_SHARED, fd, 0);
+            if (mBase == MAP_FAILED) {
+                LOGE("cannot map BpMemoryHeap (binder=%p), size=%d, fd=%d (%s)",
+                        asBinder().get(), size, fd, strerror(errno));
+                close(fd);
+            } else {
+                if (flags & MAP_ONCE) {
+                    //LOGD("pinning heap (binder=%p, size=%d, fd=%d",
+                    //        asBinder().get(), size, fd);
+                    pin_heap();
+                }
+                mSize = size;
+                mFlags = flags;
+                android_atomic_write(fd, &mHeapId);
+            }
+        }
+    }
+}
+
+int BpMemoryHeap::getHeapID() const {
+    assertMapped();
+    return mHeapId;
+}
+
+void* BpMemoryHeap::getBase() const {
+    assertMapped();
+    return mBase;
+}
+
+size_t BpMemoryHeap::getSize() const {
+    assertMapped();
+    return mSize;
+}
+
+uint32_t BpMemoryHeap::getFlags() const {
+    assertMapped();
+    return mFlags;
+}
+
+// ---------------------------------------------------------------------------
+
+IMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap");
+
+status_t BnMemoryHeap::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+       case HEAP_ID: {
+            CHECK_INTERFACE(IMemoryHeap, data, reply);
+            reply->writeFileDescriptor(getHeapID());
+            reply->writeInt32(getSize());
+            reply->writeInt32(getFlags());
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+/*****************************************************************************/
+
+HeapCache::HeapCache()
+    : DeathRecipient()
+{
+}
+
+HeapCache::~HeapCache()
+{
+}
+
+void HeapCache::binderDied(const wp<IBinder>& binder)
+{
+    //LOGD("binderDied binder=%p", binder.unsafe_get());
+    free_heap(binder); 
+}
+
+sp<IMemoryHeap> HeapCache::find_heap(const sp<IBinder>& binder) 
+{
+    Mutex::Autolock _l(mHeapCacheLock);
+    ssize_t i = mHeapCache.indexOfKey(binder);
+    if (i>=0) {
+        heap_info_t& info = mHeapCache.editValueAt(i);
+        LOGD_IF(VERBOSE,
+                "found binder=%p, heap=%p, size=%d, fd=%d, count=%d", 
+                binder.get(), info.heap.get(),
+                static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
+                static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
+                info.count);
+        android_atomic_inc(&info.count);
+        return info.heap;
+    } else {
+        heap_info_t info;
+        info.heap = interface_cast<IMemoryHeap>(binder);
+        info.count = 1;
+        //LOGD("adding binder=%p, heap=%p, count=%d",
+        //      binder.get(), info.heap.get(), info.count);
+        mHeapCache.add(binder, info);
+        return info.heap;
+    }
+}
+
+void HeapCache::pin_heap(const sp<IBinder>& binder) 
+{
+    Mutex::Autolock _l(mHeapCacheLock);
+    ssize_t i = mHeapCache.indexOfKey(binder);
+    if (i>=0) {
+        heap_info_t& info(mHeapCache.editValueAt(i));
+        android_atomic_inc(&info.count);
+        binder->linkToDeath(this);
+    } else {
+        LOGE("pin_heap binder=%p not found!!!", binder.get());
+    }    
+}
+
+void HeapCache::free_heap(const sp<IBinder>& binder)  {
+    free_heap( wp<IBinder>(binder) );
+}
+
+void HeapCache::free_heap(const wp<IBinder>& binder) 
+{
+    sp<IMemoryHeap> rel;
+    {
+        Mutex::Autolock _l(mHeapCacheLock);
+        ssize_t i = mHeapCache.indexOfKey(binder);
+        if (i>=0) {
+            heap_info_t& info(mHeapCache.editValueAt(i));
+            int32_t c = android_atomic_dec(&info.count);
+            if (c == 1) {
+                LOGD_IF(VERBOSE,
+                        "removing binder=%p, heap=%p, size=%d, fd=%d, count=%d", 
+                        binder.unsafe_get(), info.heap.get(),
+                        static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
+                        static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
+                        info.count);
+                rel = mHeapCache.valueAt(i).heap;
+                mHeapCache.removeItemsAt(i);
+            }
+        } else {
+            LOGE("free_heap binder=%p not found!!!", binder.unsafe_get());
+        }
+    }
+}
+
+sp<IMemoryHeap> HeapCache::get_heap(const sp<IBinder>& binder)
+{
+    sp<IMemoryHeap> realHeap;
+    Mutex::Autolock _l(mHeapCacheLock);
+    ssize_t i = mHeapCache.indexOfKey(binder);
+    if (i>=0)   realHeap = mHeapCache.valueAt(i).heap;
+    else        realHeap = interface_cast<IMemoryHeap>(binder);
+    return realHeap;
+}
+
+void HeapCache::dump_heaps() 
+{
+    Mutex::Autolock _l(mHeapCacheLock);
+    int c = mHeapCache.size();
+    for (int i=0 ; i<c ; i++) {
+        const heap_info_t& info = mHeapCache.valueAt(i);
+        BpMemoryHeap const* h(static_cast<BpMemoryHeap const *>(info.heap.get()));
+        LOGD("hey=%p, heap=%p, count=%d, (fd=%d, base=%p, size=%d)",
+                mHeapCache.keyAt(i).unsafe_get(),
+                info.heap.get(), info.count, 
+                h->mHeapId, h->mBase, h->mSize);
+    }
+}
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/utils/IPCThreadState.cpp b/libs/utils/IPCThreadState.cpp
new file mode 100644
index 0000000..04ae142
--- /dev/null
+++ b/libs/utils/IPCThreadState.cpp
@@ -0,0 +1,1030 @@
+/*
+ * Copyright (C) 2005 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 <utils/IPCThreadState.h>
+
+#include <utils/Binder.h>
+#include <utils/BpBinder.h>
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/TextOutput.h>
+#include <utils/threads.h>
+
+#include <private/utils/binder_module.h>
+#include <private/utils/Static.h>
+
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#ifdef HAVE_PTHREADS
+#include <pthread.h>
+#include <sched.h>
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_WIN32_THREADS
+#include <windows.h>
+#endif
+
+
+#if LOG_NDEBUG
+
+#define IF_LOG_TRANSACTIONS() if (false)
+#define IF_LOG_COMMANDS() if (false)
+#define LOG_REMOTEREFS(...) 
+#define IF_LOG_REMOTEREFS() if (false)
+#define LOG_THREADPOOL(...) 
+#define LOG_ONEWAY(...) 
+
+#else
+
+#define IF_LOG_TRANSACTIONS() IF_LOG(LOG_VERBOSE, "transact")
+#define IF_LOG_COMMANDS() IF_LOG(LOG_VERBOSE, "ipc")
+#define LOG_REMOTEREFS(...) LOG(LOG_DEBUG, "remoterefs", __VA_ARGS__)
+#define IF_LOG_REMOTEREFS() IF_LOG(LOG_DEBUG, "remoterefs")
+#define LOG_THREADPOOL(...) LOG(LOG_DEBUG, "threadpool", __VA_ARGS__)
+#define LOG_ONEWAY(...) LOG(LOG_DEBUG, "ipc", __VA_ARGS__)
+
+#endif
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+static const char* getReturnString(size_t idx);
+static const char* getCommandString(size_t idx);
+static const void* printReturnCommand(TextOutput& out, const void* _cmd);
+static const void* printCommand(TextOutput& out, const void* _cmd);
+
+// This will result in a missing symbol failure if the IF_LOG_COMMANDS()
+// conditionals don't get stripped...  but that is probably what we want.
+#if !LOG_NDEBUG
+static const char *kReturnStrings[] = {
+#if 1 /* TODO: error update strings */
+    "unknown",
+#else
+    "BR_OK",
+    "BR_TIMEOUT",
+    "BR_WAKEUP",
+    "BR_TRANSACTION",
+    "BR_REPLY",
+    "BR_ACQUIRE_RESULT",
+    "BR_DEAD_REPLY",
+    "BR_TRANSACTION_COMPLETE",
+    "BR_INCREFS",
+    "BR_ACQUIRE",
+    "BR_RELEASE",
+    "BR_DECREFS",
+    "BR_ATTEMPT_ACQUIRE",
+    "BR_EVENT_OCCURRED",
+    "BR_NOOP",
+    "BR_SPAWN_LOOPER",
+    "BR_FINISHED",
+    "BR_DEAD_BINDER",
+    "BR_CLEAR_DEATH_NOTIFICATION_DONE"
+#endif
+};
+
+static const char *kCommandStrings[] = {
+#if 1 /* TODO: error update strings */
+    "unknown",
+#else
+    "BC_NOOP",
+    "BC_TRANSACTION",
+    "BC_REPLY",
+    "BC_ACQUIRE_RESULT",
+    "BC_FREE_BUFFER",
+    "BC_TRANSACTION_COMPLETE",
+    "BC_INCREFS",
+    "BC_ACQUIRE",
+    "BC_RELEASE",
+    "BC_DECREFS",
+    "BC_INCREFS_DONE",
+    "BC_ACQUIRE_DONE",
+    "BC_ATTEMPT_ACQUIRE",
+    "BC_RETRIEVE_ROOT_OBJECT",
+    "BC_SET_THREAD_ENTRY",
+    "BC_REGISTER_LOOPER",
+    "BC_ENTER_LOOPER",
+    "BC_EXIT_LOOPER",
+    "BC_SYNC",
+    "BC_STOP_PROCESS",
+    "BC_STOP_SELF",
+    "BC_REQUEST_DEATH_NOTIFICATION",
+    "BC_CLEAR_DEATH_NOTIFICATION",
+    "BC_DEAD_BINDER_DONE"
+#endif
+};
+
+static const char* getReturnString(size_t idx)
+{
+    if (idx < sizeof(kReturnStrings) / sizeof(kReturnStrings[0]))
+        return kReturnStrings[idx];
+    else
+        return "unknown";
+}
+
+static const char* getCommandString(size_t idx)
+{
+    if (idx < sizeof(kCommandStrings) / sizeof(kCommandStrings[0]))
+        return kCommandStrings[idx];
+    else
+        return "unknown";
+}
+
+static const void* printBinderTransactionData(TextOutput& out, const void* data)
+{
+    const binder_transaction_data* btd =
+        (const binder_transaction_data*)data;
+    out << "target=" << btd->target.ptr << " (cookie " << btd->cookie << ")" << endl
+        << "code=" << TypeCode(btd->code) << ", flags=" << (void*)btd->flags << endl
+        << "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
+        << " bytes)" << endl
+        << "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
+        << " bytes)" << endl;
+    return btd+1;
+}
+
+static const void* printReturnCommand(TextOutput& out, const void* _cmd)
+{
+    static const int32_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
+    
+    const int32_t* cmd = (const int32_t*)_cmd;
+    int32_t code = *cmd++;
+    if (code == BR_ERROR) {
+        out << "BR_ERROR: " << (void*)(*cmd++) << endl;
+        return cmd;
+    } else if (code < 0 || code >= N) {
+        out << "Unknown reply: " << code << endl;
+        return cmd;
+    }
+    
+    out << kReturnStrings[code];
+    switch (code) {
+        case BR_TRANSACTION:
+        case BR_REPLY: {
+            out << ": " << indent;
+            cmd = (const int32_t *)printBinderTransactionData(out, cmd);
+            out << dedent;
+        } break;
+        
+        case BR_ACQUIRE_RESULT: {
+            const int32_t res = *cmd++;
+            out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
+        } break;
+        
+        case BR_INCREFS:
+        case BR_ACQUIRE:
+        case BR_RELEASE:
+        case BR_DECREFS: {
+            const int32_t b = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
+        } break;
+    
+        case BR_ATTEMPT_ACQUIRE: {
+            const int32_t p = *cmd++;
+            const int32_t b = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": target=" << (void*)b << " (cookie " << (void*)c
+                << "), pri=" << p;
+        } break;
+
+        case BR_DEAD_BINDER:
+        case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
+            const int32_t c = *cmd++;
+            out << ": death cookie " << (void*)c;
+        } break;
+    }
+    
+    out << endl;
+    return cmd;
+}
+
+static const void* printCommand(TextOutput& out, const void* _cmd)
+{
+    static const int32_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
+    
+    const int32_t* cmd = (const int32_t*)_cmd;
+    int32_t code = *cmd++;
+    if (code < 0 || code >= N) {
+        out << "Unknown command: " << code << endl;
+        return cmd;
+    }
+    
+    out << kCommandStrings[code];
+    switch (code) {
+        case BC_TRANSACTION:
+        case BC_REPLY: {
+            out << ": " << indent;
+            cmd = (const int32_t *)printBinderTransactionData(out, cmd);
+            out << dedent;
+        } break;
+        
+        case BC_ACQUIRE_RESULT: {
+            const int32_t res = *cmd++;
+            out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
+        } break;
+        
+        case BC_FREE_BUFFER: {
+            const int32_t buf = *cmd++;
+            out << ": buffer=" << (void*)buf;
+        } break;
+        
+        case BC_INCREFS:
+        case BC_ACQUIRE:
+        case BC_RELEASE:
+        case BC_DECREFS: {
+            const int32_t d = *cmd++;
+            out << ": descriptor=" << (void*)d;
+        } break;
+    
+        case BC_INCREFS_DONE:
+        case BC_ACQUIRE_DONE: {
+            const int32_t b = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
+        } break;
+        
+        case BC_ATTEMPT_ACQUIRE: {
+            const int32_t p = *cmd++;
+            const int32_t d = *cmd++;
+            out << ": decriptor=" << (void*)d << ", pri=" << p;
+        } break;
+        
+        case BC_REQUEST_DEATH_NOTIFICATION:
+        case BC_CLEAR_DEATH_NOTIFICATION: {
+            const int32_t h = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": handle=" << h << " (death cookie " << (void*)c << ")";
+        } break;
+
+        case BC_DEAD_BINDER_DONE: {
+            const int32_t c = *cmd++;
+            out << ": death cookie " << (void*)c;
+        } break;
+    }
+    
+    out << endl;
+    return cmd;
+}
+#endif
+
+static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
+static bool gHaveTLS = false;
+static pthread_key_t gTLS = 0;
+static bool gShutdown = false;
+
+IPCThreadState* IPCThreadState::self()
+{
+    if (gHaveTLS) {
+restart:
+        const pthread_key_t k = gTLS;
+        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
+        if (st) return st;
+        return new IPCThreadState;
+    }
+    
+    if (gShutdown) return NULL;
+    
+    pthread_mutex_lock(&gTLSMutex);
+    if (!gHaveTLS) {
+        if (pthread_key_create(&gTLS, threadDestructor) != 0) {
+            pthread_mutex_unlock(&gTLSMutex);
+            return NULL;
+        }
+        gHaveTLS = true;
+    }
+    pthread_mutex_unlock(&gTLSMutex);
+    goto restart;
+}
+
+void IPCThreadState::shutdown()
+{
+    gShutdown = true;
+    
+    if (gHaveTLS) {
+        // XXX Need to wait for all thread pool threads to exit!
+        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
+        if (st) {
+            delete st;
+            pthread_setspecific(gTLS, NULL);
+        }
+        gHaveTLS = false;
+    }
+}
+
+sp<ProcessState> IPCThreadState::process()
+{
+    return mProcess;
+}
+
+status_t IPCThreadState::clearLastError()
+{
+    const status_t err = mLastError;
+    mLastError = NO_ERROR;
+    return err;
+}
+
+int IPCThreadState::getCallingPid()
+{
+    return mCallingPid;
+}
+
+int IPCThreadState::getCallingUid()
+{
+    return mCallingUid;
+}
+
+int64_t IPCThreadState::clearCallingIdentity()
+{
+    int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
+    clearCaller();
+    return token;
+}
+
+void IPCThreadState::restoreCallingIdentity(int64_t token)
+{
+    mCallingUid = (int)(token>>32);
+    mCallingPid = (int)token;
+}
+
+void IPCThreadState::clearCaller()
+{
+    if (mProcess->supportsProcesses()) {
+        mCallingPid = getpid();
+        mCallingUid = getuid();
+    } else {
+        mCallingPid = -1;
+        mCallingUid = -1;
+    }
+}
+
+void IPCThreadState::flushCommands()
+{
+    if (mProcess->mDriverFD <= 0)
+        return;
+    talkWithDriver(false);
+}
+
+void IPCThreadState::joinThreadPool(bool isMain)
+{
+    LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
+
+    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
+    
+    status_t result;
+    do {
+        int32_t cmd;
+        
+        // When we've cleared the incoming command queue, process any pending derefs
+        if (mIn.dataPosition() >= mIn.dataSize()) {
+            size_t numPending = mPendingWeakDerefs.size();
+            if (numPending > 0) {
+                for (size_t i = 0; i < numPending; i++) {
+                    RefBase::weakref_type* refs = mPendingWeakDerefs[i];
+                    refs->decWeak(mProcess.get());
+                }
+                mPendingWeakDerefs.clear();
+            }
+
+            numPending = mPendingStrongDerefs.size();
+            if (numPending > 0) {
+                for (size_t i = 0; i < numPending; i++) {
+                    BBinder* obj = mPendingStrongDerefs[i];
+                    obj->decStrong(mProcess.get());
+                }
+                mPendingStrongDerefs.clear();
+            }
+        }
+
+        // now get the next command to be processed, waiting if necessary
+        result = talkWithDriver();
+        if (result >= NO_ERROR) {
+            size_t IN = mIn.dataAvail();
+            if (IN < sizeof(int32_t)) continue;
+            cmd = mIn.readInt32();
+            IF_LOG_COMMANDS() {
+                alog << "Processing top-level Command: "
+                    << getReturnString(cmd) << endl;
+            }
+            result = executeCommand(cmd);
+        }
+        
+        // Let this thread exit the thread pool if it is no longer
+        // needed and it is not the main process thread.
+        if(result == TIMED_OUT && !isMain) {
+            break;
+        }
+    } while (result != -ECONNREFUSED && result != -EBADF);
+
+    LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",
+        (void*)pthread_self(), getpid(), (void*)result);
+    
+    mOut.writeInt32(BC_EXIT_LOOPER);
+    talkWithDriver(false);
+}
+
+void IPCThreadState::stopProcess(bool immediate)
+{
+    //LOGI("**** STOPPING PROCESS");
+    flushCommands();
+    int fd = mProcess->mDriverFD;
+    mProcess->mDriverFD = -1;
+    close(fd);
+    //kill(getpid(), SIGKILL);
+}
+
+status_t IPCThreadState::transact(int32_t handle,
+                                  uint32_t code, const Parcel& data,
+                                  Parcel* reply, uint32_t flags)
+{
+    status_t err = data.errorCheck();
+
+    flags |= TF_ACCEPT_FDS;
+
+    IF_LOG_TRANSACTIONS() {
+        TextOutput::Bundle _b(alog);
+        alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
+            << handle << " / code " << TypeCode(code) << ": "
+            << indent << data << dedent << endl;
+    }
+    
+    if (err == NO_ERROR) {
+        LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
+            (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
+        err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
+    }
+    
+    if (err != NO_ERROR) {
+        if (reply) reply->setError(err);
+        return (mLastError = err);
+    }
+    
+    if ((flags & TF_ONE_WAY) == 0) {
+        if (reply) {
+            err = waitForResponse(reply);
+        } else {
+            Parcel fakeReply;
+            err = waitForResponse(&fakeReply);
+        }
+        
+        IF_LOG_TRANSACTIONS() {
+            TextOutput::Bundle _b(alog);
+            alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
+                << handle << ": ";
+            if (reply) alog << indent << *reply << dedent << endl;
+            else alog << "(none requested)" << endl;
+        }
+    } else {
+        err = waitForResponse(NULL, NULL);
+    }
+    
+    return err;
+}
+
+void IPCThreadState::incStrongHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
+    mOut.writeInt32(BC_ACQUIRE);
+    mOut.writeInt32(handle);
+}
+
+void IPCThreadState::decStrongHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle);
+    mOut.writeInt32(BC_RELEASE);
+    mOut.writeInt32(handle);
+}
+
+void IPCThreadState::incWeakHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
+    mOut.writeInt32(BC_INCREFS);
+    mOut.writeInt32(handle);
+}
+
+void IPCThreadState::decWeakHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle);
+    mOut.writeInt32(BC_DECREFS);
+    mOut.writeInt32(handle);
+}
+
+status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
+{
+    mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
+    mOut.writeInt32(0); // xxx was thread priority
+    mOut.writeInt32(handle);
+    status_t result = UNKNOWN_ERROR;
+    
+    waitForResponse(NULL, &result);
+    
+#if LOG_REFCOUNTS
+    printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n",
+        handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
+#endif
+    
+    return result;
+}
+
+void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder)
+{
+#if LOG_REFCOUNTS
+    printf("IPCThreadState::expungeHandle(%ld)\n", handle);
+#endif
+    self()->mProcess->expungeHandle(handle, binder);
+}
+
+status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
+{
+    mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
+    mOut.writeInt32((int32_t)handle);
+    mOut.writeInt32((int32_t)proxy);
+    return NO_ERROR;
+}
+
+status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
+{
+    mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
+    mOut.writeInt32((int32_t)handle);
+    mOut.writeInt32((int32_t)proxy);
+    return NO_ERROR;
+}
+
+IPCThreadState::IPCThreadState()
+    : mProcess(ProcessState::self())
+{
+    pthread_setspecific(gTLS, this);
+        clearCaller();
+    mIn.setDataCapacity(256);
+    mOut.setDataCapacity(256);
+}
+
+IPCThreadState::~IPCThreadState()
+{
+}
+
+status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
+{
+    status_t err;
+    status_t statusBuffer;
+    err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
+    if (err < NO_ERROR) return err;
+    
+    return waitForResponse(NULL, NULL);
+}
+
+status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
+{
+    int32_t cmd;
+    int32_t err;
+
+    while (1) {
+        if ((err=talkWithDriver()) < NO_ERROR) break;
+        err = mIn.errorCheck();
+        if (err < NO_ERROR) break;
+        if (mIn.dataAvail() == 0) continue;
+        
+        cmd = mIn.readInt32();
+        
+        IF_LOG_COMMANDS() {
+            alog << "Processing waitForResponse Command: "
+                << getReturnString(cmd) << endl;
+        }
+
+        switch (cmd) {
+        case BR_TRANSACTION_COMPLETE:
+            if (!reply && !acquireResult) goto finish;
+            break;
+        
+        case BR_DEAD_REPLY:
+            err = DEAD_OBJECT;
+            goto finish;
+
+        case BR_FAILED_REPLY:
+            err = FAILED_TRANSACTION;
+            goto finish;
+        
+        case BR_ACQUIRE_RESULT:
+            {
+                LOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
+                const int32_t result = mIn.readInt32();
+                if (!acquireResult) continue;
+                *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
+            }
+            goto finish;
+        
+        case BR_REPLY:
+            {
+                binder_transaction_data tr;
+                err = mIn.read(&tr, sizeof(tr));
+                LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
+                if (err != NO_ERROR) goto finish;
+
+                if (reply) {
+                    if ((tr.flags & TF_STATUS_CODE) == 0) {
+                        reply->ipcSetDataReference(
+                            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                            tr.data_size,
+                            reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                            tr.offsets_size/sizeof(size_t),
+                            freeBuffer, this);
+                    } else {
+                        err = *static_cast<const status_t*>(tr.data.ptr.buffer);
+                        freeBuffer(NULL,
+                            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                            tr.data_size,
+                            reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                            tr.offsets_size/sizeof(size_t), this);
+                    }
+                } else {
+                    freeBuffer(NULL,
+                        reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                        tr.data_size,
+                        reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                        tr.offsets_size/sizeof(size_t), this);
+                    continue;
+                }
+            }
+            goto finish;
+
+        default:
+            err = executeCommand(cmd);
+            if (err != NO_ERROR) goto finish;
+            break;
+        }
+    }
+
+finish:
+    if (err != NO_ERROR) {
+        if (acquireResult) *acquireResult = err;
+        if (reply) reply->setError(err);
+        mLastError = err;
+    }
+    
+    return err;
+}
+
+status_t IPCThreadState::talkWithDriver(bool doReceive)
+{
+    LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
+    
+    binder_write_read bwr;
+    
+    // Is the read buffer empty?
+    const bool needRead = mIn.dataPosition() >= mIn.dataSize();
+    
+    // We don't want to write anything if we are still reading
+    // from data left in the input buffer and the caller
+    // has requested to read the next data.
+    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
+    
+    bwr.write_size = outAvail;
+    bwr.write_buffer = (long unsigned int)mOut.data();
+
+    // This is what we'll read.
+    if (doReceive && needRead) {
+        bwr.read_size = mIn.dataCapacity();
+        bwr.read_buffer = (long unsigned int)mIn.data();
+    } else {
+        bwr.read_size = 0;
+    }
+    
+    IF_LOG_COMMANDS() {
+        TextOutput::Bundle _b(alog);
+        if (outAvail != 0) {
+            alog << "Sending commands to driver: " << indent;
+            const void* cmds = (const void*)bwr.write_buffer;
+            const void* end = ((const uint8_t*)cmds)+bwr.write_size;
+            alog << HexDump(cmds, bwr.write_size) << endl;
+            while (cmds < end) cmds = printCommand(alog, cmds);
+            alog << dedent;
+        }
+        alog << "Size of receive buffer: " << bwr.read_size
+            << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
+    }
+    
+    // Return immediately if there is nothing to do.
+    if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
+    
+    bwr.write_consumed = 0;
+    bwr.read_consumed = 0;
+    status_t err;
+    do {
+        IF_LOG_COMMANDS() {
+            alog << "About to read/write, write size = " << mOut.dataSize() << endl;
+        }
+#if defined(HAVE_ANDROID_OS)
+        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
+            err = NO_ERROR;
+        else
+            err = -errno;
+#else
+        err = INVALID_OPERATION;
+#endif
+        IF_LOG_COMMANDS() {
+            alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
+        }
+    } while (err == -EINTR);
+    
+    IF_LOG_COMMANDS() {
+        alog << "Our err: " << (void*)err << ", write consumed: "
+            << bwr.write_consumed << " (of " << mOut.dataSize()
+			<< "), read consumed: " << bwr.read_consumed << endl;
+    }
+
+    if (err >= NO_ERROR) {
+        if (bwr.write_consumed > 0) {
+            if (bwr.write_consumed < (ssize_t)mOut.dataSize())
+                mOut.remove(0, bwr.write_consumed);
+            else
+                mOut.setDataSize(0);
+        }
+        if (bwr.read_consumed > 0) {
+            mIn.setDataSize(bwr.read_consumed);
+            mIn.setDataPosition(0);
+        }
+        IF_LOG_COMMANDS() {
+            TextOutput::Bundle _b(alog);
+            alog << "Remaining data size: " << mOut.dataSize() << endl;
+            alog << "Received commands from driver: " << indent;
+            const void* cmds = mIn.data();
+            const void* end = mIn.data() + mIn.dataSize();
+            alog << HexDump(cmds, mIn.dataSize()) << endl;
+            while (cmds < end) cmds = printReturnCommand(alog, cmds);
+            alog << dedent;
+        }
+        return NO_ERROR;
+    }
+    
+    return err;
+}
+
+status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
+    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
+{
+    binder_transaction_data tr;
+
+    tr.target.handle = handle;
+    tr.code = code;
+    tr.flags = binderFlags;
+    
+    const status_t err = data.errorCheck();
+    if (err == NO_ERROR) {
+        tr.data_size = data.ipcDataSize();
+        tr.data.ptr.buffer = data.ipcData();
+        tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);
+        tr.data.ptr.offsets = data.ipcObjects();
+    } else if (statusBuffer) {
+        tr.flags |= TF_STATUS_CODE;
+        *statusBuffer = err;
+        tr.data_size = sizeof(status_t);
+        tr.data.ptr.buffer = statusBuffer;
+        tr.offsets_size = 0;
+        tr.data.ptr.offsets = NULL;
+    } else {
+        return (mLastError = err);
+    }
+    
+    mOut.writeInt32(cmd);
+    mOut.write(&tr, sizeof(tr));
+    
+    return NO_ERROR;
+}
+
+sp<BBinder> the_context_object;
+
+void setTheContextObject(sp<BBinder> obj)
+{
+    the_context_object = obj;
+}
+
+status_t IPCThreadState::executeCommand(int32_t cmd)
+{
+    BBinder* obj;
+    RefBase::weakref_type* refs;
+    status_t result = NO_ERROR;
+    
+    switch (cmd) {
+    case BR_ERROR:
+        result = mIn.readInt32();
+        break;
+        
+    case BR_OK:
+        break;
+        
+    case BR_ACQUIRE:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        LOG_ASSERT(refs->refBase() == obj,
+                   "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
+                   refs, obj, refs->refBase());
+        obj->incStrong(mProcess.get());
+        IF_LOG_REMOTEREFS() {
+            LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
+            obj->printRefs();
+        }
+        mOut.writeInt32(BC_ACQUIRE_DONE);
+        mOut.writeInt32((int32_t)refs);
+        mOut.writeInt32((int32_t)obj);
+        break;
+        
+    case BR_RELEASE:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        LOG_ASSERT(refs->refBase() == obj,
+                   "BR_RELEASE: object %p does not match cookie %p (expected %p)",
+                   refs, obj, refs->refBase());
+        IF_LOG_REMOTEREFS() {
+            LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
+            obj->printRefs();
+        }
+        mPendingStrongDerefs.push(obj);
+        break;
+        
+    case BR_INCREFS:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        refs->incWeak(mProcess.get());
+        mOut.writeInt32(BC_INCREFS_DONE);
+        mOut.writeInt32((int32_t)refs);
+        mOut.writeInt32((int32_t)obj);
+        break;
+        
+    case BR_DECREFS:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        // NOTE: This assertion is not valid, because the object may no
+        // longer exist (thus the (BBinder*)cast above resulting in a different
+        // memory address).
+        //LOG_ASSERT(refs->refBase() == obj,
+        //           "BR_DECREFS: object %p does not match cookie %p (expected %p)",
+        //           refs, obj, refs->refBase());
+        mPendingWeakDerefs.push(refs);
+        break;
+        
+    case BR_ATTEMPT_ACQUIRE:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+         
+        {
+            const bool success = refs->attemptIncStrong(mProcess.get());
+            LOG_ASSERT(success && refs->refBase() == obj,
+                       "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
+                       refs, obj, refs->refBase());
+            
+            mOut.writeInt32(BC_ACQUIRE_RESULT);
+            mOut.writeInt32((int32_t)success);
+        }
+        break;
+    
+    case BR_TRANSACTION:
+        {
+            binder_transaction_data tr;
+            result = mIn.read(&tr, sizeof(tr));
+            LOG_ASSERT(result == NO_ERROR,
+                "Not enough command data for brTRANSACTION");
+            if (result != NO_ERROR) break;
+            
+            Parcel buffer;
+            buffer.ipcSetDataReference(
+                reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                tr.data_size,
+                reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                tr.offsets_size/sizeof(size_t), freeBuffer, this);
+            
+            const pid_t origPid = mCallingPid;
+            const uid_t origUid = mCallingUid;
+            
+            mCallingPid = tr.sender_pid;
+            mCallingUid = tr.sender_euid;
+            
+            //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
+            
+            Parcel reply;
+            IF_LOG_TRANSACTIONS() {
+                TextOutput::Bundle _b(alog);
+                alog << "BR_TRANSACTION thr " << (void*)pthread_self()
+                    << " / obj " << tr.target.ptr << " / code "
+                    << TypeCode(tr.code) << ": " << indent << buffer
+                    << dedent << endl
+                    << "Data addr = "
+                    << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
+                    << ", offsets addr="
+                    << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
+            }
+            if (tr.target.ptr) {
+                sp<BBinder> b((BBinder*)tr.cookie);
+                const status_t error = b->transact(tr.code, buffer, &reply, 0);
+                if (error < NO_ERROR) reply.setError(error);
+                
+            } else {
+                const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0);
+                if (error < NO_ERROR) reply.setError(error);
+            }
+            
+            //LOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
+            //     mCallingPid, origPid, origUid);
+            
+            if ((tr.flags & TF_ONE_WAY) == 0) {
+                LOG_ONEWAY("Sending reply to %d!", mCallingPid);
+                sendReply(reply, 0);
+            } else {
+                LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
+            }
+            
+            mCallingPid = origPid;
+            mCallingUid = origUid;
+            
+            IF_LOG_TRANSACTIONS() {
+                TextOutput::Bundle _b(alog);
+                alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
+                    << tr.target.ptr << ": " << indent << reply << dedent << endl;
+            }
+            
+        }
+        break;
+    
+    case BR_DEAD_BINDER:
+        {
+            BpBinder *proxy = (BpBinder*)mIn.readInt32();
+            proxy->sendObituary();
+            mOut.writeInt32(BC_DEAD_BINDER_DONE);
+            mOut.writeInt32((int32_t)proxy);
+        } break;
+        
+    case BR_CLEAR_DEATH_NOTIFICATION_DONE:
+        {
+            BpBinder *proxy = (BpBinder*)mIn.readInt32();
+            proxy->getWeakRefs()->decWeak(proxy);
+        } break;
+        
+    case BR_FINISHED:
+        result = TIMED_OUT;
+        break;
+        
+    case BR_NOOP:
+        break;
+        
+    case BR_SPAWN_LOOPER:
+        mProcess->spawnPooledThread(false);
+        break;
+        
+    default:
+        printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
+        result = UNKNOWN_ERROR;
+        break;
+    }
+
+    if (result != NO_ERROR) {
+        mLastError = result;
+    }
+    
+    return result;
+}
+
+void IPCThreadState::threadDestructor(void *st)
+{
+	IPCThreadState* const self = static_cast<IPCThreadState*>(st);
+	if (self) {
+		self->flushCommands();
+#if defined(HAVE_ANDROID_OS)
+        ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
+#endif
+		delete self;
+	}
+}
+
+
+void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, size_t dataSize,
+                                const size_t* objects, size_t objectsSize,
+                                void* cookie)
+{
+    //LOGI("Freeing parcel %p", &parcel);
+    IF_LOG_COMMANDS() {
+        alog << "Writing BC_FREE_BUFFER for " << data << endl;
+    }
+    LOG_ASSERT(data != NULL, "Called with NULL data");
+    if (parcel != NULL) parcel->closeFileDescriptors();
+    IPCThreadState* state = self();
+    state->mOut.writeInt32(BC_FREE_BUFFER);
+    state->mOut.writeInt32((int32_t)data);
+}
+
+}; // namespace android
diff --git a/libs/utils/IPermissionController.cpp b/libs/utils/IPermissionController.cpp
new file mode 100644
index 0000000..f01d38f
--- /dev/null
+++ b/libs/utils/IPermissionController.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2005 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 "PermissionController"
+
+#include <utils/IPermissionController.h>
+
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/Parcel.h>
+#include <utils/String8.h>
+
+#include <private/utils/Static.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class BpPermissionController : public BpInterface<IPermissionController>
+{
+public:
+    BpPermissionController(const sp<IBinder>& impl)
+        : BpInterface<IPermissionController>(impl)
+    {
+    }
+        
+    virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
+        data.writeString16(permission);
+        data.writeInt32(pid);
+        data.writeInt32(uid);
+        remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply);
+        // fail on exception
+        if (reply.readInt32() != 0) return 0;
+        return reply.readInt32() != 0;
+    }
+};
+
+IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnPermissionController::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    //printf("PermissionController received: "); data.print();
+    switch(code) {
+        case CHECK_PERMISSION_TRANSACTION: {
+            CHECK_INTERFACE(IPermissionController, data, reply);
+            String16 permission = data.readString16();
+            int32_t pid = data.readInt32();
+            int32_t uid = data.readInt32();
+            bool res = checkPermission(permission, pid, uid);
+            // write exception
+            reply->writeInt32(0);
+            reply->writeInt32(res ? 1 : 0);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace android
+
diff --git a/libs/utils/IServiceManager.cpp b/libs/utils/IServiceManager.cpp
new file mode 100644
index 0000000..9beeadd
--- /dev/null
+++ b/libs/utils/IServiceManager.cpp
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2005 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 "ServiceManager"
+
+#include <utils/IServiceManager.h>
+
+#include <utils/Debug.h>
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+#include <utils/Parcel.h>
+#include <utils/String8.h>
+#include <utils/SystemClock.h>
+
+#include <private/utils/Static.h>
+
+#include <unistd.h>
+
+namespace android {
+
+sp<IServiceManager> defaultServiceManager()
+{
+    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
+    
+    {
+        AutoMutex _l(gDefaultServiceManagerLock);
+        if (gDefaultServiceManager == NULL) {
+            gDefaultServiceManager = interface_cast<IServiceManager>(
+                ProcessState::self()->getContextObject(NULL));
+        }
+    }
+    
+    return gDefaultServiceManager;
+}
+
+bool checkCallingPermission(const String16& permission)
+{
+    return checkCallingPermission(permission, NULL, NULL);
+}
+
+static String16 _permission("permission");
+
+bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid)
+{
+    IPCThreadState* ipcState = IPCThreadState::self();
+    int32_t pid = ipcState->getCallingPid();
+    int32_t uid = ipcState->getCallingUid();
+    if (outPid) *outPid = pid;
+    if (outUid) *outUid= uid;
+    
+    sp<IPermissionController> pc;
+    gDefaultServiceManagerLock.lock();
+    pc = gPermissionController;
+    gDefaultServiceManagerLock.unlock();
+    
+    int64_t startTime = 0;
+
+    while (true) {
+        if (pc != NULL) {
+            bool res = pc->checkPermission(permission, pid, uid);
+            if (res) {
+                if (startTime != 0) {
+                    LOGI("Check passed after %d seconds for %s from uid=%d pid=%d",
+                            (int)((uptimeMillis()-startTime)/1000),
+                            String8(permission).string(), uid, pid);
+                }
+                return res;
+            }
+            
+            // Is this a permission failure, or did the controller go away?
+            if (pc->asBinder()->isBinderAlive()) {
+                LOGW("Permission failure: %s from uid=%d pid=%d",
+                        String8(permission).string(), uid, pid);
+                return false;
+            }
+            
+            // Object is dead!
+            gDefaultServiceManagerLock.lock();
+            if (gPermissionController == pc) {
+                gPermissionController = NULL;
+            }
+            gDefaultServiceManagerLock.unlock();
+        }
+    
+        // Need to retrieve the permission controller.
+        sp<IBinder> binder = defaultServiceManager()->checkService(_permission);
+        if (binder == NULL) {
+            // Wait for the permission controller to come back...
+            if (startTime == 0) {
+                startTime = uptimeMillis();
+                LOGI("Waiting to check permission %s from uid=%d pid=%d",
+                        String8(permission).string(), uid, pid);
+            }
+            sleep(1);
+        } else {
+            pc = interface_cast<IPermissionController>(binder);
+            // Install the new permission controller, and try again.        
+            gDefaultServiceManagerLock.lock();
+            gPermissionController = pc;
+            gDefaultServiceManagerLock.unlock();
+        }
+    }
+}
+
+// ----------------------------------------------------------------------
+
+class BpServiceManager : public BpInterface<IServiceManager>
+{
+public:
+    BpServiceManager(const sp<IBinder>& impl)
+        : BpInterface<IServiceManager>(impl)
+    {
+    }
+        
+    virtual sp<IBinder> getService(const String16& name) const
+    {
+        unsigned n;
+        for (n = 0; n < 5; n++){
+            sp<IBinder> svc = checkService(name);
+            if (svc != NULL) return svc;
+            LOGI("Waiting for sevice %s...\n", String8(name).string());
+            sleep(1);
+        }
+        return NULL;
+    }
+    
+    virtual sp<IBinder> checkService( const String16& name) const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+        data.writeString16(name);
+        remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
+        return reply.readStrongBinder();
+    }
+
+    virtual status_t addService(const String16& name, const sp<IBinder>& service)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeStrongBinder(service);
+        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
+        return err == NO_ERROR ? reply.readInt32() : err;
+    }
+
+    virtual Vector<String16> listServices()
+    {
+        Vector<String16> res;
+        int n = 0;
+
+        for (;;) {
+            Parcel data, reply;
+            data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+            data.writeInt32(n++);
+            status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply);
+            if (err != NO_ERROR)
+                break;
+            res.add(reply.readString16());
+        }
+        return res;
+    }
+};
+
+IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnServiceManager::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    //printf("ServiceManager received: "); data.print();
+    switch(code) {
+        case GET_SERVICE_TRANSACTION: {
+            CHECK_INTERFACE(IServiceManager, data, reply);
+            String16 which = data.readString16();
+            sp<IBinder> b = const_cast<BnServiceManager*>(this)->getService(which);
+            reply->writeStrongBinder(b);
+            return NO_ERROR;
+        } break;
+        case CHECK_SERVICE_TRANSACTION: {
+            CHECK_INTERFACE(IServiceManager, data, reply);
+            String16 which = data.readString16();
+            sp<IBinder> b = const_cast<BnServiceManager*>(this)->checkService(which);
+            reply->writeStrongBinder(b);
+            return NO_ERROR;
+        } break;
+        case ADD_SERVICE_TRANSACTION: {
+            CHECK_INTERFACE(IServiceManager, data, reply);
+            String16 which = data.readString16();
+            sp<IBinder> b = data.readStrongBinder();
+            status_t err = addService(which, b);
+            reply->writeInt32(err);
+            return NO_ERROR;
+        } break;
+        case LIST_SERVICES_TRANSACTION: {
+            CHECK_INTERFACE(IServiceManager, data, reply);
+            Vector<String16> list = listServices();
+            const size_t N = list.size();
+            reply->writeInt32(N);
+            for (size_t i=0; i<N; i++) {
+                reply->writeString16(list[i]);
+            }
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace android
+
diff --git a/libs/utils/InetAddress.cpp b/libs/utils/InetAddress.cpp
new file mode 100644
index 0000000..39a0a68
--- /dev/null
+++ b/libs/utils/InetAddress.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+//
+// Internet address class.
+//
+#ifdef HAVE_WINSOCK
+# include <winsock2.h>
+#else
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+//# include <arpa/inet.h>
+# include <netdb.h>
+#endif
+
+#include <utils/inet_address.h>
+#include <utils/threads.h>
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+using namespace android;
+
+
+/*
+ * ===========================================================================
+ *      InetAddress
+ * ===========================================================================
+ */
+
+// lock for the next couple of functions; could tuck into InetAddress
+static Mutex*   gGHBNLock;
+
+/*
+ * Lock/unlock access to the hostent struct returned by gethostbyname().
+ */
+static inline void lock_gethostbyname(void)
+{
+    if (gGHBNLock == NULL)
+        gGHBNLock = new Mutex;
+    gGHBNLock->lock();
+}
+static inline void unlock_gethostbyname(void)
+{
+    assert(gGHBNLock != NULL);
+    gGHBNLock->unlock();
+}
+
+
+/*
+ * Constructor -- just init members.  This is private so that callers
+ * are required to use getByName().
+ */
+InetAddress::InetAddress(void)
+    : mAddress(NULL), mLength(-1), mName(NULL)
+{
+}
+
+/*
+ * Destructor -- free address storage.
+ */
+InetAddress::~InetAddress(void)
+{
+    delete[] (char*) mAddress;
+    delete[] mName;
+}
+
+/*
+ * Copy constructor.
+ */
+InetAddress::InetAddress(const InetAddress& orig)
+{
+    *this = orig;   // use assignment code
+}
+
+/*
+ * Assignment operator.
+ */
+InetAddress& InetAddress::operator=(const InetAddress& addr)
+{
+    // handle self-assignment
+    if (this == &addr)
+        return *this;
+    // copy mLength and mAddress
+    mLength = addr.mLength;
+    if (mLength > 0) {
+        mAddress = new char[mLength];
+        memcpy(mAddress, addr.mAddress, mLength);
+        LOG(LOG_DEBUG, "socket",
+            "HEY: copied %d bytes in assignment operator\n", mLength);
+    } else {
+        mAddress = NULL;
+    }
+    // copy mName
+    mName = new char[strlen(addr.mName)+1];
+    strcpy(mName, addr.mName);
+
+    return *this;
+}
+
+/*
+ * Create a new object from a name or a dotted-number IP notation.
+ *
+ * Returns NULL on failure.
+ */
+InetAddress*
+InetAddress::getByName(const char* host)
+{
+    InetAddress* newAddr = NULL;
+    struct sockaddr_in addr;
+    struct hostent* he;
+    DurationTimer hostTimer, lockTimer;
+
+    // gethostbyname() isn't reentrant, so we need to lock things until
+    // we can copy the data out.
+    lockTimer.start();
+    lock_gethostbyname();
+    hostTimer.start();
+
+    he = gethostbyname(host);
+    if (he == NULL) {
+        LOG(LOG_WARN, "socket", "WARNING: cannot resolve host %s\n", host);
+        unlock_gethostbyname();
+        return NULL;
+    }
+
+    memcpy(&addr.sin_addr, he->h_addr, he->h_length);
+    addr.sin_family = he->h_addrtype;
+    addr.sin_port = 0;
+
+    // got it, unlock us
+    hostTimer.stop();
+    he = NULL;
+    unlock_gethostbyname();
+
+    lockTimer.stop();
+    if ((long) lockTimer.durationUsecs() > 100000) {
+        long lockTime = (long) lockTimer.durationUsecs();
+        long hostTime = (long) hostTimer.durationUsecs();
+        LOG(LOG_DEBUG, "socket",
+            "Lookup of %s took %.3fs (gethostbyname=%.3fs lock=%.3fs)\n",
+            host, lockTime / 1000000.0, hostTime / 1000000.0,
+            (lockTime - hostTime) / 1000000.0);
+    }
+
+    // Alloc storage and copy it over.
+    newAddr = new InetAddress();
+    if (newAddr == NULL)
+        return NULL;
+
+    newAddr->mLength = sizeof(struct sockaddr_in);
+    newAddr->mAddress = new char[sizeof(struct sockaddr_in)];
+    if (newAddr->mAddress == NULL) {
+        delete newAddr;
+        return NULL;
+    }
+    memcpy(newAddr->mAddress, &addr, newAddr->mLength);
+
+    // Keep this for debug messages.
+    newAddr->mName = new char[strlen(host)+1];
+    if (newAddr->mName == NULL) {
+        delete newAddr;
+        return NULL;
+    }
+    strcpy(newAddr->mName, host);
+
+    return newAddr;
+}
+
+
+/*
+ * ===========================================================================
+ *      InetSocketAddress
+ * ===========================================================================
+ */
+
+/*
+ * Create an address with the host wildcard (INADDR_ANY).
+ */
+bool InetSocketAddress::create(int port)
+{
+    assert(mAddress == NULL);
+
+    mAddress = InetAddress::getByName("0.0.0.0");
+    if (mAddress == NULL)
+        return false;
+    mPort = port;
+    return true;
+}
+
+/*
+ * Create address with host and port specified.
+ */
+bool InetSocketAddress::create(const InetAddress* addr, int port)
+{
+    assert(mAddress == NULL);
+
+    mAddress = new InetAddress(*addr);  // make a copy
+    if (mAddress == NULL)
+        return false;
+    mPort = port;
+    return true;
+}
+
+/*
+ * Create address with host and port specified.
+ */
+bool InetSocketAddress::create(const char* host, int port)
+{
+    assert(mAddress == NULL);
+
+    mAddress = InetAddress::getByName(host);
+    if (mAddress == NULL)
+        return false;
+    mPort = port;
+    return true;
+}
+
diff --git a/libs/utils/LogSocket.cpp b/libs/utils/LogSocket.cpp
new file mode 100644
index 0000000..55c1b99
--- /dev/null
+++ b/libs/utils/LogSocket.cpp
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+
+#ifndef HAVE_WINSOCK
+//#define SOCKETLOG
+#endif
+
+#ifdef SOCKETLOG
+
+#define LOG_TAG "SOCKETLOG"
+
+#include <string.h>
+#include <cutils/log.h>
+#include "utils/LogSocket.h"
+#include "utils/logger.h"
+#include "cutils/hashmap.h"
+
+// defined in //device/data/etc/event-log-tags
+#define SOCKET_CLOSE_LOG 51000
+
+static Hashmap* statsMap = NULL;
+
+#define LOG_LIST_NUMBER 5
+
+typedef struct SocketStats {
+    int fd;
+    unsigned int send;
+    unsigned int recv;
+    unsigned int ip;
+    unsigned short port;
+    short reason;
+}SocketStats;
+
+SocketStats *get_socket_stats(int fd) {
+    if (statsMap == NULL) {
+        statsMap = hashmapCreate(8, &hashmapIntHash, &hashmapIntEquals);
+    }
+
+    SocketStats *s = (SocketStats*) hashmapGet(statsMap, &fd);
+    if (s == NULL) {
+        // LOGD("create SocketStats for fd %d", fd);
+        s = (SocketStats*) malloc(sizeof(SocketStats));
+        memset(s, 0, sizeof(SocketStats));
+        s->fd = fd;
+        hashmapPut(statsMap, &s->fd, s);
+    }
+    return s;
+}
+
+void log_socket_connect(int fd, unsigned int ip, unsigned short port) {
+    // LOGD("log_socket_connect for fd %d ip %d port%d", fd, ip, port);
+    SocketStats *s = get_socket_stats(fd);
+    s->ip = ip;
+    s->port = port;
+}
+
+void add_send_stats(int fd, int send) {
+    if (send <=0) {
+        LOGE("add_send_stats send %d", send);
+        return;
+    }
+    SocketStats *s = get_socket_stats(fd);
+    s->send += send;
+    // LOGD("add_send_stats for fd %d ip %d port%d", fd, s->ip, s->port);
+}
+
+void add_recv_stats(int fd, int recv) {
+    if (recv <=0) {
+        LOGE("add_recv_stats recv %d", recv);
+        return;
+    }
+    SocketStats *s = get_socket_stats(fd);
+    s->recv += recv;
+    // LOGD("add_recv_stats for fd %d ip %d port%d", fd, s->ip, s->port);
+}
+
+char* put_int(char* buf, int value) {
+    *buf = EVENT_TYPE_INT;
+    buf++;
+    memcpy(buf, &value, sizeof(int));
+    return buf + sizeof(int);
+}
+
+void log_socket_close(int fd, short reason) {
+    if (statsMap) {
+        SocketStats *s = (SocketStats*) hashmapGet(statsMap, &fd);
+        if (s != NULL) {
+            if (s->send != 0 || s->recv != 0) {
+                s->reason = reason;
+                // 5 int + list type need 2 bytes
+                char buf[LOG_LIST_NUMBER * 5 + 2];
+                buf[0] = EVENT_TYPE_LIST;
+                buf[1] = LOG_LIST_NUMBER;
+                char* writePos = buf + 2;
+                writePos = put_int(writePos, s->send);
+                writePos = put_int(writePos, s->recv);
+                writePos = put_int(writePos, s->ip);
+                writePos = put_int(writePos, s->port);
+                writePos = put_int(writePos, s->reason);
+                
+                android_bWriteLog(SOCKET_CLOSE_LOG, buf, sizeof(buf));
+                // LOGD("send %d recv %d reason %d", s->send, s->recv, s->reason);
+            }
+            hashmapRemove(statsMap, &s->fd);
+            free(s);
+        }
+    }
+}
+
+#else
+void add_send_stats(int fd, int send) {} 
+void add_recv_stats(int fd, int recv) {}
+void log_socket_close(int fd, short reason) {}
+void log_socket_connect(int fd, unsigned int ip, unsigned short port) {}
+#endif
diff --git a/libs/utils/MODULE_LICENSE_APACHE2 b/libs/utils/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/utils/MODULE_LICENSE_APACHE2
diff --git a/libs/utils/MemoryBase.cpp b/libs/utils/MemoryBase.cpp
new file mode 100644
index 0000000..f25e11c
--- /dev/null
+++ b/libs/utils/MemoryBase.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <utils/MemoryBase.h>
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+MemoryBase::MemoryBase(const sp<IMemoryHeap>& heap,
+        ssize_t offset, size_t size)
+    : mSize(size), mOffset(offset), mHeap(heap)
+{
+}
+
+sp<IMemoryHeap> MemoryBase::getMemory(ssize_t* offset, size_t* size) const
+{
+    if (offset) *offset = mOffset;
+    if (size)   *size = mSize;
+    return mHeap;
+}
+
+MemoryBase::~MemoryBase()
+{
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/utils/MemoryDealer.cpp b/libs/utils/MemoryDealer.cpp
new file mode 100644
index 0000000..cf8201b
--- /dev/null
+++ b/libs/utils/MemoryDealer.cpp
@@ -0,0 +1,409 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "MemoryDealer"
+
+#include <utils/MemoryDealer.h>
+
+#include <utils/Log.h>
+#include <utils/IPCThreadState.h>
+#include <utils/SortedVector.h>
+#include <utils/String8.h>
+#include <utils/MemoryBase.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/file.h>
+
+namespace android {
+
+
+// ----------------------------------------------------------------------------
+
+class SimpleMemory : public MemoryBase {
+public:
+    SimpleMemory(const sp<IMemoryHeap>& heap, ssize_t offset, size_t size);
+    virtual ~SimpleMemory();
+};
+
+
+// ----------------------------------------------------------------------------
+
+MemoryDealer::Allocation::Allocation(
+        const sp<MemoryDealer>& dealer, ssize_t offset, size_t size,
+        const sp<IMemory>& memory)
+    : mDealer(dealer), mOffset(offset), mSize(size), mMemory(memory) 
+{
+}
+
+MemoryDealer::Allocation::~Allocation()
+{
+    if (mSize) {
+        /* NOTE: it's VERY important to not free allocations of size 0 because
+         * they're special as they don't have any record in the allocator
+         * and could alias some real allocation (their offset is zero). */
+        mDealer->deallocate(mOffset);
+    }
+}
+
+sp<IMemoryHeap> MemoryDealer::Allocation::getMemory(
+    ssize_t* offset, size_t* size) const
+{
+    return mMemory->getMemory(offset, size);
+}
+
+// ----------------------------------------------------------------------------
+
+MemoryDealer::MemoryDealer(size_t size, uint32_t flags, const char* name)
+    : mHeap(new SharedHeap(size, flags, name)),
+    mAllocator(new SimpleBestFitAllocator(size))
+{    
+}
+
+MemoryDealer::MemoryDealer(const sp<HeapInterface>& heap)
+    : mHeap(heap),
+    mAllocator(new SimpleBestFitAllocator(heap->virtualSize()))
+{
+}
+
+MemoryDealer::MemoryDealer( const sp<HeapInterface>& heap,
+        const sp<AllocatorInterface>& allocator)
+    : mHeap(heap), mAllocator(allocator)
+{
+}
+
+MemoryDealer::~MemoryDealer()
+{
+}
+
+sp<IMemory> MemoryDealer::allocate(size_t size, uint32_t flags)
+{
+    sp<IMemory> memory;
+    const ssize_t offset = allocator()->allocate(size, flags);
+    if (offset >= 0) {
+        sp<IMemory> new_memory = heap()->mapMemory(offset, size);
+        if (new_memory != 0) {
+            memory = new Allocation(this, offset, size, new_memory);
+        } else {
+            LOGE("couldn't map [%8x, %d]", offset, size);
+            if (size) {
+                /* NOTE: it's VERY important to not free allocations of size 0
+                 * because they're special as they don't have any record in the 
+                 * allocator and could alias some real allocation 
+                 * (their offset is zero). */
+                allocator()->deallocate(offset);
+            }
+        }        
+    }
+    return memory;
+}
+
+void MemoryDealer::deallocate(size_t offset)
+{
+    allocator()->deallocate(offset);
+}
+
+void MemoryDealer::dump(const char* what, uint32_t flags) const
+{
+    allocator()->dump(what, flags);
+}
+
+const sp<HeapInterface>& MemoryDealer::heap() const {
+    return mHeap;
+}
+
+const sp<AllocatorInterface>& MemoryDealer::allocator() const {
+    return mAllocator;
+}
+
+// ----------------------------------------------------------------------------
+
+// align all the memory blocks on a cache-line boundary
+const int SimpleBestFitAllocator::kMemoryAlign = 32;
+
+SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size)
+{
+    size_t pagesize = getpagesize();
+    mHeapSize = ((size + pagesize-1) & ~(pagesize-1));
+
+    chunk_t* node = new chunk_t(0, mHeapSize / kMemoryAlign);
+    mList.insertHead(node);
+}
+
+SimpleBestFitAllocator::~SimpleBestFitAllocator()
+{
+    while(!mList.isEmpty()) {
+        delete mList.remove(mList.head());
+    }
+}
+
+size_t SimpleBestFitAllocator::size() const
+{
+    return mHeapSize;
+}
+
+size_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
+{
+    Mutex::Autolock _l(mLock);
+    ssize_t offset = alloc(size, flags);
+    return offset;
+}
+
+status_t SimpleBestFitAllocator::deallocate(size_t offset)
+{
+    Mutex::Autolock _l(mLock);
+    chunk_t const * const freed = dealloc(offset);
+    if (freed) {
+        return NO_ERROR;
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t SimpleBestFitAllocator::alloc(size_t size, uint32_t flags)
+{
+    if (size == 0) {
+        return 0;
+    }
+    size = (size + kMemoryAlign-1) / kMemoryAlign;
+    chunk_t* free_chunk = 0;
+    chunk_t* cur = mList.head();
+
+    size_t pagesize = getpagesize();
+    while (cur) {
+        int extra = 0;
+        if (flags & PAGE_ALIGNED)
+            extra = ( -cur->start & ((pagesize/kMemoryAlign)-1) ) ;
+
+        // best fit
+        if (cur->free && (cur->size >= (size+extra))) {
+            if ((!free_chunk) || (cur->size < free_chunk->size)) {
+                free_chunk = cur;
+            }
+            if (cur->size == size) {
+                break;
+            }
+        }
+        cur = cur->next;
+    }
+
+    if (free_chunk) {
+        const size_t free_size = free_chunk->size;
+        free_chunk->free = 0;
+        free_chunk->size = size;
+        if (free_size > size) {
+            int extra = 0;
+            if (flags & PAGE_ALIGNED)
+                extra = ( -free_chunk->start & ((pagesize/kMemoryAlign)-1) ) ;
+            if (extra) {
+                chunk_t* split = new chunk_t(free_chunk->start, extra);
+                free_chunk->start += extra;
+                mList.insertBefore(free_chunk, split);
+            }
+
+            LOGE_IF((flags&PAGE_ALIGNED) && 
+                    ((free_chunk->start*kMemoryAlign)&(pagesize-1)),
+                    "PAGE_ALIGNED requested, but page is not aligned!!!");
+
+            const ssize_t tail_free = free_size - (size+extra);
+            if (tail_free > 0) {
+                chunk_t* split = new chunk_t(
+                        free_chunk->start + free_chunk->size, tail_free);
+                mList.insertAfter(free_chunk, split);
+            }
+        }
+        return (free_chunk->start)*kMemoryAlign;
+    }
+    return NO_MEMORY;
+}
+
+SimpleBestFitAllocator::chunk_t* SimpleBestFitAllocator::dealloc(size_t start)
+{
+    start = start / kMemoryAlign;
+    chunk_t* cur = mList.head();
+    while (cur) {
+        if (cur->start == start) {
+            LOG_FATAL_IF(cur->free,
+                "block at offset 0x%08lX of size 0x%08lX already freed",
+                cur->start*kMemoryAlign, cur->size*kMemoryAlign);
+
+            // merge freed blocks together
+            chunk_t* freed = cur;
+            cur->free = 1;
+            do {
+                chunk_t* const p = cur->prev;
+                chunk_t* const n = cur->next;
+                if (p && (p->free || !cur->size)) {
+                    freed = p;
+                    p->size += cur->size;
+                    mList.remove(cur);
+                    delete cur;
+                }
+                cur = n;
+            } while (cur && cur->free);
+
+            #ifndef NDEBUG
+                if (!freed->free) {
+                    dump_l("dealloc (!freed->free)");
+                }
+            #endif
+            LOG_FATAL_IF(!freed->free,
+                "freed block at offset 0x%08lX of size 0x%08lX is not free!",
+                freed->start * kMemoryAlign, freed->size * kMemoryAlign);
+
+            return freed;
+        }
+        cur = cur->next;
+    }
+    return 0;
+}
+
+void SimpleBestFitAllocator::dump(const char* what, uint32_t flags) const
+{
+    Mutex::Autolock _l(mLock);
+    dump_l(what, flags);
+}
+
+void SimpleBestFitAllocator::dump_l(const char* what, uint32_t flags) const
+{
+    String8 result;
+    dump_l(result, what, flags);
+    LOGD("%s", result.string());
+}
+
+void SimpleBestFitAllocator::dump(String8& result,
+        const char* what, uint32_t flags) const
+{
+    Mutex::Autolock _l(mLock);
+    dump_l(result, what, flags);
+}
+
+void SimpleBestFitAllocator::dump_l(String8& result,
+        const char* what, uint32_t flags) const
+{
+    size_t size = 0;
+    int32_t i = 0;
+    chunk_t const* cur = mList.head();
+    
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    snprintf(buffer, SIZE, "  %s (%p, size=%u)\n",
+            what, this, (unsigned int)mHeapSize);
+    
+    result.append(buffer);
+            
+    while (cur) {
+        const char* errs[] = {"", "| link bogus NP",
+                            "| link bogus PN", "| link bogus NP+PN" };
+        int np = ((cur->next) && cur->next->prev != cur) ? 1 : 0;
+        int pn = ((cur->prev) && cur->prev->next != cur) ? 2 : 0;
+
+        snprintf(buffer, SIZE, "  %3u: %08x | 0x%08X | 0x%08X | %s %s\n",
+            i, int(cur), int(cur->start*kMemoryAlign),
+            int(cur->size*kMemoryAlign),
+                    int(cur->free) ? "F" : "A",
+                    errs[np|pn]);
+        
+        result.append(buffer);
+
+        if (!cur->free)
+            size += cur->size*kMemoryAlign;
+
+        i++;
+        cur = cur->next;
+    }
+    snprintf(buffer, SIZE, "  size allocated: %u (%u KB)\n", int(size), int(size/1024));
+    result.append(buffer);
+}
+        
+// ----------------------------------------------------------------------------
+
+
+SharedHeap::SharedHeap(size_t size, uint32_t flags, char const * name)
+    : MemoryHeapBase(size, flags, name)
+{
+}
+
+SharedHeap::~SharedHeap()
+{
+}
+
+sp<IMemory> SharedHeap::mapMemory(size_t offset, size_t size)
+{
+    return new SimpleMemory(this, offset, size);
+}
+ 
+
+SimpleMemory::SimpleMemory(const sp<IMemoryHeap>& heap,
+        ssize_t offset, size_t size)
+    : MemoryBase(heap, offset, size)
+{
+#ifndef NDEBUG
+    void* const start_ptr = (void*)(intptr_t(heap->base()) + offset);
+    memset(start_ptr, 0xda, size);
+#endif
+}
+
+SimpleMemory::~SimpleMemory()
+{
+    size_t freedOffset = getOffset();
+    size_t freedSize   = getSize();
+
+    // keep the size to unmap in excess
+    size_t pagesize = getpagesize();
+    size_t start = freedOffset;
+    size_t end = start + freedSize;
+    start &= ~(pagesize-1);
+    end = (end + pagesize-1) & ~(pagesize-1);
+
+    // give back to the kernel the pages we don't need
+    size_t free_start = freedOffset;
+    size_t free_end = free_start + freedSize;
+    if (start < free_start)
+        start = free_start;
+    if (end > free_end)
+        end = free_end;
+    start = (start + pagesize-1) & ~(pagesize-1);
+    end &= ~(pagesize-1);    
+
+    if (start < end) {
+        void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + start);
+        size_t size = end-start;
+
+#ifndef NDEBUG
+        memset(start_ptr, 0xdf, size);
+#endif
+
+        // MADV_REMOVE is not defined on Dapper based Goobuntu 
+#ifdef MADV_REMOVE 
+        if (size) {
+            int err = madvise(start_ptr, size, MADV_REMOVE);
+            LOGW_IF(err, "madvise(%p, %u, MADV_REMOVE) returned %s",
+                    start_ptr, size, err<0 ? strerror(errno) : "Ok");
+        }
+#endif
+    }
+}
+
+}; // namespace android
diff --git a/libs/utils/MemoryHeapBase.cpp b/libs/utils/MemoryHeapBase.cpp
new file mode 100644
index 0000000..8251728
--- /dev/null
+++ b/libs/utils/MemoryHeapBase.cpp
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "MemoryHeapBase"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/ashmem.h>
+#include <cutils/atomic.h>
+
+#include <utils/MemoryHeapBase.h>
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+MemoryHeapBase::MemoryHeapBase() 
+    : mFD(-1), mSize(0), mBase(MAP_FAILED),
+      mDevice(NULL), mNeedUnmap(false) 
+{
+}
+
+MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name)
+    : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
+      mDevice(0), mNeedUnmap(false)
+{
+    const size_t pagesize = getpagesize();
+    size = ((size + pagesize-1) & ~(pagesize-1));
+    int fd = ashmem_create_region(name == NULL ? "MemoryHeapBase" : name, size);
+    LOGE_IF(fd<0, "error creating ashmem region: %s", strerror(errno));
+    if (fd >= 0) {
+        if (mapfd(fd, size) == NO_ERROR) {
+            if (flags & READ_ONLY) {
+                ashmem_set_prot_region(fd, PROT_READ);
+            }
+        }
+    }
+}
+
+MemoryHeapBase::MemoryHeapBase(const char* device, size_t size, uint32_t flags)
+    : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
+      mDevice(0), mNeedUnmap(false)
+{
+    int fd = open(device, O_RDWR);
+    LOGE_IF(fd<0, "error opening %s: %s", device, strerror(errno));
+    if (fd >= 0) {
+        const size_t pagesize = getpagesize();
+        size = ((size + pagesize-1) & ~(pagesize-1));
+        if (mapfd(fd, size) == NO_ERROR) {
+            mDevice = device;
+        }
+    }
+}
+
+MemoryHeapBase::MemoryHeapBase(int fd, size_t size, uint32_t flags)
+    : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
+      mDevice(0), mNeedUnmap(false)
+{
+    const size_t pagesize = getpagesize();
+    size = ((size + pagesize-1) & ~(pagesize-1));
+    mapfd(dup(fd), size);
+}
+
+status_t MemoryHeapBase::init(int fd, void *base, int size, int flags, const char* device)
+{
+    if (mFD != -1) {
+        return INVALID_OPERATION;
+    }
+    mFD = fd;
+    mBase = base;
+    mSize = size;
+    mFlags = flags;
+    mDevice = device;
+    return NO_ERROR;
+}
+
+status_t MemoryHeapBase::mapfd(int fd, size_t size)
+{
+    if (size == 0) {
+        // try to figure out the size automatically
+#if HAVE_ANDROID_OS
+        // first try the PMEM ioctl
+        pmem_region reg;
+        int err = ioctl(fd, PMEM_GET_TOTAL_SIZE, &reg);
+        if (err == 0)
+            size = reg.len;
+#endif
+        if (size == 0) { // try fstat
+            struct stat sb;
+            if (fstat(fd, &sb) == 0)
+                size = sb.st_size;
+        }
+        // if it didn't work, let mmap() fail.
+    }
+
+    if ((mFlags & DONT_MAP_LOCALLY) == 0) {
+        void* base = (uint8_t*)mmap(0, size,
+                PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+        if (base == MAP_FAILED) {
+            LOGE("mmap(fd=%d, size=%u) failed (%s)",
+                    fd, uint32_t(size), strerror(errno));
+            close(fd);
+            return -errno;
+        }
+        //LOGD("mmap(fd=%d, base=%p, size=%lu)", fd, base, size);
+        mBase = base;
+        mNeedUnmap = true;
+    } else  {
+        mBase = 0; // not MAP_FAILED
+        mNeedUnmap = false;
+    }
+    mFD = fd;
+    mSize = size;
+    return NO_ERROR;
+}
+
+MemoryHeapBase::~MemoryHeapBase()
+{
+    dispose();
+}
+
+void MemoryHeapBase::dispose()
+{
+    int fd = android_atomic_or(-1, &mFD);
+    if (fd >= 0) {
+        if (mNeedUnmap) {
+            //LOGD("munmap(fd=%d, base=%p, size=%lu)", fd, mBase, mSize);
+            munmap(mBase, mSize);
+        }
+        mBase = 0;
+        mSize = 0;
+        close(fd);
+    }
+}
+
+int MemoryHeapBase::getHeapID() const {
+    return mFD;
+}
+
+void* MemoryHeapBase::getBase() const {
+    return mBase;
+}
+
+size_t MemoryHeapBase::getSize() const {
+    return mSize;
+}
+
+uint32_t MemoryHeapBase::getFlags() const {
+    return mFlags;
+}
+
+const char* MemoryHeapBase::getDevice() const {
+    return mDevice;
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/utils/MemoryHeapPmem.cpp b/libs/utils/MemoryHeapPmem.cpp
new file mode 100644
index 0000000..eba2b30
--- /dev/null
+++ b/libs/utils/MemoryHeapPmem.cpp
@@ -0,0 +1,248 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "MemoryHeapPmem"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+
+#include <utils/MemoryHeapPmem.h>
+#include <utils/MemoryHeapBase.h>
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+MemoryHeapPmem::MemoryPmem::MemoryPmem(const sp<MemoryHeapPmem>& heap)
+    : BnMemory(), mClientHeap(heap)
+{
+}
+
+MemoryHeapPmem::MemoryPmem::~MemoryPmem() {
+    if (mClientHeap != NULL) {
+        mClientHeap->remove(this);
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+class SubRegionMemory : public MemoryHeapPmem::MemoryPmem {
+public:
+    SubRegionMemory(const sp<MemoryHeapPmem>& heap, ssize_t offset, size_t size);
+    virtual ~SubRegionMemory();
+    virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
+private:
+    friend class MemoryHeapPmem;
+    void revoke();
+    size_t              mSize;
+    ssize_t             mOffset;
+};
+
+SubRegionMemory::SubRegionMemory(const sp<MemoryHeapPmem>& heap,
+        ssize_t offset, size_t size)
+    : MemoryHeapPmem::MemoryPmem(heap), mSize(size), mOffset(offset)
+{
+#ifndef NDEBUG
+    void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + offset);
+    memset(start_ptr, 0xda, size);
+#endif
+
+#if HAVE_ANDROID_OS
+    if (size > 0) {
+        const size_t pagesize = getpagesize();
+        size = (size + pagesize-1) & ~(pagesize-1);
+        int our_fd = heap->heapID();
+        struct pmem_region sub = { offset, size };
+        int err = ioctl(our_fd, PMEM_MAP, &sub);
+        LOGE_IF(err<0, "PMEM_MAP failed (%s), "
+                "mFD=%d, sub.offset=%lu, sub.size=%lu",
+                strerror(errno), our_fd, sub.offset, sub.len);
+}
+#endif
+}
+
+sp<IMemoryHeap> SubRegionMemory::getMemory(ssize_t* offset, size_t* size) const
+{
+    if (offset) *offset = mOffset;
+    if (size)   *size = mSize;
+    return getHeap();
+}
+
+SubRegionMemory::~SubRegionMemory()
+{
+    revoke();
+}
+
+
+void SubRegionMemory::revoke()
+{
+    // NOTE: revoke() doesn't need to be protected by a lock because it
+    // can only be called from MemoryHeapPmem::revoke(), which means
+    // that we can't be in ~SubRegionMemory(), or in ~SubRegionMemory(),
+    // which means MemoryHeapPmem::revoke() wouldn't have been able to 
+    // promote() it.
+    
+#if HAVE_ANDROID_OS
+    if (mSize != NULL) {
+        const sp<MemoryHeapPmem>& heap(getHeap());
+        int our_fd = heap->heapID();
+        struct pmem_region sub;
+        sub.offset = mOffset;
+        sub.len = mSize;
+        int err = ioctl(our_fd, PMEM_UNMAP, &sub);
+        LOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
+                "mFD=%d, sub.offset=%lu, sub.size=%lu",
+                strerror(errno), our_fd, sub.offset, sub.len);
+        mSize = 0;
+    }
+#endif
+}
+
+// ---------------------------------------------------------------------------
+
+MemoryHeapPmem::MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap,
+        uint32_t flags)
+    : HeapInterface(), MemoryHeapBase()
+{
+    char const * const device = pmemHeap->getDevice();
+#if HAVE_ANDROID_OS
+    if (device) {
+        int fd = open(device, O_RDWR);
+        LOGE_IF(fd<0, "couldn't open %s (%s)", device, strerror(errno));
+        if (fd >= 0) {
+            int err = ioctl(fd, PMEM_CONNECT, pmemHeap->heapID());
+            if (err < 0) {
+                LOGE("PMEM_CONNECT failed (%s), mFD=%d, sub-fd=%d",
+                        strerror(errno), fd, pmemHeap->heapID());
+                close(fd);
+            } else {
+                // everything went well...
+                mParentHeap = pmemHeap;
+                MemoryHeapBase::init(fd, 
+                        pmemHeap->getBase(),
+                        pmemHeap->getSize(),
+                        pmemHeap->getFlags() | flags,
+                        device);
+            }
+        }
+    }
+#else
+    mParentHeap = pmemHeap;
+    MemoryHeapBase::init( 
+            dup(pmemHeap->heapID()),
+            pmemHeap->getBase(),
+            pmemHeap->getSize(),
+            pmemHeap->getFlags() | flags,
+            device);
+#endif
+}
+
+MemoryHeapPmem::~MemoryHeapPmem()
+{
+}
+
+sp<IMemory> MemoryHeapPmem::mapMemory(size_t offset, size_t size)
+{
+    sp<MemoryPmem> memory = createMemory(offset, size);
+    if (memory != 0) {
+        Mutex::Autolock _l(mLock);
+        mAllocations.add(memory);
+    }
+    return memory;
+}
+
+sp<MemoryHeapPmem::MemoryPmem> MemoryHeapPmem::createMemory(
+        size_t offset, size_t size)
+{
+    sp<SubRegionMemory> memory;
+    if (heapID() > 0) 
+        memory = new SubRegionMemory(this, offset, size);
+    return memory;
+}
+
+status_t MemoryHeapPmem::slap()
+{
+#if HAVE_ANDROID_OS
+    size_t size = getSize();
+    const size_t pagesize = getpagesize();
+    size = (size + pagesize-1) & ~(pagesize-1);
+    int our_fd = getHeapID();
+    struct pmem_region sub = { 0, size };
+    int err = ioctl(our_fd, PMEM_MAP, &sub);
+    LOGE_IF(err<0, "PMEM_MAP failed (%s), "
+            "mFD=%d, sub.offset=%lu, sub.size=%lu",
+            strerror(errno), our_fd, sub.offset, sub.len);
+    return -errno;
+#else
+    return NO_ERROR;
+#endif
+}
+
+status_t MemoryHeapPmem::unslap()
+{
+#if HAVE_ANDROID_OS
+    size_t size = getSize();
+    const size_t pagesize = getpagesize();
+    size = (size + pagesize-1) & ~(pagesize-1);
+    int our_fd = getHeapID();
+    struct pmem_region sub = { 0, size };
+    int err = ioctl(our_fd, PMEM_UNMAP, &sub);
+    LOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
+            "mFD=%d, sub.offset=%lu, sub.size=%lu",
+            strerror(errno), our_fd, sub.offset, sub.len);
+    return -errno;
+#else
+    return NO_ERROR;
+#endif
+}
+
+void MemoryHeapPmem::revoke()
+{
+    SortedVector< wp<MemoryPmem> > allocations;
+
+    { // scope for lock
+        Mutex::Autolock _l(mLock);
+        allocations = mAllocations;
+    }
+    
+    ssize_t count = allocations.size();
+    for (ssize_t i=0 ; i<count ; i++) {
+        sp<MemoryPmem> memory(allocations[i].promote());
+        if (memory != 0)
+            memory->revoke();
+    }
+}
+
+void MemoryHeapPmem::remove(const wp<MemoryPmem>& memory)
+{
+    Mutex::Autolock _l(mLock);
+    mAllocations.remove(memory);
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/utils/NOTICE b/libs/utils/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/libs/utils/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/libs/utils/Parcel.cpp b/libs/utils/Parcel.cpp
new file mode 100644
index 0000000..0f4b647
--- /dev/null
+++ b/libs/utils/Parcel.cpp
@@ -0,0 +1,1377 @@
+/*
+ * Copyright (C) 2005 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 "Parcel"
+//#define LOG_NDEBUG 0
+
+#include <utils/Parcel.h>
+
+#include <utils/Binder.h>
+#include <utils/BpBinder.h>
+#include <utils/Debug.h>
+#include <utils/ProcessState.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+#include <utils/TextOutput.h>
+#include <utils/misc.h>
+
+#include <private/utils/binder_module.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#ifndef INT32_MAX
+#define INT32_MAX ((int32_t)(2147483647))
+#endif
+
+#define LOG_REFS(...)
+//#define LOG_REFS(...) LOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
+
+// ---------------------------------------------------------------------------
+
+#define PAD_SIZE(s) (((s)+3)&~3)
+
+// XXX This can be made public if we want to provide
+// support for typed data.
+struct small_flat_data
+{
+    uint32_t type;
+    uint32_t data;
+};
+
+namespace android {
+
+void acquire_object(const sp<ProcessState>& proc,
+    const flat_binder_object& obj, const void* who)
+{
+    switch (obj.type) {
+        case BINDER_TYPE_BINDER:
+            if (obj.binder) {
+                LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
+                static_cast<IBinder*>(obj.cookie)->incStrong(who);
+            }
+            return;
+        case BINDER_TYPE_WEAK_BINDER:
+            if (obj.binder)
+                static_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
+            return;
+        case BINDER_TYPE_HANDLE: {
+            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
+            if (b != NULL) {
+                LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
+                b->incStrong(who);
+            }
+            return;
+        }
+        case BINDER_TYPE_WEAK_HANDLE: {
+            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
+            if (b != NULL) b.get_refs()->incWeak(who);
+            return;
+        }
+        case BINDER_TYPE_FD: {
+            // intentionally blank -- nothing to do to acquire this, but we do
+            // recognize it as a legitimate object type.
+            return;
+        }
+    }
+
+    LOGD("Invalid object type 0x%08lx", obj.type);
+}
+
+void release_object(const sp<ProcessState>& proc,
+    const flat_binder_object& obj, const void* who)
+{
+    switch (obj.type) {
+        case BINDER_TYPE_BINDER:
+            if (obj.binder) {
+                LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
+                static_cast<IBinder*>(obj.cookie)->decStrong(who);
+            }
+            return;
+        case BINDER_TYPE_WEAK_BINDER:
+            if (obj.binder)
+                static_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
+            return;
+        case BINDER_TYPE_HANDLE: {
+            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
+            if (b != NULL) {
+                LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
+                b->decStrong(who);
+            }
+            return;
+        }
+        case BINDER_TYPE_WEAK_HANDLE: {
+            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
+            if (b != NULL) b.get_refs()->decWeak(who);
+            return;
+        }
+        case BINDER_TYPE_FD: {
+            if (obj.cookie != (void*)0) close(obj.handle);
+            return;
+        }
+    }
+
+    LOGE("Invalid object type 0x%08lx", obj.type);
+}
+
+inline static status_t finish_flatten_binder(
+    const sp<IBinder>& binder, const flat_binder_object& flat, Parcel* out)
+{
+    return out->writeObject(flat, false);
+}
+
+status_t flatten_binder(const sp<ProcessState>& proc,
+    const sp<IBinder>& binder, Parcel* out)
+{
+    flat_binder_object obj;
+    
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    if (binder != NULL) {
+        IBinder *local = binder->localBinder();
+        if (!local) {
+            BpBinder *proxy = binder->remoteBinder();
+            if (proxy == NULL) {
+                LOGE("null proxy");
+            }
+            const int32_t handle = proxy ? proxy->handle() : 0;
+            obj.type = BINDER_TYPE_HANDLE;
+            obj.handle = handle;
+            obj.cookie = NULL;
+        } else {
+            obj.type = BINDER_TYPE_BINDER;
+            obj.binder = local->getWeakRefs();
+            obj.cookie = local;
+        }
+    } else {
+        obj.type = BINDER_TYPE_BINDER;
+        obj.binder = NULL;
+        obj.cookie = NULL;
+    }
+    
+    return finish_flatten_binder(binder, obj, out);
+}
+
+status_t flatten_binder(const sp<ProcessState>& proc,
+    const wp<IBinder>& binder, Parcel* out)
+{
+    flat_binder_object obj;
+    
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    if (binder != NULL) {
+        sp<IBinder> real = binder.promote();
+        if (real != NULL) {
+            IBinder *local = real->localBinder();
+            if (!local) {
+                BpBinder *proxy = real->remoteBinder();
+                if (proxy == NULL) {
+                    LOGE("null proxy");
+                }
+                const int32_t handle = proxy ? proxy->handle() : 0;
+                obj.type = BINDER_TYPE_WEAK_HANDLE;
+                obj.handle = handle;
+                obj.cookie = NULL;
+            } else {
+                obj.type = BINDER_TYPE_WEAK_BINDER;
+                obj.binder = binder.get_refs();
+                obj.cookie = binder.unsafe_get();
+            }
+            return finish_flatten_binder(real, obj, out);
+        }
+        
+        // XXX How to deal?  In order to flatten the given binder,
+        // we need to probe it for information, which requires a primary
+        // reference...  but we don't have one.
+        //
+        // The OpenBinder implementation uses a dynamic_cast<> here,
+        // but we can't do that with the different reference counting
+        // implementation we are using.
+        LOGE("Unable to unflatten Binder weak reference!");
+        obj.type = BINDER_TYPE_BINDER;
+        obj.binder = NULL;
+        obj.cookie = NULL;
+        return finish_flatten_binder(NULL, obj, out);
+    
+    } else {
+        obj.type = BINDER_TYPE_BINDER;
+        obj.binder = NULL;
+        obj.cookie = NULL;
+        return finish_flatten_binder(NULL, obj, out);
+    }
+}
+
+inline static status_t finish_unflatten_binder(
+    BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)
+{
+    return NO_ERROR;
+}
+    
+status_t unflatten_binder(const sp<ProcessState>& proc,
+    const Parcel& in, sp<IBinder>* out)
+{
+    const flat_binder_object* flat = in.readObject(false);
+    
+    if (flat) {
+        switch (flat->type) {
+            case BINDER_TYPE_BINDER:
+                *out = static_cast<IBinder*>(flat->cookie);
+                return finish_unflatten_binder(NULL, *flat, in);
+            case BINDER_TYPE_HANDLE:
+                *out = proc->getStrongProxyForHandle(flat->handle);
+                return finish_unflatten_binder(
+                    static_cast<BpBinder*>(out->get()), *flat, in);
+        }        
+    }
+    return BAD_TYPE;
+}
+
+status_t unflatten_binder(const sp<ProcessState>& proc,
+    const Parcel& in, wp<IBinder>* out)
+{
+    const flat_binder_object* flat = in.readObject(false);
+    
+    if (flat) {
+        switch (flat->type) {
+            case BINDER_TYPE_BINDER:
+                *out = static_cast<IBinder*>(flat->cookie);
+                return finish_unflatten_binder(NULL, *flat, in);
+            case BINDER_TYPE_WEAK_BINDER:
+                if (flat->binder != NULL) {
+                    out->set_object_and_refs(
+                        static_cast<IBinder*>(flat->cookie),
+                        static_cast<RefBase::weakref_type*>(flat->binder));
+                } else {
+                    *out = NULL;
+                }
+                return finish_unflatten_binder(NULL, *flat, in);
+            case BINDER_TYPE_HANDLE:
+            case BINDER_TYPE_WEAK_HANDLE:
+                *out = proc->getWeakProxyForHandle(flat->handle);
+                return finish_unflatten_binder(
+                    static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
+        }
+    }
+    return BAD_TYPE;
+}
+
+// ---------------------------------------------------------------------------
+
+Parcel::Parcel()
+{
+    initState();
+}
+
+Parcel::~Parcel()
+{
+    freeDataNoInit();
+}
+
+const uint8_t* Parcel::data() const
+{
+    return mData;
+}
+
+size_t Parcel::dataSize() const
+{
+    return (mDataSize > mDataPos ? mDataSize : mDataPos);
+}
+
+size_t Parcel::dataAvail() const
+{
+    // TODO: decide what to do about the possibility that this can
+    // report an available-data size that exceeds a Java int's max
+    // positive value, causing havoc.  Fortunately this will only
+    // happen if someone constructs a Parcel containing more than two
+    // gigabytes of data, which on typical phone hardware is simply
+    // not possible.
+    return dataSize() - dataPosition();
+}
+
+size_t Parcel::dataPosition() const
+{
+    return mDataPos;
+}
+
+size_t Parcel::dataCapacity() const
+{
+    return mDataCapacity;
+}
+
+status_t Parcel::setDataSize(size_t size)
+{
+    status_t err;
+    err = continueWrite(size);
+    if (err == NO_ERROR) {
+        mDataSize = size;
+        LOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
+    }
+    return err;
+}
+
+void Parcel::setDataPosition(size_t pos) const
+{
+    mDataPos = pos;
+    mNextObjectHint = 0;
+}
+
+status_t Parcel::setDataCapacity(size_t size)
+{
+    if (size > mDataSize) return continueWrite(size);
+    return NO_ERROR;
+}
+
+status_t Parcel::setData(const uint8_t* buffer, size_t len)
+{
+    status_t err = restartWrite(len);
+    if (err == NO_ERROR) {
+        memcpy(const_cast<uint8_t*>(data()), buffer, len);
+        mDataSize = len;
+        mFdsKnown = false;
+    }
+    return err;
+}
+
+status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
+{
+    const sp<ProcessState> proc(ProcessState::self());
+    status_t err;
+    uint8_t *data = parcel->mData;
+    size_t *objects = parcel->mObjects;
+    size_t size = parcel->mObjectsSize;
+    int startPos = mDataPos;
+    int firstIndex = -1, lastIndex = -2;
+
+    if (len == 0) {
+        return NO_ERROR;
+    }
+
+    // range checks against the source parcel size
+    if ((offset > parcel->mDataSize)
+            || (len > parcel->mDataSize)
+            || (offset + len > parcel->mDataSize)) {
+        return BAD_VALUE;
+    }
+
+    // Count objects in range
+    for (int i = 0; i < (int) size; i++) {
+        size_t off = objects[i];
+        if ((off >= offset) && (off < offset + len)) {
+            if (firstIndex == -1) {
+                firstIndex = i;
+            }
+            lastIndex = i;
+        }
+    }
+    int numObjects = lastIndex - firstIndex + 1;
+
+    // grow data
+    err = growData(len);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    // append data
+    memcpy(mData + mDataPos, data + offset, len);
+    mDataPos += len;
+    mDataSize += len;
+
+    if (numObjects > 0) {
+        // grow objects
+        if (mObjectsCapacity < mObjectsSize + numObjects) {
+            int newSize = ((mObjectsSize + numObjects)*3)/2;
+            size_t *objects =
+                (size_t*)realloc(mObjects, newSize*sizeof(size_t));
+            if (objects == (size_t*)0) {
+                return NO_MEMORY;
+            }
+            mObjects = objects;
+            mObjectsCapacity = newSize;
+        }
+        
+        // append and acquire objects
+        int idx = mObjectsSize;
+        for (int i = firstIndex; i <= lastIndex; i++) {
+            size_t off = objects[i] - offset + startPos;
+            mObjects[idx++] = off;
+            mObjectsSize++;
+
+            const flat_binder_object* flat
+                = reinterpret_cast<flat_binder_object*>(mData + off);
+            acquire_object(proc, *flat, this);
+
+            // take note if the object is a file descriptor
+            if (flat->type == BINDER_TYPE_FD) {
+                mHasFds = mFdsKnown = true;
+            }
+        }
+    }
+
+    return NO_ERROR;
+}
+
+bool Parcel::hasFileDescriptors() const
+{
+    if (!mFdsKnown) {
+        scanForFds();
+    }
+    return mHasFds;
+}
+
+status_t Parcel::writeInterfaceToken(const String16& interface)
+{
+    // currently the interface identification token is just its name as a string
+    return writeString16(interface);
+}
+
+bool Parcel::enforceInterface(const String16& interface) const
+{
+    String16 str = readString16();
+    if (str == interface) {
+        return true;
+    } else {
+        LOGW("**** enforceInterface() expected '%s' but read '%s'\n",
+                String8(interface).string(), String8(str).string());
+        return false;
+    }
+} 
+
+const size_t* Parcel::objects() const
+{
+    return mObjects;
+}
+
+size_t Parcel::objectsCount() const
+{
+    return mObjectsSize;
+}
+
+status_t Parcel::errorCheck() const
+{
+    return mError;
+}
+
+void Parcel::setError(status_t err)
+{
+    mError = err;
+}
+
+status_t Parcel::finishWrite(size_t len)
+{
+    //printf("Finish write of %d\n", len);
+    mDataPos += len;
+    LOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
+    if (mDataPos > mDataSize) {
+        mDataSize = mDataPos;
+        LOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
+    }
+    //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
+    return NO_ERROR;
+}
+
+status_t Parcel::writeUnpadded(const void* data, size_t len)
+{
+    size_t end = mDataPos + len;
+    if (end < mDataPos) {
+        // integer overflow
+        return BAD_VALUE;
+    }
+
+    if (end <= mDataCapacity) {
+restart_write:
+        memcpy(mData+mDataPos, data, len);
+        return finishWrite(len);
+    }
+
+    status_t err = growData(len);
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::write(const void* data, size_t len)
+{
+    void* const d = writeInplace(len);
+    if (d) {
+        memcpy(d, data, len);
+        return NO_ERROR;
+    }
+    return mError;
+}
+
+void* Parcel::writeInplace(size_t len)
+{
+    const size_t padded = PAD_SIZE(len);
+
+    // sanity check for integer overflow
+    if (mDataPos+padded < mDataPos) {
+        return NULL;
+    }
+
+    if ((mDataPos+padded) <= mDataCapacity) {
+restart_write:
+        //printf("Writing %ld bytes, padded to %ld\n", len, padded);
+        uint8_t* const data = mData+mDataPos;
+
+        // Need to pad at end?
+        if (padded != len) {
+#if BYTE_ORDER == BIG_ENDIAN
+            static const uint32_t mask[4] = {
+                0x00000000, 0xffffff00, 0xffff0000, 0xff000000
+            };
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN
+            static const uint32_t mask[4] = {
+                0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
+            };
+#endif
+            //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
+            //    *reinterpret_cast<void**>(data+padded-4));
+            *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
+        }
+
+        finishWrite(padded);
+        return data;
+    }
+
+    status_t err = growData(padded);
+    if (err == NO_ERROR) goto restart_write;
+    return NULL;
+}
+
+status_t Parcel::writeInt32(int32_t val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<int32_t*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeInt64(int64_t val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<int64_t*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeFloat(float val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<float*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeDouble(double val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<double*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeCString(const char* str)
+{
+    return write(str, strlen(str)+1);
+}
+
+status_t Parcel::writeString8(const String8& str)
+{
+    status_t err = writeInt32(str.bytes());
+    if (err == NO_ERROR) {
+        err = write(str.string(), str.bytes()+1);
+    }
+    return err;
+}
+
+status_t Parcel::writeString16(const String16& str)
+{
+    return writeString16(str.string(), str.size());
+}
+
+status_t Parcel::writeString16(const char16_t* str, size_t len)
+{
+    if (str == NULL) return writeInt32(-1);
+    
+    status_t err = writeInt32(len);
+    if (err == NO_ERROR) {
+        len *= sizeof(char16_t);
+        uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
+        if (data) {
+            memcpy(data, str, len);
+            *reinterpret_cast<char16_t*>(data+len) = 0;
+            return NO_ERROR;
+        }
+        err = mError;
+    }
+    return err;
+}
+
+status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
+{
+    return flatten_binder(ProcessState::self(), val, this);
+}
+
+status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
+{
+    return flatten_binder(ProcessState::self(), val, this);
+}
+
+status_t Parcel::writeNativeHandle(const native_handle& handle)
+{
+    if (handle.version != sizeof(native_handle))
+        return BAD_TYPE;
+
+    status_t err;
+    err = writeInt32(handle.numFds);
+    if (err != NO_ERROR) return err;
+
+    err = writeInt32(handle.numInts);
+    if (err != NO_ERROR) return err;
+
+    for (int i=0 ; err==NO_ERROR && i<handle.numFds ; i++)
+        err = writeDupFileDescriptor(handle.data[i]);
+
+    if (err != NO_ERROR) {
+        LOGD("write native handle, write dup fd failed");
+        return err;
+    }
+
+    err = write(handle.data + handle.numFds, sizeof(int)*handle.numInts);
+
+    return err;
+}
+
+status_t Parcel::writeFileDescriptor(int fd)
+{
+    flat_binder_object obj;
+    obj.type = BINDER_TYPE_FD;
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    obj.handle = fd;
+    obj.cookie = (void*)0;
+    return writeObject(obj, true);
+}
+
+status_t Parcel::writeDupFileDescriptor(int fd)
+{
+    flat_binder_object obj;
+    obj.type = BINDER_TYPE_FD;
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    obj.handle = dup(fd);
+    obj.cookie = (void*)1;
+    return writeObject(obj, true);
+}
+
+status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
+{
+    const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
+    const bool enoughObjects = mObjectsSize < mObjectsCapacity;
+    if (enoughData && enoughObjects) {
+restart_write:
+        *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
+        
+        // Need to write meta-data?
+        if (nullMetaData || val.binder != NULL) {
+            mObjects[mObjectsSize] = mDataPos;
+            acquire_object(ProcessState::self(), val, this);
+            mObjectsSize++;
+        }
+        
+        // remember if it's a file descriptor
+        if (val.type == BINDER_TYPE_FD) {
+            mHasFds = mFdsKnown = true;
+        }
+
+        return finishWrite(sizeof(flat_binder_object));
+    }
+
+    if (!enoughData) {
+        const status_t err = growData(sizeof(val));
+        if (err != NO_ERROR) return err;
+    }
+    if (!enoughObjects) {
+        size_t newSize = ((mObjectsSize+2)*3)/2;
+        size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
+        if (objects == NULL) return NO_MEMORY;
+        mObjects = objects;
+        mObjectsCapacity = newSize;
+    }
+    
+    goto restart_write;
+}
+
+
+void Parcel::remove(size_t start, size_t amt)
+{
+    LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
+}
+
+status_t Parcel::read(void* outData, size_t len) const
+{
+    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
+        memcpy(outData, mData+mDataPos, len);
+        mDataPos += PAD_SIZE(len);
+        LOGV("read Setting data pos of %p to %d\n", this, mDataPos);
+        return NO_ERROR;
+    }
+    return NOT_ENOUGH_DATA;
+}
+
+const void* Parcel::readInplace(size_t len) const
+{
+    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += PAD_SIZE(len);
+        LOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
+        return data;
+    }
+    return NULL;
+}
+
+status_t Parcel::readInt32(int32_t *pArg) const
+{
+    if ((mDataPos+sizeof(int32_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int32_t);
+        *pArg =  *reinterpret_cast<const int32_t*>(data);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+int32_t Parcel::readInt32() const
+{
+    if ((mDataPos+sizeof(int32_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int32_t);
+        LOGV("readInt32 Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const int32_t*>(data);
+    }
+    return 0;
+}
+
+
+status_t Parcel::readInt64(int64_t *pArg) const
+{
+    if ((mDataPos+sizeof(int64_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int64_t);
+        *pArg = *reinterpret_cast<const int64_t*>(data);
+        LOGV("readInt64 Setting data pos of %p to %d\n", this, mDataPos);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+
+int64_t Parcel::readInt64() const
+{
+    if ((mDataPos+sizeof(int64_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int64_t);
+        LOGV("readInt64 Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const int64_t*>(data);
+    }
+    return 0;
+}
+
+status_t Parcel::readFloat(float *pArg) const
+{
+    if ((mDataPos+sizeof(float)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(float);
+        LOGV("readFloat Setting data pos of %p to %d\n", this, mDataPos);
+        *pArg = *reinterpret_cast<const float*>(data);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+
+float Parcel::readFloat() const
+{
+    if ((mDataPos+sizeof(float)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(float);
+        LOGV("readFloat Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const float*>(data);
+    }
+    return 0;
+}
+
+status_t Parcel::readDouble(double *pArg) const
+{
+    if ((mDataPos+sizeof(double)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(double);
+        LOGV("readDouble Setting data pos of %p to %d\n", this, mDataPos);
+        *pArg = *reinterpret_cast<const double*>(data);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+
+double Parcel::readDouble() const
+{
+    if ((mDataPos+sizeof(double)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(double);
+        LOGV("readDouble Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const double*>(data);
+    }
+    return 0;
+}
+
+
+const char* Parcel::readCString() const
+{
+    const size_t avail = mDataSize-mDataPos;
+    if (avail > 0) {
+        const char* str = reinterpret_cast<const char*>(mData+mDataPos);
+        // is the string's trailing NUL within the parcel's valid bounds?
+        const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
+        if (eos) {
+            const size_t len = eos - str;
+            mDataPos += PAD_SIZE(len+1);
+            LOGV("readCString Setting data pos of %p to %d\n", this, mDataPos);
+            return str;
+        }
+    }
+    return NULL;
+}
+
+String8 Parcel::readString8() const
+{
+    int32_t size = readInt32();
+    // watch for potential int overflow adding 1 for trailing NUL
+    if (size > 0 && size < INT32_MAX) {
+        const char* str = (const char*)readInplace(size+1);
+        if (str) return String8(str, size);
+    }
+    return String8();
+}
+
+String16 Parcel::readString16() const
+{
+    size_t len;
+    const char16_t* str = readString16Inplace(&len);
+    if (str) return String16(str, len);
+    LOGE("Reading a NULL string not supported here.");
+    return String16();
+}
+
+const char16_t* Parcel::readString16Inplace(size_t* outLen) const
+{
+    int32_t size = readInt32();
+    // watch for potential int overflow from size+1
+    if (size >= 0 && size < INT32_MAX) {
+        *outLen = size;
+        const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
+        if (str != NULL) {
+            return str;
+        }
+    }
+    *outLen = 0;
+    return NULL;
+}
+
+sp<IBinder> Parcel::readStrongBinder() const
+{
+    sp<IBinder> val;
+    unflatten_binder(ProcessState::self(), *this, &val);
+    return val;
+}
+
+wp<IBinder> Parcel::readWeakBinder() const
+{
+    wp<IBinder> val;
+    unflatten_binder(ProcessState::self(), *this, &val);
+    return val;
+}
+
+
+native_handle* Parcel::readNativeHandle(native_handle* (*alloc)(void*, int, int), void* cookie) const
+{
+    int numFds, numInts;
+    status_t err;
+    err = readInt32(&numFds);
+    if (err != NO_ERROR) return 0;
+    err = readInt32(&numInts);
+    if (err != NO_ERROR) return 0;
+
+    native_handle* h;
+    if (alloc == 0) {
+        size_t size = sizeof(native_handle) + sizeof(int)*(numFds + numInts);
+        h = (native_handle*)malloc(size); 
+        h->version = sizeof(native_handle);
+        h->numFds = numFds;
+        h->numInts = numInts;
+    } else {
+        h = alloc(cookie, numFds, numInts);
+        if (h->version != sizeof(native_handle)) {
+            return 0;
+        }
+    }
+    
+    for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
+        h->data[i] = dup(readFileDescriptor());
+        if (h->data[i] < 0) err = BAD_VALUE;
+    }
+    
+    err = read(h->data + numFds, sizeof(int)*numInts);
+    
+    if (err != NO_ERROR) {
+        if (alloc == 0) {
+            free(h);
+        }
+        h = 0;
+    }
+    return h;
+}
+
+
+int Parcel::readFileDescriptor() const
+{
+    const flat_binder_object* flat = readObject(true);
+    if (flat) {
+        switch (flat->type) {
+            case BINDER_TYPE_FD:
+                //LOGI("Returning file descriptor %ld from parcel %p\n", flat->handle, this);
+                return flat->handle;
+        }        
+    }
+    return BAD_TYPE;
+}
+
+const flat_binder_object* Parcel::readObject(bool nullMetaData) const
+{
+    const size_t DPOS = mDataPos;
+    if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
+        const flat_binder_object* obj
+                = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
+        mDataPos = DPOS + sizeof(flat_binder_object);
+        if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {
+            // When transferring a NULL object, we don't write it into
+            // the object list, so we don't want to check for it when
+            // reading.
+            LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+            return obj;
+        }
+        
+        // Ensure that this object is valid...
+        size_t* const OBJS = mObjects;
+        const size_t N = mObjectsSize;
+        size_t opos = mNextObjectHint;
+        
+        if (N > 0) {
+            LOGV("Parcel %p looking for obj at %d, hint=%d\n",
+                 this, DPOS, opos);
+            
+            // Start at the current hint position, looking for an object at
+            // the current data position.
+            if (opos < N) {
+                while (opos < (N-1) && OBJS[opos] < DPOS) {
+                    opos++;
+                }
+            } else {
+                opos = N-1;
+            }
+            if (OBJS[opos] == DPOS) {
+                // Found it!
+                LOGV("Parcel found obj %d at index %d with forward search",
+                     this, DPOS, opos);
+                mNextObjectHint = opos+1;
+                LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+                return obj;
+            }
+        
+            // Look backwards for it...
+            while (opos > 0 && OBJS[opos] > DPOS) {
+                opos--;
+            }
+            if (OBJS[opos] == DPOS) {
+                // Found it!
+                LOGV("Parcel found obj %d at index %d with backward search",
+                     this, DPOS, opos);
+                mNextObjectHint = opos+1;
+                LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+                return obj;
+            }
+        }
+        LOGW("Attempt to read object from Parcel %p at offset %d that is not in the object list",
+             this, DPOS);
+    }
+    return NULL;
+}
+
+void Parcel::closeFileDescriptors()
+{
+    size_t i = mObjectsSize;
+    if (i > 0) {
+        //LOGI("Closing file descriptors for %d objects...", mObjectsSize);
+    }
+    while (i > 0) {
+        i--;
+        const flat_binder_object* flat
+            = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
+        if (flat->type == BINDER_TYPE_FD) {
+            //LOGI("Closing fd: %ld\n", flat->handle);
+            close(flat->handle);
+        }
+    }
+}
+
+const uint8_t* Parcel::ipcData() const
+{
+    return mData;
+}
+
+size_t Parcel::ipcDataSize() const
+{
+    return (mDataSize > mDataPos ? mDataSize : mDataPos);
+}
+
+const size_t* Parcel::ipcObjects() const
+{
+    return mObjects;
+}
+
+size_t Parcel::ipcObjectsCount() const
+{
+    return mObjectsSize;
+}
+
+void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
+    const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
+{
+    freeDataNoInit();
+    mError = NO_ERROR;
+    mData = const_cast<uint8_t*>(data);
+    mDataSize = mDataCapacity = dataSize;
+    //LOGI("setDataReference Setting data size of %p to %lu (pid=%d)\n", this, mDataSize, getpid());
+    mDataPos = 0;
+    LOGV("setDataReference Setting data pos of %p to %d\n", this, mDataPos);
+    mObjects = const_cast<size_t*>(objects);
+    mObjectsSize = mObjectsCapacity = objectsCount;
+    mNextObjectHint = 0;
+    mOwner = relFunc;
+    mOwnerCookie = relCookie;
+    scanForFds();
+}
+
+void Parcel::print(TextOutput& to, uint32_t flags) const
+{
+    to << "Parcel(";
+    
+    if (errorCheck() != NO_ERROR) {
+        const status_t err = errorCheck();
+        to << "Error: " << (void*)err << " \"" << strerror(-err) << "\"";
+    } else if (dataSize() > 0) {
+        const uint8_t* DATA = data();
+        to << indent << HexDump(DATA, dataSize()) << dedent;
+        const size_t* OBJS = objects();
+        const size_t N = objectsCount();
+        for (size_t i=0; i<N; i++) {
+            const flat_binder_object* flat
+                = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
+            to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
+                << TypeCode(flat->type & 0x7f7f7f00)
+                << " = " << flat->binder;
+        }
+    } else {
+        to << "NULL";
+    }
+    
+    to << ")";
+}
+
+void Parcel::releaseObjects()
+{
+    const sp<ProcessState> proc(ProcessState::self());
+    size_t i = mObjectsSize;
+    uint8_t* const data = mData;
+    size_t* const objects = mObjects;
+    while (i > 0) {
+        i--;
+        const flat_binder_object* flat
+            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
+        release_object(proc, *flat, this);
+    }
+}
+
+void Parcel::acquireObjects()
+{
+    const sp<ProcessState> proc(ProcessState::self());
+    size_t i = mObjectsSize;
+    uint8_t* const data = mData;
+    size_t* const objects = mObjects;
+    while (i > 0) {
+        i--;
+        const flat_binder_object* flat
+            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
+        acquire_object(proc, *flat, this);
+    }
+}
+
+void Parcel::freeData()
+{
+    freeDataNoInit();
+    initState();
+}
+
+void Parcel::freeDataNoInit()
+{
+    if (mOwner) {
+        //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
+        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
+    } else {
+        releaseObjects();
+        if (mData) free(mData);
+        if (mObjects) free(mObjects);
+    }
+}
+
+status_t Parcel::growData(size_t len)
+{
+    size_t newSize = ((mDataSize+len)*3)/2;
+    return (newSize <= mDataSize)
+            ? (status_t) NO_MEMORY
+            : continueWrite(newSize);
+}
+
+status_t Parcel::restartWrite(size_t desired)
+{
+    if (mOwner) {
+        freeData();
+        return continueWrite(desired);
+    }
+    
+    uint8_t* data = (uint8_t*)realloc(mData, desired);
+    if (!data && desired > mDataCapacity) {
+        mError = NO_MEMORY;
+        return NO_MEMORY;
+    }
+    
+    releaseObjects();
+    
+    if (data) {
+        mData = data;
+        mDataCapacity = desired;
+    }
+    
+    mDataSize = mDataPos = 0;
+    LOGV("restartWrite Setting data size of %p to %d\n", this, mDataSize);
+    LOGV("restartWrite Setting data pos of %p to %d\n", this, mDataPos);
+        
+    free(mObjects);
+    mObjects = NULL;
+    mObjectsSize = mObjectsCapacity = 0;
+    mNextObjectHint = 0;
+    mHasFds = false;
+    mFdsKnown = true;
+    
+    return NO_ERROR;
+}
+
+status_t Parcel::continueWrite(size_t desired)
+{
+    // If shrinking, first adjust for any objects that appear
+    // after the new data size.
+    size_t objectsSize = mObjectsSize;
+    if (desired < mDataSize) {
+        if (desired == 0) {
+            objectsSize = 0;
+        } else {
+            while (objectsSize > 0) {
+                if (mObjects[objectsSize-1] < desired)
+                    break;
+                objectsSize--;
+            }
+        }
+    }
+    
+    if (mOwner) {
+        // If the size is going to zero, just release the owner's data.
+        if (desired == 0) {
+            freeData();
+            return NO_ERROR;
+        }
+
+        // If there is a different owner, we need to take
+        // posession.
+        uint8_t* data = (uint8_t*)malloc(desired);
+        if (!data) {
+            mError = NO_MEMORY;
+            return NO_MEMORY;
+        }
+        size_t* objects = NULL;
+        
+        if (objectsSize) {
+            objects = (size_t*)malloc(objectsSize*sizeof(size_t));
+            if (!objects) {
+                mError = NO_MEMORY;
+                return NO_MEMORY;
+            }
+
+            // Little hack to only acquire references on objects
+            // we will be keeping.
+            size_t oldObjectsSize = mObjectsSize;
+            mObjectsSize = objectsSize;
+            acquireObjects();
+            mObjectsSize = oldObjectsSize;
+        }
+        
+        if (mData) {
+            memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
+        }
+        if (objects && mObjects) {
+            memcpy(objects, mObjects, objectsSize*sizeof(size_t));
+        }
+        //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
+        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
+        mOwner = NULL;
+
+        mData = data;
+        mObjects = objects;
+        mDataSize = (mDataSize < desired) ? mDataSize : desired;
+        LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+        mDataCapacity = desired;
+        mObjectsSize = mObjectsCapacity = objectsSize;
+        mNextObjectHint = 0;
+
+    } else if (mData) {
+        if (objectsSize < mObjectsSize) {
+            // Need to release refs on any objects we are dropping.
+            const sp<ProcessState> proc(ProcessState::self());
+            for (size_t i=objectsSize; i<mObjectsSize; i++) {
+                const flat_binder_object* flat
+                    = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
+                if (flat->type == BINDER_TYPE_FD) {
+                    // will need to rescan because we may have lopped off the only FDs
+                    mFdsKnown = false;
+                }
+                release_object(proc, *flat, this);
+            }
+            size_t* objects =
+                (size_t*)realloc(mObjects, objectsSize*sizeof(size_t));
+            if (objects) {
+                mObjects = objects;
+            }
+            mObjectsSize = objectsSize;
+            mNextObjectHint = 0;
+        }
+
+        // We own the data, so we can just do a realloc().
+        if (desired > mDataCapacity) {
+            uint8_t* data = (uint8_t*)realloc(mData, desired);
+            if (data) {
+                mData = data;
+                mDataCapacity = desired;
+            } else if (desired > mDataCapacity) {
+                mError = NO_MEMORY;
+                return NO_MEMORY;
+            }
+        } else {
+            mDataSize = desired;
+            LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+            if (mDataPos > desired) {
+                mDataPos = desired;
+                LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
+            }
+        }
+        
+    } else {
+        // This is the first data.  Easy!
+        uint8_t* data = (uint8_t*)malloc(desired);
+        if (!data) {
+            mError = NO_MEMORY;
+            return NO_MEMORY;
+        }
+        
+        if(!(mDataCapacity == 0 && mObjects == NULL
+             && mObjectsCapacity == 0)) {
+            LOGE("continueWrite: %d/%p/%d/%d", mDataCapacity, mObjects, mObjectsCapacity, desired);
+        }
+        
+        mData = data;
+        mDataSize = mDataPos = 0;
+        LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+        LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
+        mDataCapacity = desired;
+    }
+
+    return NO_ERROR;
+}
+
+void Parcel::initState()
+{
+    mError = NO_ERROR;
+    mData = 0;
+    mDataSize = 0;
+    mDataCapacity = 0;
+    mDataPos = 0;
+    LOGV("initState Setting data size of %p to %d\n", this, mDataSize);
+    LOGV("initState Setting data pos of %p to %d\n", this, mDataPos);
+    mObjects = NULL;
+    mObjectsSize = 0;
+    mObjectsCapacity = 0;
+    mNextObjectHint = 0;
+    mHasFds = false;
+    mFdsKnown = true;
+    mOwner = NULL;
+}
+
+void Parcel::scanForFds() const
+{
+    bool hasFds = false;
+    for (size_t i=0; i<mObjectsSize; i++) {
+        const flat_binder_object* flat
+            = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
+        if (flat->type == BINDER_TYPE_FD) {
+            hasFds = true;
+            break;
+        }
+    }
+    mHasFds = hasFds;
+    mFdsKnown = true;
+}
+
+}; // namespace android
diff --git a/libs/utils/Pipe.cpp b/libs/utils/Pipe.cpp
new file mode 100644
index 0000000..613906b
--- /dev/null
+++ b/libs/utils/Pipe.cpp
@@ -0,0 +1,465 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+//
+// Unidirectional pipe.
+//
+
+#include <utils/Pipe.h>
+#include <utils/Log.h>
+
+#if defined(HAVE_WIN32_IPC)
+# include <windows.h>
+#else
+# include <fcntl.h>
+# include <unistd.h>
+# include <errno.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+using namespace android;
+
+const unsigned long kInvalidHandle = (unsigned long) -1;
+
+
+/*
+ * Constructor.  Do little.
+ */
+Pipe::Pipe(void)
+    : mReadNonBlocking(false), mReadHandle(kInvalidHandle),
+      mWriteHandle(kInvalidHandle)
+{
+}
+
+/*
+ * Destructor.  Use the system-appropriate close call.
+ */
+Pipe::~Pipe(void)
+{
+#if defined(HAVE_WIN32_IPC)
+    if (mReadHandle != kInvalidHandle) {
+        if (!CloseHandle((HANDLE)mReadHandle))
+            LOG(LOG_WARN, "pipe", "failed closing read handle (%ld)\n",
+                mReadHandle);
+    }
+    if (mWriteHandle != kInvalidHandle) {
+        FlushFileBuffers((HANDLE)mWriteHandle);
+        if (!CloseHandle((HANDLE)mWriteHandle))
+            LOG(LOG_WARN, "pipe", "failed closing write handle (%ld)\n",
+                mWriteHandle);
+    }
+#else
+    if (mReadHandle != kInvalidHandle) {
+        if (close((int) mReadHandle) != 0)
+            LOG(LOG_WARN, "pipe", "failed closing read fd (%d)\n",
+                (int) mReadHandle);
+    }
+    if (mWriteHandle != kInvalidHandle) {
+        if (close((int) mWriteHandle) != 0)
+            LOG(LOG_WARN, "pipe", "failed closing write fd (%d)\n",
+                (int) mWriteHandle);
+    }
+#endif
+}
+
+/*
+ * Create the pipe.
+ *
+ * Use the POSIX stuff for everything but Windows.
+ */
+bool Pipe::create(void)
+{
+    assert(mReadHandle == kInvalidHandle);
+    assert(mWriteHandle == kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    /* we use this across processes, so they need to be inheritable */
+    HANDLE handles[2];
+    SECURITY_ATTRIBUTES saAttr;
+
+    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+    saAttr.bInheritHandle = TRUE;
+    saAttr.lpSecurityDescriptor = NULL;
+
+    if (!CreatePipe(&handles[0], &handles[1], &saAttr, 0)) {
+        LOG(LOG_ERROR, "pipe", "unable to create pipe\n");
+        return false;
+    }
+    mReadHandle = (unsigned long) handles[0];
+    mWriteHandle = (unsigned long) handles[1];
+    return true;
+#else
+    int fds[2];
+
+    if (pipe(fds) != 0) {
+        LOG(LOG_ERROR, "pipe", "unable to create pipe\n");
+        return false;
+    }
+    mReadHandle = fds[0];
+    mWriteHandle = fds[1];
+    return true;
+#endif
+}
+
+/*
+ * Create a "half pipe".  Please, no Segway riding.
+ */
+bool Pipe::createReader(unsigned long handle)
+{
+    mReadHandle = handle;
+    assert(mWriteHandle == kInvalidHandle);
+    return true;
+}
+
+/*
+ * Create a "half pipe" for writing.
+ */
+bool Pipe::createWriter(unsigned long handle)
+{
+    mWriteHandle = handle;
+    assert(mReadHandle == kInvalidHandle);
+    return true;
+}
+
+/*
+ * Return "true" if create() has been called successfully.
+ */
+bool Pipe::isCreated(void)
+{
+    // one or the other should be open
+    return (mReadHandle != kInvalidHandle || mWriteHandle != kInvalidHandle);
+}
+
+
+/*
+ * Read data from the pipe.
+ *
+ * For Linux and Darwin, just call read().  For Windows, implement
+ * non-blocking reads by calling PeekNamedPipe first.
+ */
+int Pipe::read(void* buf, int count)
+{
+    assert(mReadHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    DWORD totalBytesAvail = count;
+    DWORD bytesRead;
+
+    if (mReadNonBlocking) {
+        // use PeekNamedPipe to adjust read count expectations
+        if (!PeekNamedPipe((HANDLE) mReadHandle, NULL, 0, NULL,
+                &totalBytesAvail, NULL))
+        {
+            LOG(LOG_ERROR, "pipe", "PeekNamedPipe failed\n");
+            return -1;
+        }
+
+        if (totalBytesAvail == 0)
+            return 0;
+    }
+
+    if (!ReadFile((HANDLE) mReadHandle, buf, totalBytesAvail, &bytesRead,
+            NULL))
+    {
+        DWORD err = GetLastError();
+        if (err == ERROR_HANDLE_EOF || err == ERROR_BROKEN_PIPE)
+            return 0;
+        LOG(LOG_ERROR, "pipe", "ReadFile failed (err=%ld)\n", err);
+        return -1;
+    }
+
+    return (int) bytesRead;
+#else
+    int cc;
+    cc = ::read(mReadHandle, buf, count);
+    if (cc < 0 && errno == EAGAIN)
+        return 0;
+    return cc;
+#endif
+}
+
+/*
+ * Write data to the pipe.
+ *
+ * POSIX systems are trivial, Windows uses a different call and doesn't
+ * handle non-blocking writes.
+ *
+ * If we add non-blocking support here, we probably want to make it an
+ * all-or-nothing write.
+ *
+ * DO NOT use LOG() here, we could be writing a log message.
+ */
+int Pipe::write(const void* buf, int count)
+{
+    assert(mWriteHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    DWORD bytesWritten;
+
+    if (mWriteNonBlocking) {
+        // BUG: can't use PeekNamedPipe() to get the amount of space
+        // left.  Looks like we need to use "overlapped I/O" functions.
+        // I just don't care that much.
+    }
+
+    if (!WriteFile((HANDLE) mWriteHandle, buf, count, &bytesWritten, NULL)) {
+        // can't LOG, use stderr
+        fprintf(stderr, "WriteFile failed (err=%ld)\n", GetLastError());
+        return -1;
+    }
+
+    return (int) bytesWritten;
+#else
+    int cc;
+    cc = ::write(mWriteHandle, buf, count);
+    if (cc < 0 && errno == EAGAIN)
+        return 0;
+    return cc;
+#endif
+}
+
+/*
+ * Figure out if there is data available on the read fd.
+ *
+ * We return "true" on error because we want the caller to try to read
+ * from the pipe.  They'll notice the read failure and do something
+ * appropriate.
+ */
+bool Pipe::readReady(void)
+{
+    assert(mReadHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    DWORD totalBytesAvail;
+
+    if (!PeekNamedPipe((HANDLE) mReadHandle, NULL, 0, NULL,
+            &totalBytesAvail, NULL))
+    {
+        LOG(LOG_ERROR, "pipe", "PeekNamedPipe failed\n");
+        return true;
+    }
+
+    return (totalBytesAvail != 0);
+#else
+    errno = 0;
+    fd_set readfds;
+    struct timeval tv = { 0, 0 };
+    int cc;
+
+    FD_ZERO(&readfds);
+    FD_SET(mReadHandle, &readfds);
+
+    cc = select(mReadHandle+1, &readfds, NULL, NULL, &tv);
+    if (cc < 0) {
+        LOG(LOG_ERROR, "pipe", "select() failed\n");
+        return true;
+    } else if (cc == 0) {
+        /* timed out, nothing available */
+        return false;
+    } else if (cc == 1) {
+        /* our fd is ready */
+        return true;
+    } else {
+        LOG(LOG_ERROR, "pipe", "HUH? select() returned > 1\n");
+        return true;
+    }
+#endif
+}
+
+/*
+ * Enable or disable non-blocking mode for the read descriptor.
+ *
+ * NOTE: the calls succeed under Mac OS X, but the pipe doesn't appear to
+ * actually be in non-blocking mode.  If this matters -- i.e. you're not
+ * using a select() call -- put a call to readReady() in front of the
+ * ::read() call, with a PIPE_NONBLOCK_BROKEN #ifdef in the Makefile for
+ * Darwin.
+ */
+bool Pipe::setReadNonBlocking(bool val)
+{
+    assert(mReadHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    // nothing to do
+#else
+    int flags;
+
+    if (fcntl(mReadHandle, F_GETFL, &flags) == -1) {
+        LOG(LOG_ERROR, "pipe", "couldn't get flags for pipe read fd\n");
+        return false;
+    }
+    if (val)
+        flags |= O_NONBLOCK;
+    else
+        flags &= ~(O_NONBLOCK);
+    if (fcntl(mReadHandle, F_SETFL, &flags) == -1) {
+        LOG(LOG_ERROR, "pipe", "couldn't set flags for pipe read fd\n");
+        return false;
+    }
+#endif
+
+    mReadNonBlocking = val;
+    return true;
+}
+
+/*
+ * Enable or disable non-blocking mode for the write descriptor.
+ *
+ * As with setReadNonBlocking(), this does not work on the Mac.
+ */
+bool Pipe::setWriteNonBlocking(bool val)
+{
+    assert(mWriteHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    // nothing to do
+#else
+    int flags;
+
+    if (fcntl(mWriteHandle, F_GETFL, &flags) == -1) {
+        LOG(LOG_WARN, "pipe",
+            "Warning: couldn't get flags for pipe write fd (errno=%d)\n",
+            errno);
+        return false;
+    }
+    if (val)
+        flags |= O_NONBLOCK;
+    else
+        flags &= ~(O_NONBLOCK);
+    if (fcntl(mWriteHandle, F_SETFL, &flags) == -1) {
+        LOG(LOG_WARN, "pipe",
+            "Warning: couldn't set flags for pipe write fd (errno=%d)\n",
+            errno);
+        return false;
+    }
+#endif
+
+    mWriteNonBlocking = val;
+    return true;
+}
+
+/*
+ * Specify whether a file descriptor can be inherited by a child process.
+ * Under Linux this means setting the close-on-exec flag, under Windows
+ * this is SetHandleInformation(HANDLE_FLAG_INHERIT).
+ */
+bool Pipe::disallowReadInherit(void)
+{
+    if (mReadHandle == kInvalidHandle)
+        return false;
+
+#if defined(HAVE_WIN32_IPC)
+    if (SetHandleInformation((HANDLE) mReadHandle, HANDLE_FLAG_INHERIT, 0) == 0)
+        return false;
+#else
+    if (fcntl((int) mReadHandle, F_SETFD, FD_CLOEXEC) != 0)
+        return false;
+#endif
+    return true;
+}
+bool Pipe::disallowWriteInherit(void)
+{
+    if (mWriteHandle == kInvalidHandle)
+        return false;
+
+#if defined(HAVE_WIN32_IPC)
+    if (SetHandleInformation((HANDLE) mWriteHandle, HANDLE_FLAG_INHERIT, 0) == 0)
+        return false;
+#else
+    if (fcntl((int) mWriteHandle, F_SETFD, FD_CLOEXEC) != 0)
+        return false;
+#endif
+    return true;
+}
+
+/*
+ * Close read descriptor.
+ */
+bool Pipe::closeRead(void)
+{
+    if (mReadHandle == kInvalidHandle)
+        return false;
+
+#if defined(HAVE_WIN32_IPC)
+    if (mReadHandle != kInvalidHandle) {
+        if (!CloseHandle((HANDLE)mReadHandle)) {
+            LOG(LOG_WARN, "pipe", "failed closing read handle\n");
+            return false;
+        }
+    }
+#else
+    if (mReadHandle != kInvalidHandle) {
+        if (close((int) mReadHandle) != 0) {
+            LOG(LOG_WARN, "pipe", "failed closing read fd\n");
+            return false;
+        }
+    }
+#endif
+    mReadHandle = kInvalidHandle;
+    return true;
+}
+
+/*
+ * Close write descriptor.
+ */
+bool Pipe::closeWrite(void)
+{
+    if (mWriteHandle == kInvalidHandle)
+        return false;
+
+#if defined(HAVE_WIN32_IPC)
+    if (mWriteHandle != kInvalidHandle) {
+        if (!CloseHandle((HANDLE)mWriteHandle)) {
+            LOG(LOG_WARN, "pipe", "failed closing write handle\n");
+            return false;
+        }
+    }
+#else
+    if (mWriteHandle != kInvalidHandle) {
+        if (close((int) mWriteHandle) != 0) {
+            LOG(LOG_WARN, "pipe", "failed closing write fd\n");
+            return false;
+        }
+    }
+#endif
+    mWriteHandle = kInvalidHandle;
+    return true;
+}
+
+/*
+ * Get the read handle.
+ */
+unsigned long Pipe::getReadHandle(void)
+{
+    assert(mReadHandle != kInvalidHandle);
+
+    return mReadHandle;
+}
+
+/*
+ * Get the write handle.
+ */
+unsigned long Pipe::getWriteHandle(void)
+{
+    assert(mWriteHandle != kInvalidHandle);
+
+    return mWriteHandle;
+}
+
diff --git a/libs/utils/ProcessState.cpp b/libs/utils/ProcessState.cpp
new file mode 100644
index 0000000..4567df6
--- /dev/null
+++ b/libs/utils/ProcessState.cpp
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2005 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 "ProcessState"
+
+#include <cutils/process_name.h>
+
+#include <utils/ProcessState.h>
+
+#include <utils/Atomic.h>
+#include <utils/BpBinder.h>
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/IServiceManager.h>
+#include <utils/String8.h>
+#include <utils/threads.h>
+
+#include <private/utils/binder_module.h>
+#include <private/utils/Static.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#define BINDER_VM_SIZE (1*1024*1024)
+
+static bool gSingleProcess = false;
+
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+ 
+// Global variables
+int                 mArgC;
+const char* const*  mArgV;
+int                 mArgLen;
+
+class PoolThread : public Thread
+{
+public:
+    PoolThread(bool isMain)
+        : mIsMain(isMain)
+    {
+    }
+    
+protected:
+    virtual bool threadLoop()
+    {
+        IPCThreadState::self()->joinThreadPool(mIsMain);
+        return false;
+    }
+    
+    const bool mIsMain;
+};
+
+sp<ProcessState> ProcessState::self()
+{
+    if (gProcess != NULL) return gProcess;
+    
+    AutoMutex _l(gProcessMutex);
+    if (gProcess == NULL) gProcess = new ProcessState;
+    return gProcess;
+}
+
+void ProcessState::setSingleProcess(bool singleProcess)
+{
+    gSingleProcess = singleProcess;
+}
+
+
+void ProcessState::setContextObject(const sp<IBinder>& object)
+{
+    setContextObject(object, String16("default"));
+}
+
+sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
+{
+    if (supportsProcesses()) {
+        return getStrongProxyForHandle(0);
+    } else {
+        return getContextObject(String16("default"), caller);
+    }
+}
+
+void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
+{
+    AutoMutex _l(mLock);
+    mContexts.add(name, object);
+}
+
+sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller)
+{
+    mLock.lock();
+    sp<IBinder> object(
+        mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL);
+    mLock.unlock();
+    
+    //printf("Getting context object %s for %p\n", String8(name).string(), caller.get());
+    
+    if (object != NULL) return object;
+
+    // Don't attempt to retrieve contexts if we manage them
+    if (mManagesContexts) {
+        LOGE("getContextObject(%s) failed, but we manage the contexts!\n",
+            String8(name).string());
+        return NULL;
+    }
+    
+    IPCThreadState* ipc = IPCThreadState::self();
+    {
+        Parcel data, reply;
+        // no interface token on this magic transaction
+        data.writeString16(name);
+        data.writeStrongBinder(caller);
+        status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0);
+        if (result == NO_ERROR) {
+            object = reply.readStrongBinder();
+        }
+    }
+    
+    ipc->flushCommands();
+    
+    if (object != NULL) setContextObject(object, name);
+    return object;
+}
+
+bool ProcessState::supportsProcesses() const
+{
+    return mDriverFD >= 0;
+}
+
+void ProcessState::startThreadPool()
+{
+    AutoMutex _l(mLock);
+    if (!mThreadPoolStarted) {
+        mThreadPoolStarted = true;
+        spawnPooledThread(true);
+    }
+}
+
+bool ProcessState::isContextManager(void) const
+{
+    return mManagesContexts;
+}
+
+bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
+{
+    if (!mManagesContexts) {
+        AutoMutex _l(mLock);
+        mBinderContextCheckFunc = checkFunc;
+        mBinderContextUserData = userData;
+        if (mDriverFD >= 0) {
+            int dummy = 0;
+#if defined(HAVE_ANDROID_OS)
+            status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
+#else
+            status_t result = INVALID_OPERATION;
+#endif
+            if (result == 0) {
+                mManagesContexts = true;
+            } else if (result == -1) {
+                mBinderContextCheckFunc = NULL;
+                mBinderContextUserData = NULL;
+                LOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
+            }
+        } else {
+            // If there is no driver, our only world is the local
+            // process so we can always become the context manager there.
+            mManagesContexts = true;
+        }
+    }
+    return mManagesContexts;
+}
+
+ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
+{
+    const size_t N=mHandleToObject.size();
+    if (N <= (size_t)handle) {
+        handle_entry e;
+        e.binder = NULL;
+        e.refs = NULL;
+        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
+        if (err < NO_ERROR) return NULL;
+    }
+    return &mHandleToObject.editItemAt(handle);
+}
+
+sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
+{
+    sp<IBinder> result;
+
+    AutoMutex _l(mLock);
+
+    handle_entry* e = lookupHandleLocked(handle);
+
+    if (e != NULL) {
+        // We need to create a new BpBinder if there isn't currently one, OR we
+        // are unable to acquire a weak reference on this current one.  See comment
+        // in getWeakProxyForHandle() for more info about this.
+        IBinder* b = e->binder;
+        if (b == NULL || !e->refs->attemptIncWeak(this)) {
+            b = new BpBinder(handle); 
+            e->binder = b;
+            if (b) e->refs = b->getWeakRefs();
+            result = b;
+        } else {
+            // This little bit of nastyness is to allow us to add a primary
+            // reference to the remote proxy when this team doesn't have one
+            // but another team is sending the handle to us.
+            result.force_set(b);
+            e->refs->decWeak(this);
+        }
+    }
+
+    return result;
+}
+
+wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
+{
+    wp<IBinder> result;
+
+    AutoMutex _l(mLock);
+
+    handle_entry* e = lookupHandleLocked(handle);
+
+    if (e != NULL) {        
+        // We need to create a new BpBinder if there isn't currently one, OR we
+        // are unable to acquire a weak reference on this current one.  The
+        // attemptIncWeak() is safe because we know the BpBinder destructor will always
+        // call expungeHandle(), which acquires the same lock we are holding now.
+        // We need to do this because there is a race condition between someone
+        // releasing a reference on this BpBinder, and a new reference on its handle
+        // arriving from the driver.
+        IBinder* b = e->binder;
+        if (b == NULL || !e->refs->attemptIncWeak(this)) {
+            b = new BpBinder(handle);
+            result = b;
+            e->binder = b;
+            if (b) e->refs = b->getWeakRefs();
+        } else {
+            result = b;
+            e->refs->decWeak(this);
+        }
+    }
+
+    return result;
+}
+
+void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
+{
+    AutoMutex _l(mLock);
+    
+    handle_entry* e = lookupHandleLocked(handle);
+
+    // This handle may have already been replaced with a new BpBinder
+    // (if someone failed the AttemptIncWeak() above); we don't want
+    // to overwrite it.
+    if (e && e->binder == binder) e->binder = NULL;
+}
+
+void ProcessState::setArgs(int argc, const char* const argv[])
+{
+    mArgC = argc;
+    mArgV = (const char **)argv;
+
+    mArgLen = 0;
+    for (int i=0; i<argc; i++) {
+        mArgLen += strlen(argv[i]) + 1;
+    }
+    mArgLen--;
+}
+
+int ProcessState::getArgC() const
+{
+    return mArgC;
+}
+
+const char* const* ProcessState::getArgV() const
+{
+    return mArgV;
+}
+
+void ProcessState::setArgV0(const char* txt)
+{
+    if (mArgV != NULL) {
+        strncpy((char*)mArgV[0], txt, mArgLen);
+        set_process_name(txt);
+    }
+}
+
+void ProcessState::spawnPooledThread(bool isMain)
+{
+    if (mThreadPoolStarted) {
+        int32_t s = android_atomic_add(1, &mThreadPoolSeq);
+        char buf[32];
+        sprintf(buf, "Binder Thread #%d", s);
+        LOGV("Spawning new pooled thread, name=%s\n", buf);
+        sp<Thread> t = new PoolThread(isMain);
+        t->run(buf);
+    }
+}
+
+static int open_driver()
+{
+    if (gSingleProcess) {
+        return -1;
+    }
+
+    int fd = open("/dev/binder", O_RDWR);
+    if (fd >= 0) {
+        fcntl(fd, F_SETFD, FD_CLOEXEC);
+        int vers;
+#if defined(HAVE_ANDROID_OS)
+        status_t result = ioctl(fd, BINDER_VERSION, &vers);
+#else
+        status_t result = -1;
+        errno = EPERM;
+#endif
+        if (result == -1) {
+            LOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
+            close(fd);
+            fd = -1;
+        }
+        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
+            LOGE("Binder driver protocol does not match user space protocol!");
+            close(fd);
+            fd = -1;
+        }
+#if defined(HAVE_ANDROID_OS)
+        size_t maxThreads = 15;
+        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
+        if (result == -1) {
+            LOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
+        }
+#endif
+        
+    } else {
+        LOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));
+    }
+    return fd;
+}
+
+ProcessState::ProcessState()
+    : mDriverFD(open_driver())
+    , mVMStart(MAP_FAILED)
+    , mManagesContexts(false)
+    , mBinderContextCheckFunc(NULL)
+    , mBinderContextUserData(NULL)
+    , mThreadPoolStarted(false)
+    , mThreadPoolSeq(1)
+{
+    if (mDriverFD >= 0) {
+        // XXX Ideally, there should be a specific define for whether we
+        // have mmap (or whether we could possibly have the kernel module
+        // availabla).
+#if !defined(HAVE_WIN32_IPC)
+        // mmap the binder, providing a chunk of virtual address space to receive transactions.
+        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
+        if (mVMStart == MAP_FAILED) {
+            // *sigh*
+            LOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
+            close(mDriverFD);
+            mDriverFD = -1;
+        }
+#else
+        mDriverFD = -1;
+#endif
+    }
+    if (mDriverFD < 0) {
+        // Need to run without the driver, starting our own thread pool.
+    }
+}
+
+ProcessState::~ProcessState()
+{
+}
+        
+}; // namespace android
diff --git a/libs/utils/README b/libs/utils/README
new file mode 100644
index 0000000..36a706d
--- /dev/null
+++ b/libs/utils/README
@@ -0,0 +1,14 @@
+Android Utility Function Library
+
+If you need a feature that is native to Linux but not present on other
+platforms, construct a platform-dependent implementation that shares
+the Linux interface.  That way the actual device runs as "light" as
+possible.
+
+If that isn't feasible, create a system-independent interface and hide
+the details.
+
+The ultimate goal is *not* to create a super-duper platform abstraction
+layer.  The goal is to provide an optimized solution for Linux with
+reasonable implementations for other platforms.
+
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
new file mode 100644
index 0000000..0bd1af4
--- /dev/null
+++ b/libs/utils/RefBase.cpp
@@ -0,0 +1,534 @@
+/*
+ * Copyright (C) 2005 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 "RefBase"
+
+#include <utils/RefBase.h>
+
+#include <utils/Atomic.h>
+#include <utils/CallStack.h>
+#include <utils/KeyedVector.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <typeinfo>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+// compile with refcounting debugging enabled
+#define DEBUG_REFS                      0
+#define DEBUG_REFS_ENABLED_BY_DEFAULT   1
+#define DEBUG_REFS_CALLSTACK_ENABLED    1
+
+// log all reference counting operations
+#define PRINT_REFS                      0
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+#define INITIAL_STRONG_VALUE (1<<28)
+
+// ---------------------------------------------------------------------------
+
+class RefBase::weakref_impl : public RefBase::weakref_type
+{
+public:
+    volatile int32_t    mStrong;
+    volatile int32_t    mWeak;
+    RefBase* const      mBase;
+    volatile int32_t    mFlags;
+
+
+#if !DEBUG_REFS
+
+    weakref_impl(RefBase* base)
+        : mStrong(INITIAL_STRONG_VALUE)
+        , mWeak(0)
+        , mBase(base)
+        , mFlags(0)
+    {
+    }
+
+    void addStrongRef(const void* /*id*/) { }
+    void removeStrongRef(const void* /*id*/) { }
+    void addWeakRef(const void* /*id*/) { }
+    void removeWeakRef(const void* /*id*/) { }
+    void printRefs() const { }
+    void trackMe(bool, bool) { }
+
+#else
+
+    weakref_impl(RefBase* base)
+        : mStrong(INITIAL_STRONG_VALUE)
+        , mWeak(0)
+        , mBase(base)
+        , mFlags(0)
+        , mStrongRefs(NULL)
+        , mWeakRefs(NULL)
+        , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
+        , mRetain(false)
+    {
+        //LOGI("NEW weakref_impl %p for RefBase %p", this, base);
+    }
+    
+    ~weakref_impl()
+    {
+        LOG_ALWAYS_FATAL_IF(!mRetain && mStrongRefs != NULL, "Strong references remain!");
+        LOG_ALWAYS_FATAL_IF(!mRetain && mWeakRefs != NULL, "Weak references remain!");
+    }
+
+    void addStrongRef(const void* id)
+    {
+        addRef(&mStrongRefs, id, mStrong);
+    }
+
+    void removeStrongRef(const void* id)
+    {
+        if (!mRetain)
+            removeRef(&mStrongRefs, id);
+        else
+            addRef(&mStrongRefs, id, -mStrong);
+    }
+
+    void addWeakRef(const void* id)
+    {
+        addRef(&mWeakRefs, id, mWeak);
+    }
+
+    void removeWeakRef(const void* id)
+    {
+        if (!mRetain)
+            removeRef(&mWeakRefs, id);
+        else
+            addRef(&mWeakRefs, id, -mWeak);
+    }
+
+    void trackMe(bool track, bool retain)
+    { 
+        mTrackEnabled = track;
+        mRetain = retain;
+    }
+
+    void printRefs() const
+    {
+        String8 text;
+
+        {
+            AutoMutex _l(const_cast<weakref_impl*>(this)->mMutex);
+    
+            char buf[128];
+            sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this);
+            text.append(buf);
+            printRefsLocked(&text, mStrongRefs);
+            sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this);
+            text.append(buf);
+            printRefsLocked(&text, mWeakRefs);
+        }
+
+        {
+            char name[100];
+            snprintf(name, 100, "/data/%p.stack", this);
+            int rc = open(name, O_RDWR | O_CREAT | O_APPEND);
+            if (rc >= 0) {
+                write(rc, text.string(), text.length());
+                close(rc);
+                LOGD("STACK TRACE for %p saved in %s", this, name);
+            }
+            else LOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this,
+                      name, strerror(errno));
+        }
+    }
+
+private:
+    struct ref_entry
+    {
+        ref_entry* next;
+        const void* id;
+#if DEBUG_REFS_CALLSTACK_ENABLED
+        CallStack stack;
+#endif
+        int32_t ref;
+    };
+
+    void addRef(ref_entry** refs, const void* id, int32_t mRef)
+    {
+        if (mTrackEnabled) {
+            AutoMutex _l(mMutex);
+            ref_entry* ref = new ref_entry;
+            // Reference count at the time of the snapshot, but before the
+            // update.  Positive value means we increment, negative--we
+            // decrement the reference count.
+            ref->ref = mRef;
+            ref->id = id;
+#if DEBUG_REFS_CALLSTACK_ENABLED
+            ref->stack.update(2);
+#endif
+            
+            ref->next = *refs;
+            *refs = ref;
+        }
+    }
+
+    void removeRef(ref_entry** refs, const void* id)
+    {
+        if (mTrackEnabled) {
+            AutoMutex _l(mMutex);
+            
+            ref_entry* ref = *refs;
+            while (ref != NULL) {
+                if (ref->id == id) {
+                    *refs = ref->next;
+                    delete ref;
+                    return;
+                }
+                
+                refs = &ref->next;
+                ref = *refs;
+            }
+            
+            LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p (weakref_type %p) that doesn't exist!",
+                             id, mBase, this);
+        }
+    }
+
+    void printRefsLocked(String8* out, const ref_entry* refs) const
+    {
+        char buf[128];
+        while (refs) {
+            char inc = refs->ref >= 0 ? '+' : '-';
+            sprintf(buf, "\t%c ID %p (ref %d):\n", 
+                    inc, refs->id, refs->ref);
+            out->append(buf);
+#if DEBUG_REFS_CALLSTACK_ENABLED
+            out->append(refs->stack.toString("\t\t"));
+#else
+            out->append("\t\t(call stacks disabled)");
+#endif
+            refs = refs->next;
+        }
+    }
+
+    Mutex mMutex;
+    ref_entry* mStrongRefs;
+    ref_entry* mWeakRefs;
+
+    bool mTrackEnabled;
+    // Collect stack traces on addref and removeref, instead of deleting the stack references
+    // on removeref that match the address ones.
+    bool mRetain;
+
+#if 0
+    void addRef(KeyedVector<const void*, int32_t>* refs, const void* id)
+    {
+        AutoMutex _l(mMutex);
+        ssize_t i = refs->indexOfKey(id);
+        if (i >= 0) {
+            ++(refs->editValueAt(i));
+        } else {
+            i = refs->add(id, 1);
+        }
+    }
+
+    void removeRef(KeyedVector<const void*, int32_t>* refs, const void* id)
+    {
+        AutoMutex _l(mMutex);
+        ssize_t i = refs->indexOfKey(id);
+        LOG_ALWAYS_FATAL_IF(i < 0, "RefBase: removing id %p that doesn't exist!", id);
+        if (i >= 0) {
+            int32_t val = --(refs->editValueAt(i));
+            if (val == 0) {
+                refs->removeItemsAt(i);
+            }
+        }
+    }
+
+    void printRefs(const KeyedVector<const void*, int32_t>& refs)
+    {
+        const size_t N=refs.size();
+        for (size_t i=0; i<N; i++) {
+            printf("\tID %p: %d remain\n", refs.keyAt(i), refs.valueAt(i));
+        }
+    }
+
+    mutable Mutex mMutex;
+    KeyedVector<const void*, int32_t> mStrongRefs;
+    KeyedVector<const void*, int32_t> mWeakRefs;
+#endif
+
+#endif
+};
+
+// ---------------------------------------------------------------------------
+
+void RefBase::incStrong(const void* id) const
+{
+    weakref_impl* const refs = mRefs;
+    refs->addWeakRef(id);
+    refs->incWeak(id);
+    
+    refs->addStrongRef(id);
+    const int32_t c = android_atomic_inc(&refs->mStrong);
+    LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
+#if PRINT_REFS
+    LOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
+#endif
+    if (c != INITIAL_STRONG_VALUE)  {
+        return;
+    }
+
+    android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
+    const_cast<RefBase*>(this)->onFirstRef();
+}
+
+void RefBase::decStrong(const void* id) const
+{
+    weakref_impl* const refs = mRefs;
+    refs->removeStrongRef(id);
+    const int32_t c = android_atomic_dec(&refs->mStrong);
+#if PRINT_REFS
+    LOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
+#endif
+    LOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
+    if (c == 1) {
+        const_cast<RefBase*>(this)->onLastStrongRef(id);
+        if ((refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
+            delete this;
+        }
+    }
+    refs->removeWeakRef(id);
+    refs->decWeak(id);
+}
+
+void RefBase::forceIncStrong(const void* id) const
+{
+    weakref_impl* const refs = mRefs;
+    refs->addWeakRef(id);
+    refs->incWeak(id);
+    
+    refs->addStrongRef(id);
+    const int32_t c = android_atomic_inc(&refs->mStrong);
+    LOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow",
+               refs);
+#if PRINT_REFS
+    LOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c);
+#endif
+
+    switch (c) {
+    case INITIAL_STRONG_VALUE:
+        android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
+        // fall through...
+    case 0:
+        const_cast<RefBase*>(this)->onFirstRef();
+    }
+}
+
+int32_t RefBase::getStrongCount() const
+{
+    return mRefs->mStrong;
+}
+
+
+
+RefBase* RefBase::weakref_type::refBase() const
+{
+    return static_cast<const weakref_impl*>(this)->mBase;
+}
+
+void RefBase::weakref_type::incWeak(const void* id)
+{
+    weakref_impl* const impl = static_cast<weakref_impl*>(this);
+    impl->addWeakRef(id);
+    const int32_t c = android_atomic_inc(&impl->mWeak);
+    LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
+}
+
+void RefBase::weakref_type::decWeak(const void* id)
+{
+    weakref_impl* const impl = static_cast<weakref_impl*>(this);
+    impl->removeWeakRef(id);
+    const int32_t c = android_atomic_dec(&impl->mWeak);
+    LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
+    if (c != 1) return;
+    
+    if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
+        if (impl->mStrong == INITIAL_STRONG_VALUE)
+            delete impl->mBase;
+        else {
+//            LOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
+            delete impl;
+        }
+    } else {
+        impl->mBase->onLastWeakRef(id);
+        if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) {
+            delete impl->mBase;
+        }
+    }
+}
+
+bool RefBase::weakref_type::attemptIncStrong(const void* id)
+{
+    incWeak(id);
+    
+    weakref_impl* const impl = static_cast<weakref_impl*>(this);
+    
+    int32_t curCount = impl->mStrong;
+    LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
+               this);
+    while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
+        if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
+            break;
+        }
+        curCount = impl->mStrong;
+    }
+    
+    if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
+        bool allow;
+        if (curCount == INITIAL_STRONG_VALUE) {
+            // Attempting to acquire first strong reference...  this is allowed
+            // if the object does NOT have a longer lifetime (meaning the
+            // implementation doesn't need to see this), or if the implementation
+            // allows it to happen.
+            allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
+                  || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
+        } else {
+            // Attempting to revive the object...  this is allowed
+            // if the object DOES have a longer lifetime (so we can safely
+            // call the object with only a weak ref) and the implementation
+            // allows it to happen.
+            allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK
+                  && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
+        }
+        if (!allow) {
+            decWeak(id);
+            return false;
+        }
+        curCount = android_atomic_inc(&impl->mStrong);
+
+        // If the strong reference count has already been incremented by
+        // someone else, the implementor of onIncStrongAttempted() is holding
+        // an unneeded reference.  So call onLastStrongRef() here to remove it.
+        // (No, this is not pretty.)  Note that we MUST NOT do this if we
+        // are in fact acquiring the first reference.
+        if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
+            impl->mBase->onLastStrongRef(id);
+        }
+    }
+    
+    impl->addWeakRef(id);
+    impl->addStrongRef(id);
+
+#if PRINT_REFS
+    LOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
+#endif
+
+    if (curCount == INITIAL_STRONG_VALUE) {
+        android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);
+        impl->mBase->onFirstRef();
+    }
+    
+    return true;
+}
+
+bool RefBase::weakref_type::attemptIncWeak(const void* id)
+{
+    weakref_impl* const impl = static_cast<weakref_impl*>(this);
+    
+    int32_t curCount = impl->mWeak;
+    LOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow",
+               this);
+    while (curCount > 0) {
+        if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) {
+            break;
+        }
+        curCount = impl->mWeak;
+    }
+
+    if (curCount > 0) {
+        impl->addWeakRef(id);
+    }
+
+    return curCount > 0;
+}
+
+int32_t RefBase::weakref_type::getWeakCount() const
+{
+    return static_cast<const weakref_impl*>(this)->mWeak;
+}
+
+void RefBase::weakref_type::printRefs() const
+{
+    static_cast<const weakref_impl*>(this)->printRefs();
+}
+
+void RefBase::weakref_type::trackMe(bool enable, bool retain)
+{
+    static_cast<const weakref_impl*>(this)->trackMe(enable, retain);
+}
+
+RefBase::weakref_type* RefBase::createWeak(const void* id) const
+{
+    mRefs->incWeak(id);
+    return mRefs;
+}
+
+RefBase::weakref_type* RefBase::getWeakRefs() const
+{
+    return mRefs;
+}
+
+RefBase::RefBase()
+    : mRefs(new weakref_impl(this))
+{
+//    LOGV("Creating refs %p with RefBase %p\n", mRefs, this);
+}
+
+RefBase::~RefBase()
+{
+//    LOGV("Destroying RefBase %p (refs %p)\n", this, mRefs);
+    if (mRefs->mWeak == 0) {
+//        LOGV("Freeing refs %p of old RefBase %p\n", mRefs, this);
+        delete mRefs;
+    }
+}
+
+void RefBase::extendObjectLifetime(int32_t mode)
+{
+    android_atomic_or(mode, &mRefs->mFlags);
+}
+
+void RefBase::onFirstRef()
+{
+}
+
+void RefBase::onLastStrongRef(const void* /*id*/)
+{
+}
+
+bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
+{
+    return (flags&FIRST_INC_STRONG) ? true : false;
+}
+
+void RefBase::onLastWeakRef(const void* /*id*/)
+{
+}
+        
+}; // namespace android
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
new file mode 100644
index 0000000..71e7cd7
--- /dev/null
+++ b/libs/utils/ResourceTypes.cpp
@@ -0,0 +1,3983 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "ResourceType"
+//#define LOG_NDEBUG 0
+
+#include <utils/Atomic.h>
+#include <utils/ByteOrder.h>
+#include <utils/Debug.h>
+#include <utils/ResourceTypes.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
+#include <utils/TextOutput.h>
+#include <utils/Log.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#ifndef INT32_MAX
+#define INT32_MAX ((int32_t)(2147483647))
+#endif
+
+#define POOL_NOISY(x) //x
+#define XML_NOISY(x) //x
+#define TABLE_NOISY(x) //x
+#define TABLE_GETENTRY(x) //x
+#define TABLE_SUPER_NOISY(x) //x
+#define LOAD_TABLE_NOISY(x) //x
+
+namespace android {
+
+#ifdef HAVE_WINSOCK
+#undef  nhtol
+#undef  htonl
+
+#ifdef HAVE_LITTLE_ENDIAN
+#define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
+#define htonl(x)    ntohl(x)
+#define ntohs(x)    ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
+#define htons(x)    ntohs(x)
+#else
+#define ntohl(x)    (x)
+#define htonl(x)    (x)
+#define ntohs(x)    (x)
+#define htons(x)    (x)
+#endif
+#endif
+
+static void printToLogFunc(void* cookie, const char* txt)
+{
+    LOGV("%s", txt);
+}
+
+// Standard C isspace() is only required to look at the low byte of its input, so
+// produces incorrect results for UTF-16 characters.  For safety's sake, assume that
+// any high-byte UTF-16 code point is not whitespace.
+inline int isspace16(char16_t c) {
+    return (c < 0x0080 && isspace(c));
+}
+
+// range checked; guaranteed to NUL-terminate within the stated number of available slots
+// NOTE: if this truncates the dst string due to running out of space, no attempt is
+// made to avoid splitting surrogate pairs.
+static void strcpy16_dtoh(uint16_t* dst, const uint16_t* src, size_t avail)
+{
+    uint16_t* last = dst + avail - 1;
+    while (*src && (dst < last)) {
+        char16_t s = dtohs(*src);
+        *dst++ = s;
+        src++;
+    }
+    *dst = 0;
+}
+
+static status_t validate_chunk(const ResChunk_header* chunk,
+                               size_t minSize,
+                               const uint8_t* dataEnd,
+                               const char* name)
+{
+    const uint16_t headerSize = dtohs(chunk->headerSize);
+    const uint32_t size = dtohl(chunk->size);
+
+    if (headerSize >= minSize) {
+        if (headerSize <= size) {
+            if (((headerSize|size)&0x3) == 0) {
+                if ((ssize_t)size <= (dataEnd-((const uint8_t*)chunk))) {
+                    return NO_ERROR;
+                }
+                LOGW("%s data size %p extends beyond resource end %p.",
+                     name, (void*)size,
+                     (void*)(dataEnd-((const uint8_t*)chunk)));
+                return BAD_TYPE;
+            }
+            LOGW("%s size 0x%x or headerSize 0x%x is not on an integer boundary.",
+                 name, (int)size, (int)headerSize);
+            return BAD_TYPE;
+        }
+        LOGW("%s size %p is smaller than header size %p.",
+             name, (void*)size, (void*)(int)headerSize);
+        return BAD_TYPE;
+    }
+    LOGW("%s header size %p is too small.",
+         name, (void*)(int)headerSize);
+    return BAD_TYPE;
+}
+
+inline void Res_value::copyFrom_dtoh(const Res_value& src)
+{
+    size = dtohs(src.size);
+    res0 = src.res0;
+    dataType = src.dataType;
+    data = dtohl(src.data);
+}
+
+void Res_png_9patch::deviceToFile()
+{
+    for (int i = 0; i < numXDivs; i++) {
+        xDivs[i] = htonl(xDivs[i]);
+    }
+    for (int i = 0; i < numYDivs; i++) {
+        yDivs[i] = htonl(yDivs[i]);
+    }
+    paddingLeft = htonl(paddingLeft);
+    paddingRight = htonl(paddingRight);
+    paddingTop = htonl(paddingTop);
+    paddingBottom = htonl(paddingBottom);
+    for (int i=0; i<numColors; i++) {
+        colors[i] = htonl(colors[i]);
+    }
+}
+
+void Res_png_9patch::fileToDevice()
+{
+    for (int i = 0; i < numXDivs; i++) {
+        xDivs[i] = ntohl(xDivs[i]);
+    }
+    for (int i = 0; i < numYDivs; i++) {
+        yDivs[i] = ntohl(yDivs[i]);
+    }
+    paddingLeft = ntohl(paddingLeft);
+    paddingRight = ntohl(paddingRight);
+    paddingTop = ntohl(paddingTop);
+    paddingBottom = ntohl(paddingBottom);
+    for (int i=0; i<numColors; i++) {
+        colors[i] = ntohl(colors[i]);
+    }
+}
+
+size_t Res_png_9patch::serializedSize()
+{
+    // The size of this struct is 32 bytes on the 32-bit target system
+    // 4 * int8_t
+    // 4 * int32_t
+    // 3 * pointer
+    return 32
+            + numXDivs * sizeof(int32_t)
+            + numYDivs * sizeof(int32_t)
+            + numColors * sizeof(uint32_t);
+}
+
+void* Res_png_9patch::serialize()
+{
+    void* newData = malloc(serializedSize());
+    serialize(newData);
+    return newData;
+}
+
+void Res_png_9patch::serialize(void * outData)
+{
+    char* data = (char*) outData;
+    memmove(data, &wasDeserialized, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
+    memmove(data + 12, &paddingLeft, 16);   // copy paddingXXXX
+    data += 32;
+
+    memmove(data, this->xDivs, numXDivs * sizeof(int32_t));
+    data +=  numXDivs * sizeof(int32_t);
+    memmove(data, this->yDivs, numYDivs * sizeof(int32_t));
+    data +=  numYDivs * sizeof(int32_t);
+    memmove(data, this->colors, numColors * sizeof(uint32_t));
+}
+
+static void deserializeInternal(const void* inData, Res_png_9patch* outData) {
+    char* patch = (char*) inData;
+    if (inData != outData) {
+        memmove(&outData->wasDeserialized, patch, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
+        memmove(&outData->paddingLeft, patch + 12, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
+    }
+    outData->wasDeserialized = true;
+    char* data = (char*)outData;
+    data +=  sizeof(Res_png_9patch);
+    outData->xDivs = (int32_t*) data;
+    data +=  outData->numXDivs * sizeof(int32_t);
+    outData->yDivs = (int32_t*) data;
+    data +=  outData->numYDivs * sizeof(int32_t);
+    outData->colors = (uint32_t*) data;
+}
+
+Res_png_9patch* Res_png_9patch::deserialize(const void* inData)
+{
+    if (sizeof(void*) != sizeof(int32_t)) {
+        LOGE("Cannot deserialize on non 32-bit system\n");
+        return NULL;
+    }
+    deserializeInternal(inData, (Res_png_9patch*) inData);
+    return (Res_png_9patch*) inData;
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+ResStringPool::ResStringPool()
+    : mError(NO_INIT), mOwnedData(NULL)
+{
+}
+
+ResStringPool::ResStringPool(const void* data, size_t size, bool copyData)
+    : mError(NO_INIT), mOwnedData(NULL)
+{
+    setTo(data, size, copyData);
+}
+
+ResStringPool::~ResStringPool()
+{
+    uninit();
+}
+
+status_t ResStringPool::setTo(const void* data, size_t size, bool copyData)
+{
+    if (!data || !size) {
+        return (mError=BAD_TYPE);
+    }
+
+    uninit();
+
+    const bool notDeviceEndian = htods(0xf0) != 0xf0;
+
+    if (copyData || notDeviceEndian) {
+        mOwnedData = malloc(size);
+        if (mOwnedData == NULL) {
+            return (mError=NO_MEMORY);
+        }
+        memcpy(mOwnedData, data, size);
+        data = mOwnedData;
+    }
+
+    mHeader = (const ResStringPool_header*)data;
+
+    if (notDeviceEndian) {
+        ResStringPool_header* h = const_cast<ResStringPool_header*>(mHeader);
+        h->header.headerSize = dtohs(mHeader->header.headerSize);
+        h->header.type = dtohs(mHeader->header.type);
+        h->header.size = dtohl(mHeader->header.size);
+        h->stringCount = dtohl(mHeader->stringCount);
+        h->styleCount = dtohl(mHeader->styleCount);
+        h->flags = dtohl(mHeader->flags);
+        h->stringsStart = dtohl(mHeader->stringsStart);
+        h->stylesStart = dtohl(mHeader->stylesStart);
+    }
+
+    if (mHeader->header.headerSize > mHeader->header.size
+            || mHeader->header.size > size) {
+        LOGW("Bad string block: header size %d or total size %d is larger than data size %d\n",
+                (int)mHeader->header.headerSize, (int)mHeader->header.size, (int)size);
+        return (mError=BAD_TYPE);
+    }
+    mSize = mHeader->header.size;
+    mEntries = (const uint32_t*)
+        (((const uint8_t*)data)+mHeader->header.headerSize);
+
+    if (mHeader->stringCount > 0) {
+        if ((mHeader->stringCount*sizeof(uint32_t) < mHeader->stringCount)  // uint32 overflow?
+            || (mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t)))
+                > size) {
+            LOGW("Bad string block: entry of %d items extends past data size %d\n",
+                    (int)(mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t))),
+                    (int)size);
+            return (mError=BAD_TYPE);
+        }
+        mStrings = (const char16_t*)
+            (((const uint8_t*)data)+mHeader->stringsStart);
+        if (mHeader->stringsStart >= (mHeader->header.size-sizeof(uint16_t))) {
+            LOGW("Bad string block: string pool starts at %d, after total size %d\n",
+                    (int)mHeader->stringsStart, (int)mHeader->header.size);
+            return (mError=BAD_TYPE);
+        }
+        if (mHeader->styleCount == 0) {
+            mStringPoolSize =
+                (mHeader->header.size-mHeader->stringsStart)/sizeof(uint16_t);
+        } else {
+            // check invariant: styles follow the strings
+            if (mHeader->stylesStart <= mHeader->stringsStart) {
+                LOGW("Bad style block: style block starts at %d, before strings at %d\n",
+                    (int)mHeader->stylesStart, (int)mHeader->stringsStart);
+                return (mError=BAD_TYPE);
+            }
+            mStringPoolSize =
+                (mHeader->stylesStart-mHeader->stringsStart)/sizeof(uint16_t);
+        }
+
+        // check invariant: stringCount > 0 requires a string pool to exist
+        if (mStringPoolSize == 0) {
+            LOGW("Bad string block: stringCount is %d but pool size is 0\n", (int)mHeader->stringCount);
+            return (mError=BAD_TYPE);
+        }
+
+        if (notDeviceEndian) {
+            size_t i;
+            uint32_t* e = const_cast<uint32_t*>(mEntries);
+            for (i=0; i<mHeader->stringCount; i++) {
+                e[i] = dtohl(mEntries[i]);
+            }
+            char16_t* s = const_cast<char16_t*>(mStrings);
+            for (i=0; i<mStringPoolSize; i++) {
+                s[i] = dtohs(mStrings[i]);
+            }
+        }
+
+        if (mStrings[mStringPoolSize-1] != 0) {
+            LOGW("Bad string block: last string is not 0-terminated\n");
+            return (mError=BAD_TYPE);
+        }
+    } else {
+        mStrings = NULL;
+        mStringPoolSize = 0;
+    }
+
+    if (mHeader->styleCount > 0) {
+        mEntryStyles = mEntries + mHeader->stringCount;
+        // invariant: integer overflow in calculating mEntryStyles
+        if (mEntryStyles < mEntries) {
+            LOGW("Bad string block: integer overflow finding styles\n");
+            return (mError=BAD_TYPE);
+        }
+
+        if (((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader) > (int)size) {
+            LOGW("Bad string block: entry of %d styles extends past data size %d\n",
+                    (int)((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader),
+                    (int)size);
+            return (mError=BAD_TYPE);
+        }
+        mStyles = (const uint32_t*)
+            (((const uint8_t*)data)+mHeader->stylesStart);
+        if (mHeader->stylesStart >= mHeader->header.size) {
+            LOGW("Bad string block: style pool starts %d, after total size %d\n",
+                    (int)mHeader->stylesStart, (int)mHeader->header.size);
+            return (mError=BAD_TYPE);
+        }
+        mStylePoolSize =
+            (mHeader->header.size-mHeader->stylesStart)/sizeof(uint32_t);
+
+        if (notDeviceEndian) {
+            size_t i;
+            uint32_t* e = const_cast<uint32_t*>(mEntryStyles);
+            for (i=0; i<mHeader->styleCount; i++) {
+                e[i] = dtohl(mEntryStyles[i]);
+            }
+            uint32_t* s = const_cast<uint32_t*>(mStyles);
+            for (i=0; i<mStylePoolSize; i++) {
+                s[i] = dtohl(mStyles[i]);
+            }
+        }
+
+        const ResStringPool_span endSpan = {
+            { htodl(ResStringPool_span::END) },
+            htodl(ResStringPool_span::END), htodl(ResStringPool_span::END)
+        };
+        if (memcmp(&mStyles[mStylePoolSize-(sizeof(endSpan)/sizeof(uint32_t))],
+                   &endSpan, sizeof(endSpan)) != 0) {
+            LOGW("Bad string block: last style is not 0xFFFFFFFF-terminated\n");
+            return (mError=BAD_TYPE);
+        }
+    } else {
+        mEntryStyles = NULL;
+        mStyles = NULL;
+        mStylePoolSize = 0;
+    }
+
+    return (mError=NO_ERROR);
+}
+
+status_t ResStringPool::getError() const
+{
+    return mError;
+}
+
+void ResStringPool::uninit()
+{
+    mError = NO_INIT;
+    if (mOwnedData) {
+        free(mOwnedData);
+        mOwnedData = NULL;
+    }
+}
+
+const uint16_t* ResStringPool::stringAt(size_t idx, size_t* outLen) const
+{
+    if (mError == NO_ERROR && idx < mHeader->stringCount) {
+        const uint32_t off = (mEntries[idx]/sizeof(uint16_t));
+        if (off < (mStringPoolSize-1)) {
+            const char16_t* str = mStrings+off;
+            *outLen = *str;
+            if ((*str)&0x8000) {
+                str++;
+                *outLen = (((*outLen)&0x7fff)<<16) + *str;
+            }
+            if ((uint32_t)(str+1+*outLen-mStrings) < mStringPoolSize) {
+                return str+1;
+            } else {
+                LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
+                        (int)idx, (int)(str+1+*outLen-mStrings), (int)mStringPoolSize);
+            }
+        } else {
+            LOGW("Bad string block: string #%d entry is at %d, past end at %d\n",
+                    (int)idx, (int)(off*sizeof(uint16_t)),
+                    (int)(mStringPoolSize*sizeof(uint16_t)));
+        }
+    }
+    return NULL;
+}
+
+const ResStringPool_span* ResStringPool::styleAt(const ResStringPool_ref& ref) const
+{
+    return styleAt(ref.index);
+}
+
+const ResStringPool_span* ResStringPool::styleAt(size_t idx) const
+{
+    if (mError == NO_ERROR && idx < mHeader->styleCount) {
+        const uint32_t off = (mEntryStyles[idx]/sizeof(uint32_t));
+        if (off < mStylePoolSize) {
+            return (const ResStringPool_span*)(mStyles+off);
+        } else {
+            LOGW("Bad string block: style #%d entry is at %d, past end at %d\n",
+                    (int)idx, (int)(off*sizeof(uint32_t)),
+                    (int)(mStylePoolSize*sizeof(uint32_t)));
+        }
+    }
+    return NULL;
+}
+
+ssize_t ResStringPool::indexOfString(const char16_t* str, size_t strLen) const
+{
+    if (mError != NO_ERROR) {
+        return mError;
+    }
+
+    size_t len;
+
+    if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
+        // Do a binary search for the string...
+        ssize_t l = 0;
+        ssize_t h = mHeader->stringCount-1;
+
+        ssize_t mid;
+        while (l <= h) {
+            mid = l + (h - l)/2;
+            const char16_t* s = stringAt(mid, &len);
+            int c = s ? strzcmp16(s, len, str, strLen) : -1;
+            POOL_NOISY(printf("Looking for %s, at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
+                         String8(str).string(),
+                         String8(s).string(),
+                         c, (int)l, (int)mid, (int)h));
+            if (c == 0) {
+                return mid;
+            } else if (c < 0) {
+                l = mid + 1;
+            } else {
+                h = mid - 1;
+            }
+        }
+    } else {
+        // It is unusual to get the ID from an unsorted string block...
+        // most often this happens because we want to get IDs for style
+        // span tags; since those always appear at the end of the string
+        // block, start searching at the back.
+        for (int i=mHeader->stringCount-1; i>=0; i--) {
+            const char16_t* s = stringAt(i, &len);
+            POOL_NOISY(printf("Looking for %s, at %s, i=%d\n",
+                         String8(str, strLen).string(),
+                         String8(s).string(),
+                         i));
+            if (s && strzcmp16(s, len, str, strLen) == 0) {
+                return i;
+            }
+        }
+    }
+
+    return NAME_NOT_FOUND;
+}
+
+size_t ResStringPool::size() const
+{
+    return (mError == NO_ERROR) ? mHeader->stringCount : 0;
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+ResXMLParser::ResXMLParser(const ResXMLTree& tree)
+    : mTree(tree), mEventCode(BAD_DOCUMENT)
+{
+}
+
+void ResXMLParser::restart()
+{
+    mCurNode = NULL;
+    mEventCode = mTree.mError == NO_ERROR ? START_DOCUMENT : BAD_DOCUMENT;
+}
+
+ResXMLParser::event_code_t ResXMLParser::getEventType() const
+{
+    return mEventCode;
+}
+
+ResXMLParser::event_code_t ResXMLParser::next()
+{
+    if (mEventCode == START_DOCUMENT) {
+        mCurNode = mTree.mRootNode;
+        mCurExt = mTree.mRootExt;
+        return (mEventCode=mTree.mRootCode);
+    } else if (mEventCode >= FIRST_CHUNK_CODE) {
+        return nextNode();
+    }
+    return mEventCode;
+}
+
+const int32_t ResXMLParser::getCommentID() const
+{
+    return mCurNode != NULL ? dtohl(mCurNode->comment.index) : -1;
+}
+
+const uint16_t* ResXMLParser::getComment(size_t* outLen) const
+{
+    int32_t id = getCommentID();
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const uint32_t ResXMLParser::getLineNumber() const
+{
+    return mCurNode != NULL ? dtohl(mCurNode->lineNumber) : -1;
+}
+
+const int32_t ResXMLParser::getTextID() const
+{
+    if (mEventCode == TEXT) {
+        return dtohl(((const ResXMLTree_cdataExt*)mCurExt)->data.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getText(size_t* outLen) const
+{
+    int32_t id = getTextID();
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+ssize_t ResXMLParser::getTextValue(Res_value* outValue) const
+{
+    if (mEventCode == TEXT) {
+        outValue->copyFrom_dtoh(((const ResXMLTree_cdataExt*)mCurExt)->typedData);
+        return sizeof(Res_value);
+    }
+    return BAD_TYPE;
+}
+
+const int32_t ResXMLParser::getNamespacePrefixID() const
+{
+    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {
+        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->prefix.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const
+{
+    int32_t id = getNamespacePrefixID();
+    //printf("prefix=%d  event=%p\n", id, mEventCode);
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const int32_t ResXMLParser::getNamespaceUriID() const
+{
+    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {
+        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->uri.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const
+{
+    int32_t id = getNamespaceUriID();
+    //printf("uri=%d  event=%p\n", id, mEventCode);
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const int32_t ResXMLParser::getElementNamespaceID() const
+{
+    if (mEventCode == START_TAG) {
+        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->ns.index);
+    }
+    if (mEventCode == END_TAG) {
+        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->ns.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getElementNamespace(size_t* outLen) const
+{
+    int32_t id = getElementNamespaceID();
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const int32_t ResXMLParser::getElementNameID() const
+{
+    if (mEventCode == START_TAG) {
+        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->name.index);
+    }
+    if (mEventCode == END_TAG) {
+        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->name.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getElementName(size_t* outLen) const
+{
+    int32_t id = getElementNameID();
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+size_t ResXMLParser::getAttributeCount() const
+{
+    if (mEventCode == START_TAG) {
+        return dtohs(((const ResXMLTree_attrExt*)mCurExt)->attributeCount);
+    }
+    return 0;
+}
+
+const int32_t ResXMLParser::getAttributeNamespaceID(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return dtohl(attr->ns.index);
+        }
+    }
+    return -2;
+}
+
+const uint16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) const
+{
+    int32_t id = getAttributeNamespaceID(idx);
+    //printf("attribute namespace=%d  idx=%d  event=%p\n", id, idx, mEventCode);
+    //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id));
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const int32_t ResXMLParser::getAttributeNameID(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return dtohl(attr->name.index);
+        }
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const
+{
+    int32_t id = getAttributeNameID(idx);
+    //printf("attribute name=%d  idx=%d  event=%p\n", id, idx, mEventCode);
+    //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id));
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const uint32_t ResXMLParser::getAttributeNameResID(size_t idx) const
+{
+    int32_t id = getAttributeNameID(idx);
+    if (id >= 0 && (size_t)id < mTree.mNumResIds) {
+        return dtohl(mTree.mResIds[id]);
+    }
+    return 0;
+}
+
+const int32_t ResXMLParser::getAttributeValueStringID(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return dtohl(attr->rawValue.index);
+        }
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen) const
+{
+    int32_t id = getAttributeValueStringID(idx);
+    //XML_NOISY(printf("getAttributeValue 0x%x=0x%x\n", idx, id));
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+int32_t ResXMLParser::getAttributeDataType(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return attr->typedValue.dataType;
+        }
+    }
+    return Res_value::TYPE_NULL;
+}
+
+int32_t ResXMLParser::getAttributeData(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return dtohl(attr->typedValue.data);
+        }
+    }
+    return 0;
+}
+
+ssize_t ResXMLParser::getAttributeValue(size_t idx, Res_value* outValue) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            outValue->copyFrom_dtoh(attr->typedValue);
+            return sizeof(Res_value);
+        }
+    }
+    return BAD_TYPE;
+}
+
+ssize_t ResXMLParser::indexOfAttribute(const char* ns, const char* attr) const
+{
+    String16 nsStr(ns != NULL ? ns : "");
+    String16 attrStr(attr);
+    return indexOfAttribute(ns ? nsStr.string() : NULL, ns ? nsStr.size() : 0,
+                            attrStr.string(), attrStr.size());
+}
+
+ssize_t ResXMLParser::indexOfAttribute(const char16_t* ns, size_t nsLen,
+                                       const char16_t* attr, size_t attrLen) const
+{
+    if (mEventCode == START_TAG) {
+        const size_t N = getAttributeCount();
+        for (size_t i=0; i<N; i++) {
+            size_t curNsLen, curAttrLen;
+            const char16_t* curNs = getAttributeNamespace(i, &curNsLen);
+            const char16_t* curAttr = getAttributeName(i, &curAttrLen);
+            //printf("%d: ns=%p attr=%p curNs=%p curAttr=%p\n",
+            //       i, ns, attr, curNs, curAttr);
+            //printf(" --> attr=%s, curAttr=%s\n",
+            //       String8(attr).string(), String8(curAttr).string());
+            if (attr && curAttr && (strzcmp16(attr, attrLen, curAttr, curAttrLen) == 0)) {
+                if (ns == NULL) {
+                    if (curNs == NULL) return i;
+                } else if (curNs != NULL) {
+                    //printf(" --> ns=%s, curNs=%s\n",
+                    //       String8(ns).string(), String8(curNs).string());
+                    if (strzcmp16(ns, nsLen, curNs, curNsLen) == 0) return i;
+                }
+            }
+        }
+    }
+
+    return NAME_NOT_FOUND;
+}
+
+ssize_t ResXMLParser::indexOfID() const
+{
+    if (mEventCode == START_TAG) {
+        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->idIndex);
+        if (idx > 0) return (idx-1);
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t ResXMLParser::indexOfClass() const
+{
+    if (mEventCode == START_TAG) {
+        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->classIndex);
+        if (idx > 0) return (idx-1);
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t ResXMLParser::indexOfStyle() const
+{
+    if (mEventCode == START_TAG) {
+        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->styleIndex);
+        if (idx > 0) return (idx-1);
+    }
+    return NAME_NOT_FOUND;
+}
+
+ResXMLParser::event_code_t ResXMLParser::nextNode()
+{
+    if (mEventCode < 0) {
+        return mEventCode;
+    }
+
+    do {
+        const ResXMLTree_node* next = (const ResXMLTree_node*)
+            (((const uint8_t*)mCurNode) + dtohl(mCurNode->header.size));
+        //LOGW("Next node: prev=%p, next=%p\n", mCurNode, next);
+        
+        if (((const uint8_t*)next) >= mTree.mDataEnd) {
+            mCurNode = NULL;
+            return (mEventCode=END_DOCUMENT);
+        }
+
+        if (mTree.validateNode(next) != NO_ERROR) {
+            mCurNode = NULL;
+            return (mEventCode=BAD_DOCUMENT);
+        }
+
+        mCurNode = next;
+        const uint16_t headerSize = dtohs(next->header.headerSize);
+        const uint32_t totalSize = dtohl(next->header.size);
+        mCurExt = ((const uint8_t*)next) + headerSize;
+        size_t minExtSize = 0;
+        event_code_t eventCode = (event_code_t)dtohs(next->header.type);
+        switch ((mEventCode=eventCode)) {
+            case RES_XML_START_NAMESPACE_TYPE:
+            case RES_XML_END_NAMESPACE_TYPE:
+                minExtSize = sizeof(ResXMLTree_namespaceExt);
+                break;
+            case RES_XML_START_ELEMENT_TYPE:
+                minExtSize = sizeof(ResXMLTree_attrExt);
+                break;
+            case RES_XML_END_ELEMENT_TYPE:
+                minExtSize = sizeof(ResXMLTree_endElementExt);
+                break;
+            case RES_XML_CDATA_TYPE:
+                minExtSize = sizeof(ResXMLTree_cdataExt);
+                break;
+            default:
+                LOGW("Unknown XML block: header type %d in node at %d\n",
+                     (int)dtohs(next->header.type),
+                     (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)));
+                continue;
+        }
+        
+        if ((totalSize-headerSize) < minExtSize) {
+            LOGW("Bad XML block: header type 0x%x in node at 0x%x has size %d, need %d\n",
+                 (int)dtohs(next->header.type),
+                 (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)),
+                 (int)(totalSize-headerSize), (int)minExtSize);
+            return (mEventCode=BAD_DOCUMENT);
+        }
+        
+        //printf("CurNode=%p, CurExt=%p, headerSize=%d, minExtSize=%d\n",
+        //       mCurNode, mCurExt, headerSize, minExtSize);
+        
+        return eventCode;
+    } while (true);
+}
+
+void ResXMLParser::getPosition(ResXMLParser::ResXMLPosition* pos) const
+{
+    pos->eventCode = mEventCode;
+    pos->curNode = mCurNode;
+    pos->curExt = mCurExt;
+}
+
+void ResXMLParser::setPosition(const ResXMLParser::ResXMLPosition& pos)
+{
+    mEventCode = pos.eventCode;
+    mCurNode = pos.curNode;
+    mCurExt = pos.curExt;
+}
+
+
+// --------------------------------------------------------------------
+
+static volatile int32_t gCount = 0;
+
+ResXMLTree::ResXMLTree()
+    : ResXMLParser(*this)
+    , mError(NO_INIT), mOwnedData(NULL)
+{
+    //LOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
+    restart();
+}
+
+ResXMLTree::ResXMLTree(const void* data, size_t size, bool copyData)
+    : ResXMLParser(*this)
+    , mError(NO_INIT), mOwnedData(NULL)
+{
+    //LOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
+    setTo(data, size, copyData);
+}
+
+ResXMLTree::~ResXMLTree()
+{
+    //LOGI("Destroying ResXMLTree in %p #%d\n", this, android_atomic_dec(&gCount)-1);
+    uninit();
+}
+
+status_t ResXMLTree::setTo(const void* data, size_t size, bool copyData)
+{
+    uninit();
+    mEventCode = START_DOCUMENT;
+
+    if (copyData) {
+        mOwnedData = malloc(size);
+        if (mOwnedData == NULL) {
+            return (mError=NO_MEMORY);
+        }
+        memcpy(mOwnedData, data, size);
+        data = mOwnedData;
+    }
+
+    mHeader = (const ResXMLTree_header*)data;
+    mSize = dtohl(mHeader->header.size);
+    if (dtohs(mHeader->header.headerSize) > mSize || mSize > size) {
+        LOGW("Bad XML block: header size %d or total size %d is larger than data size %d\n",
+             (int)dtohs(mHeader->header.headerSize),
+             (int)dtohl(mHeader->header.size), (int)size);
+        mError = BAD_TYPE;
+        restart();
+        return mError;
+    }
+    mDataEnd = ((const uint8_t*)mHeader) + mSize;
+
+    mStrings.uninit();
+    mRootNode = NULL;
+    mResIds = NULL;
+    mNumResIds = 0;
+
+    // First look for a couple interesting chunks: the string block
+    // and first XML node.
+    const ResChunk_header* chunk =
+        (const ResChunk_header*)(((const uint8_t*)mHeader) + dtohs(mHeader->header.headerSize));
+    const ResChunk_header* lastChunk = chunk;
+    while (((const uint8_t*)chunk) < (mDataEnd-sizeof(ResChunk_header)) &&
+           ((const uint8_t*)chunk) < (mDataEnd-dtohl(chunk->size))) {
+        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), mDataEnd, "XML");
+        if (err != NO_ERROR) {
+            mError = err;
+            goto done;
+        }
+        const uint16_t type = dtohs(chunk->type);
+        const size_t size = dtohl(chunk->size);
+        XML_NOISY(printf("Scanning @ %p: type=0x%x, size=0x%x\n",
+                     (void*)(((uint32_t)chunk)-((uint32_t)mHeader)), type, size));
+        if (type == RES_STRING_POOL_TYPE) {
+            mStrings.setTo(chunk, size);
+        } else if (type == RES_XML_RESOURCE_MAP_TYPE) {
+            mResIds = (const uint32_t*)
+                (((const uint8_t*)chunk)+dtohs(chunk->headerSize));
+            mNumResIds = (dtohl(chunk->size)-dtohs(chunk->headerSize))/sizeof(uint32_t);
+        } else if (type >= RES_XML_FIRST_CHUNK_TYPE
+                   && type <= RES_XML_LAST_CHUNK_TYPE) {
+            if (validateNode((const ResXMLTree_node*)chunk) != NO_ERROR) {
+                mError = BAD_TYPE;
+                goto done;
+            }
+            mCurNode = (const ResXMLTree_node*)lastChunk;
+            if (nextNode() == BAD_DOCUMENT) {
+                mError = BAD_TYPE;
+                goto done;
+            }
+            mRootNode = mCurNode;
+            mRootExt = mCurExt;
+            mRootCode = mEventCode;
+            break;
+        } else {
+            XML_NOISY(printf("Skipping unknown chunk!\n"));
+        }
+        lastChunk = chunk;
+        chunk = (const ResChunk_header*)
+            (((const uint8_t*)chunk) + size);
+    }
+
+    if (mRootNode == NULL) {
+        LOGW("Bad XML block: no root element node found\n");
+        mError = BAD_TYPE;
+        goto done;
+    }
+
+    mError = mStrings.getError();
+
+done:
+    restart();
+    return mError;
+}
+
+status_t ResXMLTree::getError() const
+{
+    return mError;
+}
+
+void ResXMLTree::uninit()
+{
+    mError = NO_INIT;
+    if (mOwnedData) {
+        free(mOwnedData);
+        mOwnedData = NULL;
+    }
+    restart();
+}
+
+const ResStringPool& ResXMLTree::getStrings() const
+{
+    return mStrings;
+}
+
+status_t ResXMLTree::validateNode(const ResXMLTree_node* node) const
+{
+    const uint16_t eventCode = dtohs(node->header.type);
+
+    status_t err = validate_chunk(
+        &node->header, sizeof(ResXMLTree_node),
+        mDataEnd, "ResXMLTree_node");
+
+    if (err >= NO_ERROR) {
+        // Only perform additional validation on START nodes
+        if (eventCode != RES_XML_START_ELEMENT_TYPE) {
+            return NO_ERROR;
+        }
+
+        const uint16_t headerSize = dtohs(node->header.headerSize);
+        const uint32_t size = dtohl(node->header.size);
+        const ResXMLTree_attrExt* attrExt = (const ResXMLTree_attrExt*)
+            (((const uint8_t*)node) + headerSize);
+        // check for sensical values pulled out of the stream so far...
+        if ((size >= headerSize + sizeof(ResXMLTree_attrExt))
+                && ((void*)attrExt > (void*)node)) {
+            const size_t attrSize = ((size_t)dtohs(attrExt->attributeSize))
+                * dtohs(attrExt->attributeCount);
+            if ((dtohs(attrExt->attributeStart)+attrSize) <= (size-headerSize)) {
+                return NO_ERROR;
+            }
+            LOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n",
+                    (unsigned int)(dtohs(attrExt->attributeStart)+attrSize),
+                    (unsigned int)(size-headerSize));
+        }
+        else {
+            LOGW("Bad XML start block: node header size 0x%x, size 0x%x\n",
+                (unsigned int)headerSize, (unsigned int)size);
+        }
+        return BAD_TYPE;
+    }
+
+    return err;
+
+#if 0
+    const bool isStart = dtohs(node->header.type) == RES_XML_START_ELEMENT_TYPE;
+
+    const uint16_t headerSize = dtohs(node->header.headerSize);
+    const uint32_t size = dtohl(node->header.size);
+
+    if (headerSize >= (isStart ? sizeof(ResXMLTree_attrNode) : sizeof(ResXMLTree_node))) {
+        if (size >= headerSize) {
+            if (((const uint8_t*)node) <= (mDataEnd-size)) {
+                if (!isStart) {
+                    return NO_ERROR;
+                }
+                if ((((size_t)dtohs(node->attributeSize))*dtohs(node->attributeCount))
+                        <= (size-headerSize)) {
+                    return NO_ERROR;
+                }
+                LOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n",
+                        ((int)dtohs(node->attributeSize))*dtohs(node->attributeCount),
+                        (int)(size-headerSize));
+                return BAD_TYPE;
+            }
+            LOGW("Bad XML block: node at 0x%x extends beyond data end 0x%x\n",
+                    (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), (int)mSize);
+            return BAD_TYPE;
+        }
+        LOGW("Bad XML block: node at 0x%x header size 0x%x smaller than total size 0x%x\n",
+                (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),
+                (int)headerSize, (int)size);
+        return BAD_TYPE;
+    }
+    LOGW("Bad XML block: node at 0x%x header size 0x%x too small\n",
+            (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),
+            (int)headerSize);
+    return BAD_TYPE;
+#endif
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+struct ResTable::Header
+{
+    Header() : ownedData(NULL), header(NULL) { }
+
+    void*                           ownedData;
+    const ResTable_header*          header;
+    size_t                          size;
+    const uint8_t*                  dataEnd;
+    size_t                          index;
+    void*                           cookie;
+
+    ResStringPool                   values;
+};
+
+struct ResTable::Type
+{
+    Type(const Header* _header, const Package* _package, size_t count)
+        : header(_header), package(_package), entryCount(count),
+          typeSpec(NULL), typeSpecFlags(NULL) { }
+    const Header* const             header;
+    const Package* const            package;
+    const size_t                    entryCount;
+    const ResTable_typeSpec*        typeSpec;
+    const uint32_t*                 typeSpecFlags;
+    Vector<const ResTable_type*>    configs;
+};
+
+struct ResTable::Package
+{
+    Package(const Header* _header, const ResTable_package* _package)
+        : header(_header), package(_package) { }
+    ~Package()
+    {
+        size_t i = types.size();
+        while (i > 0) {
+            i--;
+            delete types[i];
+        }
+    }
+    
+    const Header* const             header;
+    const ResTable_package* const   package;
+    Vector<Type*>                   types;
+
+    const Type* getType(size_t idx) const {
+        return idx < types.size() ? types[idx] : NULL;
+    }
+};
+
+// A group of objects describing a particular resource package.
+// The first in 'package' is always the root object (from the resource
+// table that defined the package); the ones after are skins on top of it.
+struct ResTable::PackageGroup
+{
+    PackageGroup(const String16& _name, uint32_t _id)
+        : name(_name), id(_id), typeCount(0), bags(NULL) { }
+    ~PackageGroup() {
+        clearBagCache();
+        const size_t N = packages.size();
+        for (size_t i=0; i<N; i++) {
+            delete packages[i];
+        }
+    }
+
+    void clearBagCache() {
+        if (bags) {
+            TABLE_NOISY(printf("bags=%p\n", bags));
+            Package* pkg = packages[0];
+            TABLE_NOISY(printf("typeCount=%x\n", typeCount));
+            for (size_t i=0; i<typeCount; i++) {
+                TABLE_NOISY(printf("type=%d\n", i));
+                const Type* type = pkg->getType(i);
+                if (type != NULL) {
+                    bag_set** typeBags = bags[i];
+                    TABLE_NOISY(printf("typeBags=%p\n", typeBags));
+                    if (typeBags) {
+                        TABLE_NOISY(printf("type->entryCount=%x\n", type->entryCount));
+                        const size_t N = type->entryCount;
+                        for (size_t j=0; j<N; j++) {
+                            if (typeBags[j] && typeBags[j] != (bag_set*)0xFFFFFFFF)
+                                free(typeBags[j]);
+                        }
+                        free(typeBags);
+                    }
+                }
+            }
+            free(bags);
+            bags = NULL;
+        }
+    }
+    
+    String16 const                  name;
+    uint32_t const                  id;
+    Vector<Package*>                packages;
+
+    // Taken from the root package.
+    ResStringPool                   typeStrings;
+    ResStringPool                   keyStrings;
+    size_t                          typeCount;
+
+    // Computed attribute bags, first indexed by the type and second
+    // by the entry in that type.
+    bag_set***                      bags;
+};
+
+struct ResTable::bag_set
+{
+    size_t numAttrs;    // number in array
+    size_t availAttrs;  // total space in array
+    uint32_t typeSpecFlags;
+    // Followed by 'numAttr' bag_entry structures.
+};
+
+ResTable::Theme::Theme(const ResTable& table)
+    : mTable(table)
+{
+    memset(mPackages, 0, sizeof(mPackages));
+}
+
+ResTable::Theme::~Theme()
+{
+    for (size_t i=0; i<Res_MAXPACKAGE; i++) {
+        package_info* pi = mPackages[i];
+        if (pi != NULL) {
+            free_package(pi);
+        }
+    }
+}
+
+void ResTable::Theme::free_package(package_info* pi)
+{
+    for (size_t j=0; j<pi->numTypes; j++) {
+        theme_entry* te = pi->types[j].entries;
+        if (te != NULL) {
+            free(te);
+        }
+    }
+    free(pi);
+}
+
+ResTable::Theme::package_info* ResTable::Theme::copy_package(package_info* pi)
+{
+    package_info* newpi = (package_info*)malloc(
+        sizeof(package_info) + (pi->numTypes*sizeof(type_info)));
+    newpi->numTypes = pi->numTypes;
+    for (size_t j=0; j<newpi->numTypes; j++) {
+        size_t cnt = pi->types[j].numEntries;
+        newpi->types[j].numEntries = cnt;
+        theme_entry* te = pi->types[j].entries;
+        if (te != NULL) {
+            theme_entry* newte = (theme_entry*)malloc(cnt*sizeof(theme_entry));
+            newpi->types[j].entries = newte;
+            memcpy(newte, te, cnt*sizeof(theme_entry));
+        } else {
+            newpi->types[j].entries = NULL;
+        }
+    }
+    return newpi;
+}
+
+status_t ResTable::Theme::applyStyle(uint32_t resID, bool force)
+{
+    const bag_entry* bag;
+    uint32_t bagTypeSpecFlags = 0;
+    mTable.lock();
+    const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags);
+    TABLE_NOISY(LOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
+    if (N < 0) {
+        mTable.unlock();
+        return N;
+    }
+
+    uint32_t curPackage = 0xffffffff;
+    ssize_t curPackageIndex = 0;
+    package_info* curPI = NULL;
+    uint32_t curType = 0xffffffff;
+    size_t numEntries = 0;
+    theme_entry* curEntries = NULL;
+
+    const bag_entry* end = bag + N;
+    while (bag < end) {
+        const uint32_t attrRes = bag->map.name.ident;
+        const uint32_t p = Res_GETPACKAGE(attrRes);
+        const uint32_t t = Res_GETTYPE(attrRes);
+        const uint32_t e = Res_GETENTRY(attrRes);
+
+        if (curPackage != p) {
+            const ssize_t pidx = mTable.getResourcePackageIndex(attrRes);
+            if (pidx < 0) {
+                LOGE("Style contains key with bad package: 0x%08x\n", attrRes);
+                bag++;
+                continue;
+            }
+            curPackage = p;
+            curPackageIndex = pidx;
+            curPI = mPackages[pidx];
+            if (curPI == NULL) {
+                PackageGroup* const grp = mTable.mPackageGroups[pidx];
+                int cnt = grp->typeCount;
+                curPI = (package_info*)malloc(
+                    sizeof(package_info) + (cnt*sizeof(type_info)));
+                curPI->numTypes = cnt;
+                memset(curPI->types, 0, cnt*sizeof(type_info));
+                mPackages[pidx] = curPI;
+            }
+            curType = 0xffffffff;
+        }
+        if (curType != t) {
+            if (t >= curPI->numTypes) {
+                LOGE("Style contains key with bad type: 0x%08x\n", attrRes);
+                bag++;
+                continue;
+            }
+            curType = t;
+            curEntries = curPI->types[t].entries;
+            if (curEntries == NULL) {
+                PackageGroup* const grp = mTable.mPackageGroups[curPackageIndex];
+                const Type* type = grp->packages[0]->getType(t);
+                int cnt = type != NULL ? type->entryCount : 0;
+                curEntries = (theme_entry*)malloc(cnt*sizeof(theme_entry));
+                memset(curEntries, Res_value::TYPE_NULL, cnt*sizeof(theme_entry));
+                curPI->types[t].numEntries = cnt;
+                curPI->types[t].entries = curEntries;
+            }
+            numEntries = curPI->types[t].numEntries;
+        }
+        if (e >= numEntries) {
+            LOGE("Style contains key with bad entry: 0x%08x\n", attrRes);
+            bag++;
+            continue;
+        }
+        theme_entry* curEntry = curEntries + e;
+        TABLE_NOISY(LOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
+                   attrRes, bag->map.value.dataType, bag->map.value.data,
+             curEntry->value.dataType));
+        if (force || curEntry->value.dataType == Res_value::TYPE_NULL) {
+            curEntry->stringBlock = bag->stringBlock;
+            curEntry->typeSpecFlags |= bagTypeSpecFlags;
+            curEntry->value = bag->map.value;
+        }
+
+        bag++;
+    }
+
+    mTable.unlock();
+
+    //LOGI("Applying style 0x%08x (force=%d)  theme %p...\n", resID, force, this);
+    //dumpToLog();
+    
+    return NO_ERROR;
+}
+
+status_t ResTable::Theme::setTo(const Theme& other)
+{
+    //LOGI("Setting theme %p from theme %p...\n", this, &other);
+    //dumpToLog();
+    //other.dumpToLog();
+    
+    if (&mTable == &other.mTable) {
+        for (size_t i=0; i<Res_MAXPACKAGE; i++) {
+            if (mPackages[i] != NULL) {
+                free_package(mPackages[i]);
+            }
+            if (other.mPackages[i] != NULL) {
+                mPackages[i] = copy_package(other.mPackages[i]);
+            } else {
+                mPackages[i] = NULL;
+            }
+        }
+    } else {
+        // @todo: need to really implement this, not just copy
+        // the system package (which is still wrong because it isn't
+        // fixing up resource references).
+        for (size_t i=0; i<Res_MAXPACKAGE; i++) {
+            if (mPackages[i] != NULL) {
+                free_package(mPackages[i]);
+            }
+            if (i == 0 && other.mPackages[i] != NULL) {
+                mPackages[i] = copy_package(other.mPackages[i]);
+            } else {
+                mPackages[i] = NULL;
+            }
+        }
+    }
+
+    //LOGI("Final theme:");
+    //dumpToLog();
+    
+    return NO_ERROR;
+}
+
+ssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue,
+        uint32_t* outTypeSpecFlags) const
+{
+    int cnt = 20;
+
+    if (outTypeSpecFlags != NULL) *outTypeSpecFlags = 0;
+    
+    do {
+        const ssize_t p = mTable.getResourcePackageIndex(resID);
+        const uint32_t t = Res_GETTYPE(resID);
+        const uint32_t e = Res_GETENTRY(resID);
+
+        TABLE_NOISY(LOGV("Looking up attr 0x%08x in theme %p", resID, this));
+
+        if (p >= 0) {
+            const package_info* const pi = mPackages[p];
+            if (pi != NULL) {
+                if (t < pi->numTypes) {
+                    const type_info& ti = pi->types[t];
+                    if (e < ti.numEntries) {
+                        const theme_entry& te = ti.entries[e];
+                            if (outTypeSpecFlags != NULL) {
+                                *outTypeSpecFlags |= te.typeSpecFlags;
+                            }
+                        const uint8_t type = te.value.dataType;
+                        if (type == Res_value::TYPE_ATTRIBUTE) {
+                            if (cnt > 0) {
+                                cnt--;
+                                resID = te.value.data;
+                                continue;
+                            }
+                            LOGW("Too many attribute references, stopped at: 0x%08x\n", resID);
+                            return BAD_INDEX;
+                        } else if (type != Res_value::TYPE_NULL) {
+                            *outValue = te.value;
+                            return te.stringBlock;
+                        }
+                        return BAD_INDEX;
+                    }
+                }
+            }
+        }
+        break;
+
+    } while (true);
+
+    return BAD_INDEX;
+}
+
+ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,
+        ssize_t blockIndex, uint32_t* outLastRef,
+        uint32_t* inoutTypeSpecFlags) const
+{
+    //printf("Resolving type=0x%x\n", inOutValue->dataType);
+    if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
+        uint32_t newTypeSpecFlags;
+        blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags);
+        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags;
+        //printf("Retrieved attribute new type=0x%x\n", inOutValue->dataType);
+        if (blockIndex < 0) {
+            return blockIndex;
+        }
+    }
+    return mTable.resolveReference(inOutValue, blockIndex, outLastRef);
+}
+
+void ResTable::Theme::dumpToLog() const
+{
+    LOGI("Theme %p:\n", this);
+    for (size_t i=0; i<Res_MAXPACKAGE; i++) {
+        package_info* pi = mPackages[i];
+        if (pi == NULL) continue;
+        
+        LOGI("  Package #0x%02x:\n", (int)(i+1));
+        for (size_t j=0; j<pi->numTypes; j++) {
+            type_info& ti = pi->types[j];
+            if (ti.numEntries == 0) continue;
+            
+            LOGI("    Type #0x%02x:\n", (int)(j+1));
+            for (size_t k=0; k<ti.numEntries; k++) {
+                theme_entry& te = ti.entries[k];
+                if (te.value.dataType == Res_value::TYPE_NULL) continue;
+                LOGI("      0x%08x: t=0x%x, d=0x%08x (block=%d)\n",
+                     (int)Res_MAKEID(i, j, k),
+                     te.value.dataType, (int)te.value.data, (int)te.stringBlock);
+            }
+        }
+    }
+}
+
+ResTable::ResTable()
+    : mError(NO_INIT)
+{
+    memset(&mParams, 0, sizeof(mParams));
+    memset(mPackageMap, 0, sizeof(mPackageMap));
+    //LOGI("Creating ResTable %p\n", this);
+}
+
+ResTable::ResTable(const void* data, size_t size, void* cookie, bool copyData)
+    : mError(NO_INIT)
+{
+    memset(&mParams, 0, sizeof(mParams));
+    memset(mPackageMap, 0, sizeof(mPackageMap));
+    add(data, size, cookie, copyData);
+    LOG_FATAL_IF(mError != NO_ERROR, "Error parsing resource table");
+    //LOGI("Creating ResTable %p\n", this);
+}
+
+ResTable::~ResTable()
+{
+    //LOGI("Destroying ResTable in %p\n", this);
+    uninit();
+}
+
+inline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const
+{
+    return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1;
+}
+
+status_t ResTable::add(const void* data, size_t size, void* cookie, bool copyData)
+{
+    return add(data, size, cookie, NULL, copyData);
+}
+
+status_t ResTable::add(Asset* asset, void* cookie, bool copyData)
+{
+    const void* data = asset->getBuffer(true);
+    if (data == NULL) {
+        LOGW("Unable to get buffer of resource asset file");
+        return UNKNOWN_ERROR;
+    }
+    size_t size = (size_t)asset->getLength();
+    return add(data, size, cookie, asset, copyData);
+}
+
+status_t ResTable::add(const void* data, size_t size, void* cookie,
+                       Asset* asset, bool copyData)
+{
+    if (!data) return NO_ERROR;
+    Header* header = new Header;
+    header->index = mHeaders.size();
+    header->cookie = cookie;
+    mHeaders.add(header);
+
+    const bool notDeviceEndian = htods(0xf0) != 0xf0;
+
+    LOAD_TABLE_NOISY(
+        LOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%p, asset=%p, copy=%d\n",
+             data, size, cookie, asset, copyData));
+    
+    if (copyData || notDeviceEndian) {
+        header->ownedData = malloc(size);
+        if (header->ownedData == NULL) {
+            return (mError=NO_MEMORY);
+        }
+        memcpy(header->ownedData, data, size);
+        data = header->ownedData;
+    }
+
+    header->header = (const ResTable_header*)data;
+    header->size = dtohl(header->header->header.size);
+    //LOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header->size,
+    //     dtohl(header->header->header.size), header->header->header.size);
+    LOAD_TABLE_NOISY(LOGV("Loading ResTable @%p:\n", header->header));
+    LOAD_TABLE_NOISY(printHexData(2, header->header, header->size < 256 ? header->size : 256,
+                                  16, 16, 0, false, printToLogFunc));
+    if (dtohs(header->header->header.headerSize) > header->size
+            || header->size > size) {
+        LOGW("Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\n",
+             (int)dtohs(header->header->header.headerSize),
+             (int)header->size, (int)size);
+        return (mError=BAD_TYPE);
+    }
+    if (((dtohs(header->header->header.headerSize)|header->size)&0x3) != 0) {
+        LOGW("Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\n",
+             (int)dtohs(header->header->header.headerSize),
+             (int)header->size);
+        return (mError=BAD_TYPE);
+    }
+    header->dataEnd = ((const uint8_t*)header->header) + header->size;
+
+    // Iterate through all chunks.
+    size_t curPackage = 0;
+
+    const ResChunk_header* chunk =
+        (const ResChunk_header*)(((const uint8_t*)header->header)
+                                 + dtohs(header->header->header.headerSize));
+    while (((const uint8_t*)chunk) <= (header->dataEnd-sizeof(ResChunk_header)) &&
+           ((const uint8_t*)chunk) <= (header->dataEnd-dtohl(chunk->size))) {
+        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), header->dataEnd, "ResTable");
+        if (err != NO_ERROR) {
+            return (mError=err);
+        }
+        TABLE_NOISY(LOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+                     dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
+                     (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
+        const size_t csize = dtohl(chunk->size);
+        const uint16_t ctype = dtohs(chunk->type);
+        if (ctype == RES_STRING_POOL_TYPE) {
+            if (header->values.getError() != NO_ERROR) {
+                // Only use the first string chunk; ignore any others that
+                // may appear.
+                status_t err = header->values.setTo(chunk, csize);
+                if (err != NO_ERROR) {
+                    return (mError=err);
+                }
+            } else {
+                LOGW("Multiple string chunks found in resource table.");
+            }
+        } else if (ctype == RES_TABLE_PACKAGE_TYPE) {
+            if (curPackage >= dtohl(header->header->packageCount)) {
+                LOGW("More package chunks were found than the %d declared in the header.",
+                     dtohl(header->header->packageCount));
+                return (mError=BAD_TYPE);
+            }
+            if (parsePackage((ResTable_package*)chunk, header) != NO_ERROR) {
+                return mError;
+            }
+            curPackage++;
+        } else {
+            LOGW("Unknown chunk type %p in table at %p.\n",
+                 (void*)(int)(ctype),
+                 (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)));
+        }
+        chunk = (const ResChunk_header*)
+            (((const uint8_t*)chunk) + csize);
+    }
+
+    if (curPackage < dtohl(header->header->packageCount)) {
+        LOGW("Fewer package chunks (%d) were found than the %d declared in the header.",
+             (int)curPackage, dtohl(header->header->packageCount));
+        return (mError=BAD_TYPE);
+    }
+    mError = header->values.getError();
+    if (mError != NO_ERROR) {
+        LOGW("No string values found in resource table!");
+    }
+    TABLE_NOISY(LOGV("Returning from add with mError=%d\n", mError));
+    return mError;
+}
+
+status_t ResTable::getError() const
+{
+    return mError;
+}
+
+void ResTable::uninit()
+{
+    mError = NO_INIT;
+    size_t N = mPackageGroups.size();
+    for (size_t i=0; i<N; i++) {
+        PackageGroup* g = mPackageGroups[i];
+        delete g;
+    }
+    N = mHeaders.size();
+    for (size_t i=0; i<N; i++) {
+        Header* header = mHeaders[i];
+        if (header->ownedData) {
+            free(header->ownedData);
+        }
+        delete header;
+    }
+
+    mPackageGroups.clear();
+    mHeaders.clear();
+}
+
+bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const
+{
+    if (mError != NO_ERROR) {
+        return false;
+    }
+
+    const ssize_t p = getResourcePackageIndex(resID);
+    const int t = Res_GETTYPE(resID);
+    const int e = Res_GETENTRY(resID);
+
+    if (p < 0) {
+        LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+        return false;
+    }
+    if (t < 0) {
+        LOGW("No type identifier when getting name for resource number 0x%08x", resID);
+        return false;
+    }
+
+    const PackageGroup* const grp = mPackageGroups[p];
+    if (grp == NULL) {
+        LOGW("Bad identifier when getting name for resource number 0x%08x", resID);
+        return false;
+    }
+    if (grp->packages.size() > 0) {
+        const Package* const package = grp->packages[0];
+
+        const ResTable_type* type;
+        const ResTable_entry* entry;
+        ssize_t offset = getEntry(package, t, e, NULL, &type, &entry, NULL);
+        if (offset <= 0) {
+            return false;
+        }
+
+        outName->package = grp->name.string();
+        outName->packageLen = grp->name.size();
+        outName->type = grp->typeStrings.stringAt(t, &outName->typeLen);
+        outName->name = grp->keyStrings.stringAt(
+            dtohl(entry->key.index), &outName->nameLen);
+        return true;
+    }
+
+    return false;
+}
+
+ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag,
+        uint32_t* outSpecFlags, ResTable_config* outConfig) const
+{
+    if (mError != NO_ERROR) {
+        return mError;
+    }
+
+    const ssize_t p = getResourcePackageIndex(resID);
+    const int t = Res_GETTYPE(resID);
+    const int e = Res_GETENTRY(resID);
+
+    if (p < 0) {
+        LOGW("No package identifier when getting value for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+    if (t < 0) {
+        LOGW("No type identifier when getting value for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+
+    const Res_value* bestValue = NULL;
+    const Package* bestPackage = NULL;
+    ResTable_config bestItem;
+    memset(&bestItem, 0, sizeof(bestItem)); // make the compiler shut up
+
+    if (outSpecFlags != NULL) *outSpecFlags = 0;
+    
+    // Look through all resource packages, starting with the most
+    // recently added.
+    const PackageGroup* const grp = mPackageGroups[p];
+    if (grp == NULL) {
+        LOGW("Bad identifier when getting value for resource number 0x%08x", resID);
+        return false;
+    }
+    size_t ip = grp->packages.size();
+    while (ip > 0) {
+        ip--;
+
+        const Package* const package = grp->packages[ip];
+
+        const ResTable_type* type;
+        const ResTable_entry* entry;
+        const Type* typeClass;
+        ssize_t offset = getEntry(package, t, e, &mParams, &type, &entry, &typeClass);
+        if (offset <= 0) {
+            if (offset < 0) {
+                LOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %d: 0x%08x\n",
+                        resID, t, e, (int)ip, (int)offset);
+                return offset;
+            }
+            continue;
+        }
+
+        if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) != 0) {
+            if (!mayBeBag) {
+                LOGW("Requesting resource %p failed because it is complex\n",
+                     (void*)resID);
+            }
+            continue;
+        }
+
+        TABLE_NOISY(aout << "Resource type data: "
+              << HexDump(type, dtohl(type->header.size)) << endl);
+        
+        if ((size_t)offset > (dtohl(type->header.size)-sizeof(Res_value))) {
+            LOGW("ResTable_item at %d is beyond type chunk data %d",
+                 (int)offset, dtohl(type->header.size));
+            return BAD_TYPE;
+        }
+        
+        const Res_value* item =
+            (const Res_value*)(((const uint8_t*)type) + offset);
+        ResTable_config thisConfig;
+        thisConfig.copyFromDtoH(type->config);
+
+        if (outSpecFlags != NULL) {
+            if (typeClass->typeSpecFlags != NULL) {
+                *outSpecFlags |= dtohl(typeClass->typeSpecFlags[e]);
+            } else {
+                *outSpecFlags = -1;
+            }
+        }
+        
+        if (bestPackage != NULL && bestItem.isBetterThan(thisConfig)) {
+            continue;
+        }
+        
+        bestItem = thisConfig;
+        bestValue = item;
+        bestPackage = package;
+    }
+
+    TABLE_NOISY(printf("Found result: package %p\n", bestPackage));
+
+    if (bestValue) {
+        outValue->size = dtohs(bestValue->size);
+        outValue->res0 = bestValue->res0;
+        outValue->dataType = bestValue->dataType;
+        outValue->data = dtohl(bestValue->data);
+        if (outConfig != NULL) {
+            *outConfig = bestItem;
+        }
+        TABLE_NOISY(size_t len;
+              printf("Found value: pkg=%d, type=%d, str=%s, int=%d\n",
+                     bestPackage->header->index,
+                     outValue->dataType,
+                     outValue->dataType == bestValue->TYPE_STRING
+                     ? String8(bestPackage->header->values.stringAt(
+                         outValue->data, &len)).string()
+                     : "",
+                     outValue->data));
+        return bestPackage->header->index;
+    }
+
+    return BAD_INDEX;
+}
+
+ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
+        uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags) const
+{
+    int count=0;
+    while (blockIndex >= 0 && value->dataType == value->TYPE_REFERENCE
+           && value->data != 0 && count < 20) {
+        if (outLastRef) *outLastRef = value->data;
+        uint32_t lastRef = value->data;
+        uint32_t newFlags = 0;
+        const ssize_t newIndex = getResource(value->data, value, true, &newFlags);
+        //LOGI("Resolving reference d=%p: newIndex=%d, t=0x%02x, d=%p\n",
+        //     (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data);
+        //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);
+        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags;
+        if (newIndex < 0) {
+            // This can fail if the resource being referenced is a style...
+            // in this case, just return the reference, and expect the
+            // caller to deal with.
+            return blockIndex;
+        }
+        blockIndex = newIndex;
+        count++;
+    }
+    return blockIndex;
+}
+
+const char16_t* ResTable::valueToString(
+    const Res_value* value, size_t stringBlock,
+    char16_t tmpBuffer[TMP_BUFFER_SIZE], size_t* outLen)
+{
+    if (!value) {
+        return NULL;
+    }
+    if (value->dataType == value->TYPE_STRING) {
+        return getTableStringBlock(stringBlock)->stringAt(value->data, outLen);
+    }
+    // XXX do int to string conversions.
+    return NULL;
+}
+
+ssize_t ResTable::lockBag(uint32_t resID, const bag_entry** outBag) const
+{
+    mLock.lock();
+    ssize_t err = getBagLocked(resID, outBag);
+    if (err < NO_ERROR) {
+        //printf("*** get failed!  unlocking\n");
+        mLock.unlock();
+    }
+    return err;
+}
+
+void ResTable::unlockBag(const bag_entry* bag) const
+{
+    //printf("<<< unlockBag %p\n", this);
+    mLock.unlock();
+}
+
+void ResTable::lock() const
+{
+    mLock.lock();
+}
+
+void ResTable::unlock() const
+{
+    mLock.unlock();
+}
+
+ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
+        uint32_t* outTypeSpecFlags) const
+{
+    if (mError != NO_ERROR) {
+        return mError;
+    }
+
+    const ssize_t p = getResourcePackageIndex(resID);
+    const int t = Res_GETTYPE(resID);
+    const int e = Res_GETENTRY(resID);
+
+    if (p < 0) {
+        LOGW("Invalid package identifier when getting bag for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+    if (t < 0) {
+        LOGW("No type identifier when getting bag for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+
+    //printf("Get bag: id=0x%08x, p=%d, t=%d\n", resID, p, t);
+    PackageGroup* const grp = mPackageGroups[p];
+    if (grp == NULL) {
+        LOGW("Bad identifier when getting bag for resource number 0x%08x", resID);
+        return false;
+    }
+
+    if (t >= (int)grp->typeCount) {
+        LOGW("Type identifier 0x%x is larger than type count 0x%x",
+             t+1, (int)grp->typeCount);
+        return BAD_INDEX;
+    }
+
+    const Package* const basePackage = grp->packages[0];
+
+    const Type* const typeConfigs = basePackage->getType(t);
+
+    const size_t NENTRY = typeConfigs->entryCount;
+    if (e >= (int)NENTRY) {
+        LOGW("Entry identifier 0x%x is larger than entry count 0x%x",
+             e, (int)typeConfigs->entryCount);
+        return BAD_INDEX;
+    }
+
+    // First see if we've already computed this bag...
+    if (grp->bags) {
+        bag_set** typeSet = grp->bags[t];
+        if (typeSet) {
+            bag_set* set = typeSet[e];
+            if (set) {
+                if (set != (bag_set*)0xFFFFFFFF) {
+                    if (outTypeSpecFlags != NULL) {
+                        *outTypeSpecFlags = set->typeSpecFlags;
+                    }
+                    *outBag = (bag_entry*)(set+1);
+                    //LOGI("Found existing bag for: %p\n", (void*)resID);
+                    return set->numAttrs;
+                }
+                LOGW("Attempt to retrieve bag 0x%08x which is invalid or in a cycle.",
+                     resID);
+                return BAD_INDEX;
+            }
+        }
+    }
+
+    // Bag not found, we need to compute it!
+    if (!grp->bags) {
+        grp->bags = (bag_set***)malloc(sizeof(bag_set*)*grp->typeCount);
+        if (!grp->bags) return NO_MEMORY;
+        memset(grp->bags, 0, sizeof(bag_set*)*grp->typeCount);
+    }
+
+    bag_set** typeSet = grp->bags[t];
+    if (!typeSet) {
+        typeSet = (bag_set**)malloc(sizeof(bag_set*)*NENTRY);
+        if (!typeSet) return NO_MEMORY;
+        memset(typeSet, 0, sizeof(bag_set*)*NENTRY);
+        grp->bags[t] = typeSet;
+    }
+
+    // Mark that we are currently working on this one.
+    typeSet[e] = (bag_set*)0xFFFFFFFF;
+
+    // This is what we are building.
+    bag_set* set = NULL;
+
+    TABLE_NOISY(LOGI("Building bag: %p\n", (void*)resID));
+    
+    // Now collect all bag attributes from all packages.
+    size_t ip = grp->packages.size();
+    while (ip > 0) {
+        ip--;
+
+        const Package* const package = grp->packages[ip];
+
+        const ResTable_type* type;
+        const ResTable_entry* entry;
+        const Type* typeClass;
+        LOGV("Getting entry pkg=%p, t=%d, e=%d\n", package, t, e);
+        ssize_t offset = getEntry(package, t, e, &mParams, &type, &entry, &typeClass);
+        LOGV("Resulting offset=%d\n", offset);
+        if (offset <= 0) {
+            if (offset < 0) {
+                if (set) free(set);
+                return offset;
+            }
+            continue;
+        }
+
+        if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) == 0) {
+            LOGW("Skipping entry %p in package table %d because it is not complex!\n",
+                 (void*)resID, (int)ip);
+            continue;
+        }
+
+        const uint16_t entrySize = dtohs(entry->size);
+        const uint32_t parent = entrySize >= sizeof(ResTable_map_entry)
+            ? dtohl(((const ResTable_map_entry*)entry)->parent.ident) : 0;
+        const uint32_t count = entrySize >= sizeof(ResTable_map_entry)
+            ? dtohl(((const ResTable_map_entry*)entry)->count) : 0;
+        
+        size_t N = count;
+
+        TABLE_NOISY(LOGI("Found map: size=%p parent=%p count=%d\n",
+                         entrySize, parent, count));
+
+        if (set == NULL) {
+            // If this map inherits from another, we need to start
+            // with its parent's values.  Otherwise start out empty.
+            TABLE_NOISY(printf("Creating new bag, entrySize=0x%08x, parent=0x%08x\n",
+                         entrySize, parent));
+            if (parent) {
+                const bag_entry* parentBag;
+                uint32_t parentTypeSpecFlags = 0;
+                const ssize_t NP = getBagLocked(parent, &parentBag, &parentTypeSpecFlags);
+                const size_t NT = ((NP >= 0) ? NP : 0) + N;
+                set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*NT);
+                if (set == NULL) {
+                    return NO_MEMORY;
+                }
+                if (NP > 0) {
+                    memcpy(set+1, parentBag, NP*sizeof(bag_entry));
+                    set->numAttrs = NP;
+                    TABLE_NOISY(LOGI("Initialized new bag with %d inherited attributes.\n", NP));
+                } else {
+                    TABLE_NOISY(LOGI("Initialized new bag with no inherited attributes.\n"));
+                    set->numAttrs = 0;
+                }
+                set->availAttrs = NT;
+                set->typeSpecFlags = parentTypeSpecFlags;
+            } else {
+                set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*N);
+                if (set == NULL) {
+                    return NO_MEMORY;
+                }
+                set->numAttrs = 0;
+                set->availAttrs = N;
+                set->typeSpecFlags = 0;
+            }
+        }
+
+        if (typeClass->typeSpecFlags != NULL) {
+            set->typeSpecFlags |= dtohl(typeClass->typeSpecFlags[e]);
+        } else {
+            set->typeSpecFlags = -1;
+        }
+        
+        // Now merge in the new attributes...
+        ssize_t curOff = offset;
+        const ResTable_map* map;
+        bag_entry* entries = (bag_entry*)(set+1);
+        size_t curEntry = 0;
+        uint32_t pos = 0;
+        TABLE_NOISY(LOGI("Starting with set %p, entries=%p, avail=%d\n",
+                     set, entries, set->availAttrs));
+        while (pos < count) {
+            TABLE_NOISY(printf("Now at %p\n", (void*)curOff));
+
+            if ((size_t)curOff > (dtohl(type->header.size)-sizeof(ResTable_map))) {
+                LOGW("ResTable_map at %d is beyond type chunk data %d",
+                     (int)curOff, dtohl(type->header.size));
+                return BAD_TYPE;
+            }
+            map = (const ResTable_map*)(((const uint8_t*)type) + curOff);
+            N++;
+
+            const uint32_t newName = htodl(map->name.ident);
+            bool isInside;
+            uint32_t oldName = 0;
+            while ((isInside=(curEntry < set->numAttrs))
+                    && (oldName=entries[curEntry].map.name.ident) < newName) {
+                TABLE_NOISY(printf("#%d: Keeping existing attribute: 0x%08x\n",
+                             curEntry, entries[curEntry].map.name.ident));
+                curEntry++;
+            }
+
+            if ((!isInside) || oldName != newName) {
+                // This is a new attribute...  figure out what to do with it.
+                if (set->numAttrs >= set->availAttrs) {
+                    // Need to alloc more memory...
+                    const size_t newAvail = set->availAttrs+N;
+                    set = (bag_set*)realloc(set,
+                                            sizeof(bag_set)
+                                            + sizeof(bag_entry)*newAvail);
+                    if (set == NULL) {
+                        return NO_MEMORY;
+                    }
+                    set->availAttrs = newAvail;
+                    entries = (bag_entry*)(set+1);
+                    TABLE_NOISY(printf("Reallocated set %p, entries=%p, avail=%d\n",
+                                 set, entries, set->availAttrs));
+                }
+                if (isInside) {
+                    // Going in the middle, need to make space.
+                    memmove(entries+curEntry+1, entries+curEntry,
+                            sizeof(bag_entry)*(set->numAttrs-curEntry));
+                    set->numAttrs++;
+                }
+                TABLE_NOISY(printf("#%d: Inserting new attribute: 0x%08x\n",
+                             curEntry, newName));
+            } else {
+                TABLE_NOISY(printf("#%d: Replacing existing attribute: 0x%08x\n",
+                             curEntry, oldName));
+            }
+
+            bag_entry* cur = entries+curEntry;
+
+            cur->stringBlock = package->header->index;
+            cur->map.name.ident = newName;
+            cur->map.value.copyFrom_dtoh(map->value);
+            TABLE_NOISY(printf("Setting entry #%d %p: block=%d, name=0x%08x, type=%d, data=0x%08x\n",
+                         curEntry, cur, cur->stringBlock, cur->map.name.ident,
+                         cur->map.value.dataType, cur->map.value.data));
+
+            // On to the next!
+            curEntry++;
+            pos++;
+            const size_t size = dtohs(map->value.size);
+            curOff += size + sizeof(*map)-sizeof(map->value);
+        };
+        if (curEntry > set->numAttrs) {
+            set->numAttrs = curEntry;
+        }
+    }
+
+    // And this is it...
+    typeSet[e] = set;
+    if (set) {
+        if (outTypeSpecFlags != NULL) {
+            *outTypeSpecFlags = set->typeSpecFlags;
+        }
+        *outBag = (bag_entry*)(set+1);
+        TABLE_NOISY(LOGI("Returning %d attrs\n", set->numAttrs));
+        return set->numAttrs;
+    }
+    return BAD_INDEX;
+}
+
+void ResTable::setParameters(const ResTable_config* params)
+{
+    mLock.lock();
+    TABLE_GETENTRY(LOGI("Setting parameters: imsi:%d/%d lang:%c%c cnt:%c%c "
+                        "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+                       params->mcc, params->mnc,
+                       params->language[0] ? params->language[0] : '-',
+                       params->language[1] ? params->language[1] : '-',
+                       params->country[0] ? params->country[0] : '-',
+                       params->country[1] ? params->country[1] : '-',
+                       params->orientation,
+                       params->touchscreen,
+                       params->density,
+                       params->keyboard,
+                       params->inputFlags,
+                       params->navigation,
+                       params->screenWidth,
+                       params->screenHeight));
+    mParams = *params;
+    for (size_t i=0; i<mPackageGroups.size(); i++) {
+        TABLE_NOISY(LOGI("CLEARING BAGS FOR GROUP %d!", i));
+        mPackageGroups[i]->clearBagCache();
+    }
+    mLock.unlock();
+}
+
+void ResTable::getParameters(ResTable_config* params) const
+{
+    mLock.lock();
+    *params = mParams;
+    mLock.unlock();
+}
+
+struct id_name_map {
+    uint32_t id;
+    size_t len;
+    char16_t name[6];
+};
+
+const static id_name_map ID_NAMES[] = {
+    { ResTable_map::ATTR_TYPE,  5, { '^', 't', 'y', 'p', 'e' } },
+    { ResTable_map::ATTR_L10N,  5, { '^', 'l', '1', '0', 'n' } },
+    { ResTable_map::ATTR_MIN,   4, { '^', 'm', 'i', 'n' } },
+    { ResTable_map::ATTR_MAX,   4, { '^', 'm', 'a', 'x' } },
+    { ResTable_map::ATTR_OTHER, 6, { '^', 'o', 't', 'h', 'e', 'r' } },
+    { ResTable_map::ATTR_ZERO,  5, { '^', 'z', 'e', 'r', 'o' } },
+    { ResTable_map::ATTR_ONE,   4, { '^', 'o', 'n', 'e' } },
+    { ResTable_map::ATTR_TWO,   4, { '^', 't', 'w', 'o' } },
+    { ResTable_map::ATTR_FEW,   4, { '^', 'f', 'e', 'w' } },
+    { ResTable_map::ATTR_MANY,  5, { '^', 'm', 'a', 'n', 'y' } },
+};
+
+uint32_t ResTable::identifierForName(const char16_t* name, size_t nameLen,
+                                     const char16_t* type, size_t typeLen,
+                                     const char16_t* package,
+                                     size_t packageLen,
+                                     uint32_t* outTypeSpecFlags) const
+{
+    TABLE_SUPER_NOISY(printf("Identifier for name: error=%d\n", mError));
+
+    // Check for internal resource identifier as the very first thing, so
+    // that we will always find them even when there are no resources.
+    if (name[0] == '^') {
+        const int N = (sizeof(ID_NAMES)/sizeof(ID_NAMES[0]));
+        size_t len;
+        for (int i=0; i<N; i++) {
+            const id_name_map* m = ID_NAMES + i;
+            len = m->len;
+            if (len != nameLen) {
+                continue;
+            }
+            for (size_t j=1; j<len; j++) {
+                if (m->name[j] != name[j]) {
+                    goto nope;
+                }
+            }
+            return m->id;
+nope:
+            ;
+        }
+        if (nameLen > 7) {
+            if (name[1] == 'i' && name[2] == 'n'
+                && name[3] == 'd' && name[4] == 'e' && name[5] == 'x'
+                && name[6] == '_') {
+                int index = atoi(String8(name + 7, nameLen - 7).string());
+                if (Res_CHECKID(index)) {
+                    LOGW("Array resource index: %d is too large.",
+                         index);
+                    return 0;
+                }
+                return  Res_MAKEARRAY(index);
+            }
+        }
+        return 0;
+    }
+
+    if (mError != NO_ERROR) {
+        return 0;
+    }
+
+    // Figure out the package and type we are looking in...
+
+    const char16_t* packageEnd = NULL;
+    const char16_t* typeEnd = NULL;
+    const char16_t* const nameEnd = name+nameLen;
+    const char16_t* p = name;
+    while (p < nameEnd) {
+        if (*p == ':') packageEnd = p;
+        else if (*p == '/') typeEnd = p;
+        p++;
+    }
+    if (*name == '@') name++;
+    if (name >= nameEnd) {
+        return 0;
+    }
+
+    if (packageEnd) {
+        package = name;
+        packageLen = packageEnd-name;
+        name = packageEnd+1;
+    } else if (!package) {
+        return 0;
+    }
+
+    if (typeEnd) {
+        type = name;
+        typeLen = typeEnd-name;
+        name = typeEnd+1;
+    } else if (!type) {
+        return 0;
+    }
+
+    if (name >= nameEnd) {
+        return 0;
+    }
+    nameLen = nameEnd-name;
+
+    TABLE_NOISY(printf("Looking for identifier: type=%s, name=%s, package=%s\n",
+                 String8(type, typeLen).string(),
+                 String8(name, nameLen).string(),
+                 String8(package, packageLen).string()));
+
+    const size_t NG = mPackageGroups.size();
+    for (size_t ig=0; ig<NG; ig++) {
+        const PackageGroup* group = mPackageGroups[ig];
+
+        if (strzcmp16(package, packageLen,
+                      group->name.string(), group->name.size())) {
+            TABLE_NOISY(printf("Skipping package group: %s\n", String8(group->name).string()));
+            continue;
+        }
+
+        const ssize_t ti = group->typeStrings.indexOfString(type, typeLen);
+        if (ti < 0) {
+            TABLE_NOISY(printf("Type not found in package %s\n", String8(group->name).string()));
+            continue;
+        }
+
+        const ssize_t ei = group->keyStrings.indexOfString(name, nameLen);
+        if (ei < 0) {
+            TABLE_NOISY(printf("Name not found in package %s\n", String8(group->name).string()));
+            continue;
+        }
+
+        TABLE_NOISY(printf("Search indices: type=%d, name=%d\n", ti, ei));
+
+        const Type* const typeConfigs = group->packages[0]->getType(ti);
+        if (typeConfigs == NULL || typeConfigs->configs.size() <= 0) {
+            TABLE_NOISY(printf("Expected type structure not found in package %s for idnex %d\n",
+                               String8(group->name).string(), ti));
+        }
+        
+        size_t NTC = typeConfigs->configs.size();
+        for (size_t tci=0; tci<NTC; tci++) {
+            const ResTable_type* const ty = typeConfigs->configs[tci];
+            const uint32_t typeOffset = dtohl(ty->entriesStart);
+
+            const uint8_t* const end = ((const uint8_t*)ty) + dtohl(ty->header.size);
+            const uint32_t* const eindex = (const uint32_t*)
+                (((const uint8_t*)ty) + dtohs(ty->header.headerSize));
+
+            const size_t NE = dtohl(ty->entryCount);
+            for (size_t i=0; i<NE; i++) {
+                uint32_t offset = dtohl(eindex[i]);
+                if (offset == ResTable_type::NO_ENTRY) {
+                    continue;
+                }
+                
+                offset += typeOffset;
+                
+                if (offset > (dtohl(ty->header.size)-sizeof(ResTable_entry))) {
+                    LOGW("ResTable_entry at %d is beyond type chunk data %d",
+                         offset, dtohl(ty->header.size));
+                    return 0;
+                }
+                if ((offset&0x3) != 0) {
+                    LOGW("ResTable_entry at %d (pkg=%d type=%d ent=%d) is not on an integer boundary when looking for %s:%s/%s",
+                         (int)offset, (int)group->id, (int)ti+1, (int)i,
+                         String8(package, packageLen).string(),
+                         String8(type, typeLen).string(),
+                         String8(name, nameLen).string());
+                    return 0;
+                }
+                
+                const ResTable_entry* const entry = (const ResTable_entry*)
+                    (((const uint8_t*)ty) + offset);
+                if (dtohs(entry->size) < sizeof(*entry)) {
+                    LOGW("ResTable_entry size %d is too small", dtohs(entry->size));
+                    return BAD_TYPE;
+                }
+
+                TABLE_SUPER_NOISY(printf("Looking at entry #%d: want str %d, have %d\n",
+                                         i, ei, dtohl(entry->key.index)));
+                if (dtohl(entry->key.index) == (size_t)ei) {
+                    if (outTypeSpecFlags) {
+                        *outTypeSpecFlags = typeConfigs->typeSpecFlags[i];
+                    }
+                    return Res_MAKEID(group->id-1, ti, i);
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+bool ResTable::expandResourceRef(const uint16_t* refStr, size_t refLen,
+                                 String16* outPackage,
+                                 String16* outType,
+                                 String16* outName,
+                                 const String16* defType,
+                                 const String16* defPackage,
+                                 const char** outErrorMsg)
+{
+    const char16_t* packageEnd = NULL;
+    const char16_t* typeEnd = NULL;
+    const char16_t* p = refStr;
+    const char16_t* const end = p + refLen;
+    while (p < end) {
+        if (*p == ':') packageEnd = p;
+        else if (*p == '/') {
+            typeEnd = p;
+            break;
+        }
+        p++;
+    }
+    p = refStr;
+    if (*p == '@') p++;
+
+    if (packageEnd) {
+        *outPackage = String16(p, packageEnd-p);
+        p = packageEnd+1;
+    } else {
+        if (!defPackage) {
+            if (outErrorMsg) {
+                *outErrorMsg = "No resource package specified";
+            }
+            return false;
+        }
+        *outPackage = *defPackage;
+    }
+    if (typeEnd) {
+        *outType = String16(p, typeEnd-p);
+        p = typeEnd+1;
+    } else {
+        if (!defType) {
+            if (outErrorMsg) {
+                *outErrorMsg = "No resource type specified";
+            }
+            return false;
+        }
+        *outType = *defType;
+    }
+    *outName = String16(p, end-p);
+    return true;
+}
+
+static uint32_t get_hex(char c, bool* outError)
+{
+    if (c >= '0' && c <= '9') {
+        return c - '0';
+    } else if (c >= 'a' && c <= 'f') {
+        return c - 'a' + 0xa;
+    } else if (c >= 'A' && c <= 'F') {
+        return c - 'A' + 0xa;
+    }
+    *outError = true;
+    return 0;
+}
+
+struct unit_entry
+{
+    const char* name;
+    size_t len;
+    uint8_t type;
+    uint32_t unit;
+    float scale;
+};
+
+static const unit_entry unitNames[] = {
+    { "px", strlen("px"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PX, 1.0f },
+    { "dip", strlen("dip"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },
+    { "dp", strlen("dp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },
+    { "sp", strlen("sp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_SP, 1.0f },
+    { "pt", strlen("pt"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PT, 1.0f },
+    { "in", strlen("in"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_IN, 1.0f },
+    { "mm", strlen("mm"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_MM, 1.0f },
+    { "%", strlen("%"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION, 1.0f/100 },
+    { "%p", strlen("%p"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100 },
+    { NULL, 0, 0, 0, 0 }
+};
+
+static bool parse_unit(const char* str, Res_value* outValue,
+                       float* outScale, const char** outEnd)
+{
+    const char* end = str;
+    while (*end != 0 && !isspace((unsigned char)*end)) {
+        end++;
+    }
+    const size_t len = end-str;
+
+    const char* realEnd = end;
+    while (*realEnd != 0 && isspace((unsigned char)*realEnd)) {
+        realEnd++;
+    }
+    if (*realEnd != 0) {
+        return false;
+    }
+    
+    const unit_entry* cur = unitNames;
+    while (cur->name) {
+        if (len == cur->len && strncmp(cur->name, str, len) == 0) {
+            outValue->dataType = cur->type;
+            outValue->data = cur->unit << Res_value::COMPLEX_UNIT_SHIFT;
+            *outScale = cur->scale;
+            *outEnd = end;
+            //printf("Found unit %s for %s\n", cur->name, str);
+            return true;
+        }
+        cur++;
+    }
+
+    return false;
+}
+
+
+bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue)
+{
+    while (len > 0 && isspace16(*s)) {
+        s++;
+        len--;
+    }
+
+    if (len <= 0) {
+        return false;
+    }
+
+    size_t i = 0;
+    int32_t val = 0;
+    bool neg = false;
+
+    if (*s == '-') {
+        neg = true;
+        i++;
+    }
+
+    if (s[i] < '0' || s[i] > '9') {
+        return false;
+    }
+
+    // Decimal or hex?
+    if (s[i] == '0' && s[i+1] == 'x') {
+        if (outValue)
+            outValue->dataType = outValue->TYPE_INT_HEX;
+        i += 2;
+        bool error = false;
+        while (i < len && !error) {
+            val = (val*16) + get_hex(s[i], &error);
+            i++;
+        }
+        if (error) {
+            return false;
+        }
+    } else {
+        if (outValue)
+            outValue->dataType = outValue->TYPE_INT_DEC;
+        while (i < len) {
+            if (s[i] < '0' || s[i] > '9') {
+                return false;
+            }
+            val = (val*10) + s[i]-'0';
+            i++;
+        }
+    }
+
+    if (neg) val = -val;
+
+    while (i < len && isspace16(s[i])) {
+        i++;
+    }
+
+    if (i == len) {
+        if (outValue)
+            outValue->data = val;
+        return true;
+    }
+
+    return false;
+}
+
+bool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue)
+{
+    while (len > 0 && isspace16(*s)) {
+        s++;
+        len--;
+    }
+
+    if (len <= 0) {
+        return false;
+    }
+
+    char buf[128];
+    int i=0;
+    while (len > 0 && *s != 0 && i < 126) {
+        if (*s > 255) {
+            return false;
+        }
+        buf[i++] = *s++;
+        len--;
+    }
+
+    if (len > 0) {
+        return false;
+    }
+    if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') {
+        return false;
+    }
+
+    buf[i] = 0;
+    const char* end;
+    float f = strtof(buf, (char**)&end);
+
+    if (*end != 0 && !isspace((unsigned char)*end)) {
+        // Might be a unit...
+        float scale;
+        if (parse_unit(end, outValue, &scale, &end)) {
+            f *= scale;
+            const bool neg = f < 0;
+            if (neg) f = -f;
+            uint64_t bits = (uint64_t)(f*(1<<23)+.5f);
+            uint32_t radix;
+            uint32_t shift;
+            if ((bits&0x7fffff) == 0) {
+                // Always use 23p0 if there is no fraction, just to make
+                // things easier to read.
+                radix = Res_value::COMPLEX_RADIX_23p0;
+                shift = 23;
+            } else if ((bits&0xffffffffff800000LL) == 0) {
+                // Magnitude is zero -- can fit in 0 bits of precision.
+                radix = Res_value::COMPLEX_RADIX_0p23;
+                shift = 0;
+            } else if ((bits&0xffffffff80000000LL) == 0) {
+                // Magnitude can fit in 8 bits of precision.
+                radix = Res_value::COMPLEX_RADIX_8p15;
+                shift = 8;
+            } else if ((bits&0xffffff8000000000LL) == 0) {
+                // Magnitude can fit in 16 bits of precision.
+                radix = Res_value::COMPLEX_RADIX_16p7;
+                shift = 16;
+            } else {
+                // Magnitude needs entire range, so no fractional part.
+                radix = Res_value::COMPLEX_RADIX_23p0;
+                shift = 23;
+            }
+            int32_t mantissa = (int32_t)(
+                (bits>>shift) & Res_value::COMPLEX_MANTISSA_MASK);
+            if (neg) {
+                mantissa = (-mantissa) & Res_value::COMPLEX_MANTISSA_MASK;
+            }
+            outValue->data |= 
+                (radix<<Res_value::COMPLEX_RADIX_SHIFT)
+                | (mantissa<<Res_value::COMPLEX_MANTISSA_SHIFT);
+            //printf("Input value: %f 0x%016Lx, mult: %f, radix: %d, shift: %d, final: 0x%08x\n",
+            //       f * (neg ? -1 : 1), bits, f*(1<<23),
+            //       radix, shift, outValue->data);
+            return true;
+        }
+        return false;
+    }
+
+    while (*end != 0 && isspace((unsigned char)*end)) {
+        end++;
+    }
+
+    if (*end == 0) {
+        if (outValue) {
+            outValue->dataType = outValue->TYPE_FLOAT;
+            *(float*)(&outValue->data) = f;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool ResTable::stringToValue(Res_value* outValue, String16* outString,
+                             const char16_t* s, size_t len,
+                             bool preserveSpaces, bool coerceType,
+                             uint32_t attrID,
+                             const String16* defType,
+                             const String16* defPackage,
+                             Accessor* accessor,
+                             void* accessorCookie,
+                             uint32_t attrType,
+                             bool enforcePrivate) const
+{
+    bool localizationSetting = accessor != NULL && accessor->getLocalizationSetting();
+    const char* errorMsg = NULL;
+
+    outValue->size = sizeof(Res_value);
+    outValue->res0 = 0;
+
+    // First strip leading/trailing whitespace.  Do this before handling
+    // escapes, so they can be used to force whitespace into the string.
+    if (!preserveSpaces) {
+        while (len > 0 && isspace16(*s)) {
+            s++;
+            len--;
+        }
+        while (len > 0 && isspace16(s[len-1])) {
+            len--;
+        }
+        // If the string ends with '\', then we keep the space after it.
+        if (len > 0 && s[len-1] == '\\' && s[len] != 0) {
+            len++;
+        }
+    }
+
+    //printf("Value for: %s\n", String8(s, len).string());
+
+    uint32_t l10nReq = ResTable_map::L10N_NOT_REQUIRED;
+    uint32_t attrMin = 0x80000000, attrMax = 0x7fffffff;
+    bool fromAccessor = false;
+    if (attrID != 0 && !Res_INTERNALID(attrID)) {
+        const ssize_t p = getResourcePackageIndex(attrID);
+        const bag_entry* bag;
+        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
+        //printf("For attr 0x%08x got bag of %d\n", attrID, cnt);
+        if (cnt >= 0) {
+            while (cnt > 0) {
+                //printf("Entry 0x%08x = 0x%08x\n", bag->map.name.ident, bag->map.value.data);
+                switch (bag->map.name.ident) {
+                case ResTable_map::ATTR_TYPE:
+                    attrType = bag->map.value.data;
+                    break;
+                case ResTable_map::ATTR_MIN:
+                    attrMin = bag->map.value.data;
+                    break;
+                case ResTable_map::ATTR_MAX:
+                    attrMax = bag->map.value.data;
+                    break;
+                case ResTable_map::ATTR_L10N:
+                    l10nReq = bag->map.value.data;
+                    break;
+                }
+                bag++;
+                cnt--;
+            }
+            unlockBag(bag);
+        } else if (accessor && accessor->getAttributeType(attrID, &attrType)) {
+            fromAccessor = true;
+            if (attrType == ResTable_map::TYPE_ENUM
+                    || attrType == ResTable_map::TYPE_FLAGS
+                    || attrType == ResTable_map::TYPE_INTEGER) {
+                accessor->getAttributeMin(attrID, &attrMin);
+                accessor->getAttributeMax(attrID, &attrMax);
+            }
+            if (localizationSetting) {
+                l10nReq = accessor->getAttributeL10N(attrID);
+            }
+        }
+    }
+
+    const bool canStringCoerce =
+        coerceType && (attrType&ResTable_map::TYPE_STRING) != 0;
+
+    if (*s == '@') {
+        outValue->dataType = outValue->TYPE_REFERENCE;
+
+        // Note: we don't check attrType here because the reference can
+        // be to any other type; we just need to count on the client making
+        // sure the referenced type is correct.
+        
+        //printf("Looking up ref: %s\n", String8(s, len).string());
+
+        // It's a reference!
+        if (len == 5 && s[1]=='n' && s[2]=='u' && s[3]=='l' && s[4]=='l') {
+            outValue->data = 0;
+            return true;
+        } else {
+            bool createIfNotFound = false;
+            const char16_t* resourceRefName;
+            int resourceNameLen;
+            if (len > 2 && s[1] == '+') {
+                createIfNotFound = true;
+                resourceRefName = s + 2;
+                resourceNameLen = len - 2;
+            } else if (len > 2 && s[1] == '*') {
+                enforcePrivate = false;
+                resourceRefName = s + 2;
+                resourceNameLen = len - 2;
+            } else {
+                createIfNotFound = false;
+                resourceRefName = s + 1;
+                resourceNameLen = len - 1;
+            }
+            String16 package, type, name;
+            if (!expandResourceRef(resourceRefName,resourceNameLen, &package, &type, &name,
+                                   defType, defPackage, &errorMsg)) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, errorMsg);
+                }
+                return false;
+            }
+
+            uint32_t specFlags = 0;
+            uint32_t rid = identifierForName(name.string(), name.size(), type.string(),
+                    type.size(), package.string(), package.size(), &specFlags);
+            if (rid != 0) {
+                if (enforcePrivate) {
+                    if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
+                        if (accessor != NULL) {
+                            accessor->reportError(accessorCookie, "Resource is not public.");
+                        }
+                        return false;
+                    }
+                }
+                if (!accessor) {
+                    outValue->data = rid;
+                    return true;
+                }
+                rid = Res_MAKEID(
+                    accessor->getRemappedPackage(Res_GETPACKAGE(rid)),
+                    Res_GETTYPE(rid), Res_GETENTRY(rid));
+                TABLE_NOISY(printf("Incl %s:%s/%s: 0x%08x\n",
+                       String8(package).string(), String8(type).string(),
+                       String8(name).string(), rid));
+                outValue->data = rid;
+                return true;
+            }
+
+            if (accessor) {
+                uint32_t rid = accessor->getCustomResourceWithCreation(package, type, name,
+                                                                       createIfNotFound);
+                if (rid != 0) {
+                    TABLE_NOISY(printf("Pckg %s:%s/%s: 0x%08x\n",
+                           String8(package).string(), String8(type).string(),
+                           String8(name).string(), rid));
+                    outValue->data = rid;
+                    return true;
+                }
+            }
+        }
+
+        if (accessor != NULL) {
+            accessor->reportError(accessorCookie, "No resource found that matches the given name");
+        }
+        return false;
+    }
+
+    // if we got to here, and localization is required and it's not a reference,
+    // complain and bail.
+    if (l10nReq == ResTable_map::L10N_SUGGESTED) {
+        if (localizationSetting) {
+            if (accessor != NULL) {
+                accessor->reportError(accessorCookie, "This attribute must be localized.");
+            }
+        }
+    }
+    
+    if (*s == '#') {
+        // It's a color!  Convert to an integer of the form 0xaarrggbb.
+        uint32_t color = 0;
+        bool error = false;
+        if (len == 4) {
+            outValue->dataType = outValue->TYPE_INT_COLOR_RGB4;
+            color |= 0xFF000000;
+            color |= get_hex(s[1], &error) << 20;
+            color |= get_hex(s[1], &error) << 16;
+            color |= get_hex(s[2], &error) << 12;
+            color |= get_hex(s[2], &error) << 8;
+            color |= get_hex(s[3], &error) << 4;
+            color |= get_hex(s[3], &error);
+        } else if (len == 5) {
+            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB4;
+            color |= get_hex(s[1], &error) << 28;
+            color |= get_hex(s[1], &error) << 24;
+            color |= get_hex(s[2], &error) << 20;
+            color |= get_hex(s[2], &error) << 16;
+            color |= get_hex(s[3], &error) << 12;
+            color |= get_hex(s[3], &error) << 8;
+            color |= get_hex(s[4], &error) << 4;
+            color |= get_hex(s[4], &error);
+        } else if (len == 7) {
+            outValue->dataType = outValue->TYPE_INT_COLOR_RGB8;
+            color |= 0xFF000000;
+            color |= get_hex(s[1], &error) << 20;
+            color |= get_hex(s[2], &error) << 16;
+            color |= get_hex(s[3], &error) << 12;
+            color |= get_hex(s[4], &error) << 8;
+            color |= get_hex(s[5], &error) << 4;
+            color |= get_hex(s[6], &error);
+        } else if (len == 9) {
+            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB8;
+            color |= get_hex(s[1], &error) << 28;
+            color |= get_hex(s[2], &error) << 24;
+            color |= get_hex(s[3], &error) << 20;
+            color |= get_hex(s[4], &error) << 16;
+            color |= get_hex(s[5], &error) << 12;
+            color |= get_hex(s[6], &error) << 8;
+            color |= get_hex(s[7], &error) << 4;
+            color |= get_hex(s[8], &error);
+        } else {
+            error = true;
+        }
+        if (!error) {
+            if ((attrType&ResTable_map::TYPE_COLOR) == 0) {
+                if (!canStringCoerce) {
+                    if (accessor != NULL) {
+                        accessor->reportError(accessorCookie,
+                                "Color types not allowed");
+                    }
+                    return false;
+                }
+            } else {
+                outValue->data = color;
+                //printf("Color input=%s, output=0x%x\n", String8(s, len).string(), color);
+                return true;
+            }
+        } else {
+            if ((attrType&ResTable_map::TYPE_COLOR) != 0) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Color value not valid --"
+                            " must be #rgb, #argb, #rrggbb, or #aarrggbb");
+                }
+                #if 0
+                fprintf(stderr, "%s: Color ID %s value %s is not valid\n",
+                        "Resource File", //(const char*)in->getPrintableSource(),
+                        String8(*curTag).string(),
+                        String8(s, len).string());
+                #endif
+                return false;
+            }
+        }
+    }
+
+    if (*s == '?') {
+        outValue->dataType = outValue->TYPE_ATTRIBUTE;
+
+        // Note: we don't check attrType here because the reference can
+        // be to any other type; we just need to count on the client making
+        // sure the referenced type is correct.
+
+        //printf("Looking up attr: %s\n", String8(s, len).string());
+
+        static const String16 attr16("attr");
+        String16 package, type, name;
+        if (!expandResourceRef(s+1, len-1, &package, &type, &name,
+                               &attr16, defPackage, &errorMsg)) {
+            if (accessor != NULL) {
+                accessor->reportError(accessorCookie, errorMsg);
+            }
+            return false;
+        }
+
+        //printf("Pkg: %s, Type: %s, Name: %s\n",
+        //       String8(package).string(), String8(type).string(),
+        //       String8(name).string());
+        uint32_t specFlags = 0;
+        uint32_t rid = 
+            identifierForName(name.string(), name.size(),
+                              type.string(), type.size(),
+                              package.string(), package.size(), &specFlags);
+        if (rid != 0) {
+            if (enforcePrivate) {
+                if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
+                    if (accessor != NULL) {
+                        accessor->reportError(accessorCookie, "Attribute is not public.");
+                    }
+                    return false;
+                }
+            }
+            if (!accessor) {
+                outValue->data = rid;
+                return true;
+            }
+            rid = Res_MAKEID(
+                accessor->getRemappedPackage(Res_GETPACKAGE(rid)),
+                Res_GETTYPE(rid), Res_GETENTRY(rid));
+            //printf("Incl %s:%s/%s: 0x%08x\n",
+            //       String8(package).string(), String8(type).string(),
+            //       String8(name).string(), rid);
+            outValue->data = rid;
+            return true;
+        }
+
+        if (accessor) {
+            uint32_t rid = accessor->getCustomResource(package, type, name);
+            if (rid != 0) {
+                //printf("Mine %s:%s/%s: 0x%08x\n",
+                //       String8(package).string(), String8(type).string(),
+                //       String8(name).string(), rid);
+                outValue->data = rid;
+                return true;
+            }
+        }
+
+        if (accessor != NULL) {
+            accessor->reportError(accessorCookie, "No resource found that matches the given name");
+        }
+        return false;
+    }
+
+    if (stringToInt(s, len, outValue)) {
+        if ((attrType&ResTable_map::TYPE_INTEGER) == 0) {
+            // If this type does not allow integers, but does allow floats,
+            // fall through on this error case because the float type should
+            // be able to accept any integer value.
+            if (!canStringCoerce && (attrType&ResTable_map::TYPE_FLOAT) == 0) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Integer types not allowed");
+                }
+                return false;
+            }
+        } else {
+            if (((int32_t)outValue->data) < ((int32_t)attrMin)
+                    || ((int32_t)outValue->data) > ((int32_t)attrMax)) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Integer value out of range");
+                }
+                return false;
+            }
+            return true;
+        }
+    }
+
+    if (stringToFloat(s, len, outValue)) {
+        if (outValue->dataType == Res_value::TYPE_DIMENSION) {
+            if ((attrType&ResTable_map::TYPE_DIMENSION) != 0) {
+                return true;
+            }
+            if (!canStringCoerce) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Dimension types not allowed");
+                }
+                return false;
+            }
+        } else if (outValue->dataType == Res_value::TYPE_FRACTION) {
+            if ((attrType&ResTable_map::TYPE_FRACTION) != 0) {
+                return true;
+            }
+            if (!canStringCoerce) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Fraction types not allowed");
+                }
+                return false;
+            }
+        } else if ((attrType&ResTable_map::TYPE_FLOAT) == 0) {
+            if (!canStringCoerce) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Float types not allowed");
+                }
+                return false;
+            }
+        } else {
+            return true;
+        }
+    }
+
+    if (len == 4) {
+        if ((s[0] == 't' || s[0] == 'T') &&
+            (s[1] == 'r' || s[1] == 'R') &&
+            (s[2] == 'u' || s[2] == 'U') &&
+            (s[3] == 'e' || s[3] == 'E')) {
+            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {
+                if (!canStringCoerce) {
+                    if (accessor != NULL) {
+                        accessor->reportError(accessorCookie, "Boolean types not allowed");
+                    }
+                    return false;
+                }
+            } else {
+                outValue->dataType = outValue->TYPE_INT_BOOLEAN;
+                outValue->data = (uint32_t)-1;
+                return true;
+            }
+        }
+    }
+
+    if (len == 5) {
+        if ((s[0] == 'f' || s[0] == 'F') &&
+            (s[1] == 'a' || s[1] == 'A') &&
+            (s[2] == 'l' || s[2] == 'L') &&
+            (s[3] == 's' || s[3] == 'S') &&
+            (s[4] == 'e' || s[4] == 'E')) {
+            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {
+                if (!canStringCoerce) {
+                    if (accessor != NULL) {
+                        accessor->reportError(accessorCookie, "Boolean types not allowed");
+                    }
+                    return false;
+                }
+            } else {
+                outValue->dataType = outValue->TYPE_INT_BOOLEAN;
+                outValue->data = 0;
+                return true;
+            }
+        }
+    }
+
+    if ((attrType&ResTable_map::TYPE_ENUM) != 0) {
+        const ssize_t p = getResourcePackageIndex(attrID);
+        const bag_entry* bag;
+        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
+        //printf("Got %d for enum\n", cnt);
+        if (cnt >= 0) {
+            resource_name rname;
+            while (cnt > 0) {
+                if (!Res_INTERNALID(bag->map.name.ident)) {
+                    //printf("Trying attr #%08x\n", bag->map.name.ident);
+                    if (getResourceName(bag->map.name.ident, &rname)) {
+                        #if 0
+                        printf("Matching %s against %s (0x%08x)\n",
+                               String8(s, len).string(),
+                               String8(rname.name, rname.nameLen).string(),
+                               bag->map.name.ident);
+                        #endif
+                        if (strzcmp16(s, len, rname.name, rname.nameLen) == 0) {
+                            outValue->dataType = bag->map.value.dataType;
+                            outValue->data = bag->map.value.data;
+                            unlockBag(bag);
+                            return true;
+                        }
+                    }
+    
+                }
+                bag++;
+                cnt--;
+            }
+            unlockBag(bag);
+        }
+
+        if (fromAccessor) {
+            if (accessor->getAttributeEnum(attrID, s, len, outValue)) {
+                return true;
+            }
+        }
+    }
+
+    if ((attrType&ResTable_map::TYPE_FLAGS) != 0) {
+        const ssize_t p = getResourcePackageIndex(attrID);
+        const bag_entry* bag;
+        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
+        //printf("Got %d for flags\n", cnt);
+        if (cnt >= 0) {
+            bool failed = false;
+            resource_name rname;
+            outValue->dataType = Res_value::TYPE_INT_HEX;
+            outValue->data = 0;
+            const char16_t* end = s + len;
+            const char16_t* pos = s;
+            while (pos < end && !failed) {
+                const char16_t* start = pos;
+                end++;
+                while (pos < end && *pos != '|') {
+                    pos++;
+                }
+				//printf("Looking for: %s\n", String8(start, pos-start).string());
+                const bag_entry* bagi = bag;
+				ssize_t i;
+                for (i=0; i<cnt; i++, bagi++) {
+                    if (!Res_INTERNALID(bagi->map.name.ident)) {
+                        //printf("Trying attr #%08x\n", bagi->map.name.ident);
+                        if (getResourceName(bagi->map.name.ident, &rname)) {
+                            #if 0
+                            printf("Matching %s against %s (0x%08x)\n",
+                                   String8(start,pos-start).string(),
+                                   String8(rname.name, rname.nameLen).string(),
+                                   bagi->map.name.ident);
+                            #endif
+                            if (strzcmp16(start, pos-start, rname.name, rname.nameLen) == 0) {
+                                outValue->data |= bagi->map.value.data;
+                                break;
+                            }
+                        }
+                    }
+                }
+                if (i >= cnt) {
+                    // Didn't find this flag identifier.
+                    failed = true;
+                }
+                if (pos < end) {
+                    pos++;
+                }
+            }
+            unlockBag(bag);
+            if (!failed) {
+				//printf("Final flag value: 0x%lx\n", outValue->data);
+                return true;
+            }
+        }
+
+
+        if (fromAccessor) {
+            if (accessor->getAttributeFlags(attrID, s, len, outValue)) {
+				//printf("Final flag value: 0x%lx\n", outValue->data);
+                return true;
+            }
+        }
+    }
+
+    if ((attrType&ResTable_map::TYPE_STRING) == 0) {
+        if (accessor != NULL) {
+            accessor->reportError(accessorCookie, "String types not allowed");
+        }
+        return false;
+    }
+
+    // Generic string handling...
+    outValue->dataType = outValue->TYPE_STRING;
+    if (outString) {
+        bool failed = collectString(outString, s, len, preserveSpaces, &errorMsg);
+        if (accessor != NULL) {
+            accessor->reportError(accessorCookie, errorMsg);
+        }
+        return failed;
+    }
+
+    return true;
+}
+
+bool ResTable::collectString(String16* outString,
+                             const char16_t* s, size_t len,
+                             bool preserveSpaces,
+                             const char** outErrorMsg,
+                             bool append)
+{
+    String16 tmp;
+
+    char quoted = 0;
+    const char16_t* p = s;
+    while (p < (s+len)) {
+        while (p < (s+len)) {
+            const char16_t c = *p;
+            if (c == '\\') {
+                break;
+            }
+            if (!preserveSpaces) {
+                if (quoted == 0 && isspace16(c)
+                    && (c != ' ' || isspace16(*(p+1)))) {
+                    break;
+                }
+                if (c == '"' && (quoted == 0 || quoted == '"')) {
+                    break;
+                }
+                if (c == '\'' && (quoted == 0 || quoted == '\'')) {
+                    break;
+                }
+            }
+            p++;
+        }
+        if (p < (s+len)) {
+            if (p > s) {
+                tmp.append(String16(s, p-s));
+            }
+            if (!preserveSpaces && (*p == '"' || *p == '\'')) {
+                if (quoted == 0) {
+                    quoted = *p;
+                } else {
+                    quoted = 0;
+                }
+                p++;
+            } else if (!preserveSpaces && isspace16(*p)) {
+                // Space outside of a quote -- consume all spaces and
+                // leave a single plain space char.
+                tmp.append(String16(" "));
+                p++;
+                while (p < (s+len) && isspace16(*p)) {
+                    p++;
+                }
+            } else if (*p == '\\') {
+                p++;
+                if (p < (s+len)) {
+                    switch (*p) {
+                    case 't':
+                        tmp.append(String16("\t"));
+                        break;
+                    case 'n':
+                        tmp.append(String16("\n"));
+                        break;
+                    case '#':
+                        tmp.append(String16("#"));
+                        break;
+                    case '@':
+                        tmp.append(String16("@"));
+                        break;
+                    case '?':
+                        tmp.append(String16("?"));
+                        break;
+                    case '"':
+                        tmp.append(String16("\""));
+                        break;
+                    case '\'':
+                        tmp.append(String16("'"));
+                        break;
+                    case '\\':
+                        tmp.append(String16("\\"));
+                        break;
+                    case 'u':
+                    {
+                        char16_t chr = 0;
+                        int i = 0;
+                        while (i < 4 && p[1] != 0) {
+                            p++;
+                            i++;
+                            int c;
+                            if (*p >= '0' && *p <= '9') {
+                                c = *p - '0';
+                            } else if (*p >= 'a' && *p <= 'f') {
+                                c = *p - 'a' + 10;
+                            } else if (*p >= 'A' && *p <= 'F') {
+                                c = *p - 'A' + 10;
+                            } else {
+                                if (outErrorMsg) {
+                                    *outErrorMsg = "Bad character in \\u unicode escape sequence";
+                                }
+                                return false;
+                            }
+                            chr = (chr<<4) | c;
+                        }
+                        tmp.append(String16(&chr, 1));
+                    } break;
+                    default:
+                        // ignore unknown escape chars.
+                        break;
+                    }
+                    p++;
+                }
+            }
+            len -= (p-s);
+            s = p;
+        }
+    }
+
+    if (tmp.size() != 0) {
+        if (len > 0) {
+            tmp.append(String16(s, len));
+        }
+        if (append) {
+            outString->append(tmp);
+        } else {
+            outString->setTo(tmp);
+        }
+    } else {
+        if (append) {
+            outString->append(String16(s, len));
+        } else {
+            outString->setTo(s, len);
+        }
+    }
+
+    return true;
+}
+
+size_t ResTable::getBasePackageCount() const
+{
+    if (mError != NO_ERROR) {
+        return 0;
+    }
+    return mPackageGroups.size();
+}
+
+const char16_t* ResTable::getBasePackageName(size_t idx) const
+{
+    if (mError != NO_ERROR) {
+        return 0;
+    }
+    LOG_FATAL_IF(idx >= mPackageGroups.size(),
+                 "Requested package index %d past package count %d",
+                 (int)idx, (int)mPackageGroups.size());
+    return mPackageGroups[idx]->name.string();
+}
+
+uint32_t ResTable::getBasePackageId(size_t idx) const
+{
+    if (mError != NO_ERROR) {
+        return 0;
+    }
+    LOG_FATAL_IF(idx >= mPackageGroups.size(),
+                 "Requested package index %d past package count %d",
+                 (int)idx, (int)mPackageGroups.size());
+    return mPackageGroups[idx]->id;
+}
+
+size_t ResTable::getTableCount() const
+{
+    return mHeaders.size();
+}
+
+const ResStringPool* ResTable::getTableStringBlock(size_t index) const
+{
+    return &mHeaders[index]->values;
+}
+
+void* ResTable::getTableCookie(size_t index) const
+{
+    return mHeaders[index]->cookie;
+}
+
+void ResTable::getConfigurations(Vector<ResTable_config>* configs) const
+{
+    const size_t I = mPackageGroups.size();
+    for (size_t i=0; i<I; i++) {
+        const PackageGroup* packageGroup = mPackageGroups[i];
+        const size_t J = packageGroup->packages.size();
+        for (size_t j=0; j<J; j++) {
+            const Package* package = packageGroup->packages[j];
+            const size_t K = package->types.size();
+            for (size_t k=0; k<K; k++) {
+                const Type* type = package->types[k];
+                if (type == NULL) continue;
+                const size_t L = type->configs.size();
+                for (size_t l=0; l<L; l++) {
+                    const ResTable_type* config = type->configs[l];
+                    const ResTable_config* cfg = &config->config;
+                    // only insert unique
+                    const size_t M = configs->size();
+                    size_t m;
+                    for (m=0; m<M; m++) {
+                        if (0 == (*configs)[m].compare(*cfg)) {
+                            break;
+                        }
+                    }
+                    // if we didn't find it
+                    if (m == M) {
+                        configs->add(*cfg);
+                    }
+                }
+            }
+        }
+    }
+}
+
+void ResTable::getLocales(Vector<String8>* locales) const
+{
+    Vector<ResTable_config> configs;
+    LOGD("calling getConfigurations");
+    getConfigurations(&configs);
+    LOGD("called getConfigurations size=%d", (int)configs.size());
+    const size_t I = configs.size();
+    for (size_t i=0; i<I; i++) {
+        char locale[6];
+        configs[i].getLocale(locale);
+        const size_t J = locales->size();
+        size_t j;
+        for (j=0; j<J; j++) {
+            if (0 == strcmp(locale, (*locales)[j].string())) {
+                break;
+            }
+        }
+        if (j == J) {
+            locales->add(String8(locale));
+        }
+    }
+}
+
+ssize_t ResTable::getEntry(
+    const Package* package, int typeIndex, int entryIndex,
+    const ResTable_config* config,
+    const ResTable_type** outType, const ResTable_entry** outEntry,
+    const Type** outTypeClass) const
+{
+    LOGV("Getting entry from package %p\n", package);
+    const ResTable_package* const pkg = package->package;
+
+    const Type* allTypes = package->getType(typeIndex);
+    LOGV("allTypes=%p\n", allTypes);
+    if (allTypes == NULL) {
+        LOGV("Skipping entry type index 0x%02x because type is NULL!\n", typeIndex);
+        return 0;
+    }
+
+    if ((size_t)entryIndex >= allTypes->entryCount) {
+        LOGW("getEntry failing because entryIndex %d is beyond type entryCount %d",
+            entryIndex, (int)allTypes->entryCount);
+        return BAD_TYPE;
+    }
+        
+    const ResTable_type* type = NULL;
+    uint32_t offset = ResTable_type::NO_ENTRY;
+    ResTable_config bestConfig;
+    memset(&bestConfig, 0, sizeof(bestConfig)); // make the compiler shut up
+    
+    const size_t NT = allTypes->configs.size();
+    for (size_t i=0; i<NT; i++) {
+        const ResTable_type* const thisType = allTypes->configs[i];
+        if (thisType == NULL) continue;
+        
+        ResTable_config thisConfig;
+        thisConfig.copyFromDtoH(thisType->config);
+
+        TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): imsi:%d/%d=%d/%d lang:%c%c=%c%c cnt:%c%c=%c%c "
+                            "orien:%d=%d touch:%d=%d density:%d=%d key:%d=%d inp:%d=%d nav:%d=%d w:%d=%d h:%d=%d\n",
+                           entryIndex, typeIndex+1, dtohl(thisType->config.size),
+                           thisConfig.mcc, thisConfig.mnc,
+                           config ? config->mcc : 0, config ? config->mnc : 0,
+                           thisConfig.language[0] ? thisConfig.language[0] : '-',
+                           thisConfig.language[1] ? thisConfig.language[1] : '-',
+                           config && config->language[0] ? config->language[0] : '-',
+                           config && config->language[1] ? config->language[1] : '-',
+                           thisConfig.country[0] ? thisConfig.country[0] : '-',
+                           thisConfig.country[1] ? thisConfig.country[1] : '-',
+                           config && config->country[0] ? config->country[0] : '-',
+                           config && config->country[1] ? config->country[1] : '-',
+                           thisConfig.orientation,
+                           config ? config->orientation : 0,
+                           thisConfig.touchscreen,
+                           config ? config->touchscreen : 0,
+                           thisConfig.density,
+                           config ? config->density : 0,
+                           thisConfig.keyboard,
+                           config ? config->keyboard : 0,
+                           thisConfig.inputFlags,
+                           config ? config->inputFlags : 0,
+                           thisConfig.navigation,
+                           config ? config->navigation : 0,
+                           thisConfig.screenWidth,
+                           config ? config->screenWidth : 0,
+                           thisConfig.screenHeight,
+                           config ? config->screenHeight : 0));
+        
+        // Check to make sure this one is valid for the current parameters.
+        if (config && !thisConfig.match(*config)) {
+            TABLE_GETENTRY(LOGI("Does not match config!\n"));
+            continue;
+        }
+        
+        // Check if there is the desired entry in this type.
+        
+        const uint8_t* const end = ((const uint8_t*)thisType)
+            + dtohl(thisType->header.size);
+        const uint32_t* const eindex = (const uint32_t*)
+            (((const uint8_t*)thisType) + dtohs(thisType->header.headerSize));
+        
+        uint32_t thisOffset = dtohl(eindex[entryIndex]);
+        if (thisOffset == ResTable_type::NO_ENTRY) {
+            TABLE_GETENTRY(LOGI("Skipping because it is not defined!\n"));
+            continue;
+        }
+        
+        if (type != NULL) {
+            // Check if this one is less specific than the last found.  If so,
+            // we will skip it.  We check starting with things we most care
+            // about to those we least care about.
+            if (!thisConfig.isBetterThan(bestConfig, config)) {
+                TABLE_GETENTRY(LOGI("This config is worse than last!\n"));
+                continue;
+            }
+        }
+        
+        type = thisType;
+        offset = thisOffset;
+        bestConfig = thisConfig;
+        TABLE_GETENTRY(LOGI("Best entry so far -- using it!\n"));
+        if (!config) break;
+    }
+    
+    if (type == NULL) {
+        TABLE_GETENTRY(LOGI("No value found for requested entry!\n"));
+        return BAD_INDEX;
+    }
+    
+    offset += dtohl(type->entriesStart);
+    TABLE_NOISY(aout << "Looking in resource table " << package->header->header
+          << ", typeOff="
+          << (void*)(((const char*)type)-((const char*)package->header->header))
+          << ", offset=" << (void*)offset << endl);
+
+    if (offset > (dtohl(type->header.size)-sizeof(ResTable_entry))) {
+        LOGW("ResTable_entry at 0x%x is beyond type chunk data 0x%x",
+             offset, dtohl(type->header.size));
+        return BAD_TYPE;
+    }
+    if ((offset&0x3) != 0) {
+        LOGW("ResTable_entry at 0x%x is not on an integer boundary",
+             offset);
+        return BAD_TYPE;
+    }
+
+    const ResTable_entry* const entry = (const ResTable_entry*)
+        (((const uint8_t*)type) + offset);
+    if (dtohs(entry->size) < sizeof(*entry)) {
+        LOGW("ResTable_entry size 0x%x is too small", dtohs(entry->size));
+        return BAD_TYPE;
+    }
+
+    *outType = type;
+    *outEntry = entry;
+    if (outTypeClass != NULL) {
+        *outTypeClass = allTypes;
+    }
+    return offset + dtohs(entry->size);
+}
+
+status_t ResTable::parsePackage(const ResTable_package* const pkg,
+                                const Header* const header)
+{
+    const uint8_t* base = (const uint8_t*)pkg;
+    status_t err = validate_chunk(&pkg->header, sizeof(*pkg),
+                                  header->dataEnd, "ResTable_package");
+    if (err != NO_ERROR) {
+        return (mError=err);
+    }
+
+    const size_t pkgSize = dtohl(pkg->header.size);
+
+    if (dtohl(pkg->typeStrings) >= pkgSize) {
+        LOGW("ResTable_package type strings at %p are past chunk size %p.",
+             (void*)dtohl(pkg->typeStrings), (void*)pkgSize);
+        return (mError=BAD_TYPE);
+    }
+    if ((dtohl(pkg->typeStrings)&0x3) != 0) {
+        LOGW("ResTable_package type strings at %p is not on an integer boundary.",
+             (void*)dtohl(pkg->typeStrings));
+        return (mError=BAD_TYPE);
+    }
+    if (dtohl(pkg->keyStrings) >= pkgSize) {
+        LOGW("ResTable_package key strings at %p are past chunk size %p.",
+             (void*)dtohl(pkg->keyStrings), (void*)pkgSize);
+        return (mError=BAD_TYPE);
+    }
+    if ((dtohl(pkg->keyStrings)&0x3) != 0) {
+        LOGW("ResTable_package key strings at %p is not on an integer boundary.",
+             (void*)dtohl(pkg->keyStrings));
+        return (mError=BAD_TYPE);
+    }
+    
+    Package* package = NULL;
+    PackageGroup* group = NULL;
+    uint32_t id = dtohl(pkg->id);
+    if (id != 0 && id < 256) {
+        size_t idx = mPackageMap[id];
+        if (idx == 0) {
+            idx = mPackageGroups.size()+1;
+
+            char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)];
+            strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t));
+            group = new PackageGroup(String16(tmpName), id);
+            if (group == NULL) {
+                return (mError=NO_MEMORY);
+            }
+
+            err = group->typeStrings.setTo(base+dtohl(pkg->typeStrings),
+                                           header->dataEnd-(base+dtohl(pkg->typeStrings)));
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+            err = group->keyStrings.setTo(base+dtohl(pkg->keyStrings),
+                                          header->dataEnd-(base+dtohl(pkg->keyStrings)));
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+
+            //printf("Adding new package id %d at index %d\n", id, idx);
+            err = mPackageGroups.add(group);
+            if (err < NO_ERROR) {
+                return (mError=err);
+            }
+            mPackageMap[id] = (uint8_t)idx;
+        } else {
+            group = mPackageGroups.itemAt(idx-1);
+            if (group == NULL) {
+                return (mError=UNKNOWN_ERROR);
+            }
+        }
+        package = new Package(header, pkg);
+        if (package == NULL) {
+            return (mError=NO_MEMORY);
+        }
+        err = group->packages.add(package);
+        if (err < NO_ERROR) {
+            return (mError=err);
+        }
+    } else {
+        LOG_ALWAYS_FATAL("Skins not supported!");
+        return NO_ERROR;
+    }
+
+    
+    // Iterate through all chunks.
+    size_t curPackage = 0;
+    
+    const ResChunk_header* chunk =
+        (const ResChunk_header*)(((const uint8_t*)pkg)
+                                 + dtohs(pkg->header.headerSize));
+    const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size);
+    while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) &&
+           ((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) {
+        TABLE_NOISY(LOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+                         dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
+                         (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
+        const size_t csize = dtohl(chunk->size);
+        const uint16_t ctype = dtohs(chunk->type);
+        if (ctype == RES_TABLE_TYPE_SPEC_TYPE) {
+            const ResTable_typeSpec* typeSpec = (const ResTable_typeSpec*)(chunk);
+            err = validate_chunk(&typeSpec->header, sizeof(*typeSpec),
+                                 endPos, "ResTable_typeSpec");
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+            
+            const size_t typeSpecSize = dtohl(typeSpec->header.size);
+            
+            LOAD_TABLE_NOISY(printf("TypeSpec off %p: type=0x%x, headerSize=0x%x, size=%p\n",
+                                    (void*)(base-(const uint8_t*)chunk),
+                                    dtohs(typeSpec->header.type),
+                                    dtohs(typeSpec->header.headerSize),
+                                    (void*)typeSize));
+            // look for block overrun or int overflow when multiplying by 4
+            if ((dtohl(typeSpec->entryCount) > (INT32_MAX/sizeof(uint32_t))
+                    || dtohs(typeSpec->header.headerSize)+(sizeof(uint32_t)*dtohl(typeSpec->entryCount))
+                    > typeSpecSize)) {
+                LOGW("ResTable_typeSpec entry index to %p extends beyond chunk end %p.",
+                     (void*)(dtohs(typeSpec->header.headerSize)
+                             +(sizeof(uint32_t)*dtohl(typeSpec->entryCount))),
+                     (void*)typeSpecSize);
+                return (mError=BAD_TYPE);
+            }
+            
+            if (typeSpec->id == 0) {
+                LOGW("ResTable_type has an id of 0.");
+                return (mError=BAD_TYPE);
+            }
+            
+            while (package->types.size() < typeSpec->id) {
+                package->types.add(NULL);
+            }
+            Type* t = package->types[typeSpec->id-1];
+            if (t == NULL) {
+                t = new Type(header, package, dtohl(typeSpec->entryCount));
+                package->types.editItemAt(typeSpec->id-1) = t;
+            } else if (dtohl(typeSpec->entryCount) != t->entryCount) {
+                LOGW("ResTable_typeSpec entry count inconsistent: given %d, previously %d",
+                    (int)dtohl(typeSpec->entryCount), (int)t->entryCount);
+                return (mError=BAD_TYPE);
+            }
+            t->typeSpecFlags = (const uint32_t*)(
+                    ((const uint8_t*)typeSpec) + dtohs(typeSpec->header.headerSize));
+            t->typeSpec = typeSpec;
+            
+        } else if (ctype == RES_TABLE_TYPE_TYPE) {
+            const ResTable_type* type = (const ResTable_type*)(chunk);
+            err = validate_chunk(&type->header, sizeof(*type)-sizeof(ResTable_config)+4,
+                                 endPos, "ResTable_type");
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+            
+            const size_t typeSize = dtohl(type->header.size);
+            
+            LOAD_TABLE_NOISY(printf("Type off %p: type=0x%x, headerSize=0x%x, size=%p\n",
+                                    (void*)(base-(const uint8_t*)chunk),
+                                    dtohs(type->header.type),
+                                    dtohs(type->header.headerSize),
+                                    (void*)typeSize));
+            if (dtohs(type->header.headerSize)+(sizeof(uint32_t)*dtohl(type->entryCount))
+                > typeSize) {
+                LOGW("ResTable_type entry index to %p extends beyond chunk end %p.",
+                     (void*)(dtohs(type->header.headerSize)
+                             +(sizeof(uint32_t)*dtohl(type->entryCount))),
+                     (void*)typeSize);
+                return (mError=BAD_TYPE);
+            }
+            if (dtohl(type->entryCount) != 0
+                && dtohl(type->entriesStart) > (typeSize-sizeof(ResTable_entry))) {
+                LOGW("ResTable_type entriesStart at %p extends beyond chunk end %p.",
+                     (void*)dtohl(type->entriesStart), (void*)typeSize);
+                return (mError=BAD_TYPE);
+            }
+            if (type->id == 0) {
+                LOGW("ResTable_type has an id of 0.");
+                return (mError=BAD_TYPE);
+            }
+            
+            while (package->types.size() < type->id) {
+                package->types.add(NULL);
+            }
+            Type* t = package->types[type->id-1];
+            if (t == NULL) {
+                t = new Type(header, package, dtohl(type->entryCount));
+                package->types.editItemAt(type->id-1) = t;
+            } else if (dtohl(type->entryCount) != t->entryCount) {
+                LOGW("ResTable_type entry count inconsistent: given %d, previously %d",
+                    (int)dtohl(type->entryCount), (int)t->entryCount);
+                return (mError=BAD_TYPE);
+            }
+            
+            TABLE_GETENTRY(
+                ResTable_config thisConfig;
+                thisConfig.copyFromDtoH(type->config);
+                LOGI("Adding config to type %d: imsi:%d/%d lang:%c%c cnt:%c%c "
+                     "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+                      type->id,
+                      thisConfig.mcc, thisConfig.mnc,
+                      thisConfig.language[0] ? thisConfig.language[0] : '-',
+                      thisConfig.language[1] ? thisConfig.language[1] : '-',
+                      thisConfig.country[0] ? thisConfig.country[0] : '-',
+                      thisConfig.country[1] ? thisConfig.country[1] : '-',
+                      thisConfig.orientation,
+                      thisConfig.touchscreen,
+                      thisConfig.density,
+                      thisConfig.keyboard,
+                      thisConfig.inputFlags,
+                      thisConfig.navigation,
+                      thisConfig.screenWidth,
+                      thisConfig.screenHeight));
+            t->configs.add(type);
+        } else {
+            status_t err = validate_chunk(chunk, sizeof(ResChunk_header),
+                                          endPos, "ResTable_package:unknown");
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+        }
+        chunk = (const ResChunk_header*)
+            (((const uint8_t*)chunk) + csize);
+    }
+
+    if (group->typeCount == 0) {
+        group->typeCount = package->types.size();
+    }
+    
+    return NO_ERROR;
+}
+
+#ifndef HAVE_ANDROID_OS
+#define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string())
+
+#define CHAR16_ARRAY_EQ(constant, var, len) \
+        ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len))))
+
+void ResTable::print() const
+{
+    printf("mError=0x%x (%s)\n", mError, strerror(mError));
+#if 0
+    printf("mParams=%c%c-%c%c,\n",
+            mParams.language[0], mParams.language[1],
+            mParams.country[0], mParams.country[1]);
+#endif
+    size_t pgCount = mPackageGroups.size();
+    printf("Package Groups (%d)\n", (int)pgCount);
+    for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) {
+        const PackageGroup* pg = mPackageGroups[pgIndex];
+        printf("Package Group %d id=%d packageCount=%d name=%s\n",
+                (int)pgIndex, pg->id, (int)pg->packages.size(),
+                String8(pg->name).string());
+        
+        size_t pkgCount = pg->packages.size();
+        for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) {
+            const Package* pkg = pg->packages[pkgIndex];
+            size_t typeCount = pkg->types.size();
+            printf("  Package %d id=%d name=%s typeCount=%d\n", (int)pkgIndex,
+                    pkg->package->id, String8(String16(pkg->package->name)).string(),
+                    (int)typeCount);
+            for (size_t typeIndex=0; typeIndex<typeCount; typeIndex++) {
+                const Type* typeConfigs = pkg->getType(typeIndex);
+                if (typeConfigs == NULL) {
+                    printf("    type %d NULL\n", (int)typeIndex);
+                    continue;
+                }
+                const size_t NTC = typeConfigs->configs.size();
+                printf("    type %d configCount=%d entryCount=%d\n",
+                       (int)typeIndex, (int)NTC, (int)typeConfigs->entryCount);
+                if (typeConfigs->typeSpecFlags != NULL) {
+                    for (size_t entryIndex=0; entryIndex<typeConfigs->entryCount; entryIndex++) {
+                        uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
+                                    | (0x00ff0000 & ((typeIndex+1)<<16))
+                                    | (0x0000ffff & (entryIndex));
+                        resource_name resName;
+                        this->getResourceName(resID, &resName);
+                        printf("      spec resource 0x%08x %s:%s/%s: flags=0x%08x\n",
+                            resID,
+                            CHAR16_TO_CSTR(resName.package, resName.packageLen),
+                            CHAR16_TO_CSTR(resName.type, resName.typeLen),
+                            CHAR16_TO_CSTR(resName.name, resName.nameLen),
+                            dtohl(typeConfigs->typeSpecFlags[entryIndex]));
+                    }
+                }
+                for (size_t configIndex=0; configIndex<NTC; configIndex++) {
+                    const ResTable_type* type = typeConfigs->configs[configIndex];
+                    if ((((uint64_t)type)&0x3) != 0) {
+                        printf("      NON-INTEGER ResTable_type ADDRESS: %p\n", type);
+                        continue;
+                    }
+                    printf("      config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%d key=%d infl=%d nav=%d w=%d h=%d\n",
+                           (int)configIndex,
+                           type->config.language[0] ? type->config.language[0] : '-',
+                           type->config.language[1] ? type->config.language[1] : '-',
+                           type->config.country[0] ? type->config.country[0] : '-',
+                           type->config.country[1] ? type->config.country[1] : '-',
+                           type->config.orientation,
+                           type->config.touchscreen,
+                           dtohs(type->config.density),
+                           type->config.keyboard,
+                           type->config.inputFlags,
+                           type->config.navigation,
+                           dtohs(type->config.screenWidth),
+                           dtohs(type->config.screenHeight));
+                    size_t entryCount = dtohl(type->entryCount);
+                    uint32_t entriesStart = dtohl(type->entriesStart);
+                    if ((entriesStart&0x3) != 0) {
+                        printf("      NON-INTEGER ResTable_type entriesStart OFFSET: %p\n", (void*)entriesStart);
+                        continue;
+                    }
+                    uint32_t typeSize = dtohl(type->header.size);
+                    if ((typeSize&0x3) != 0) {
+                        printf("      NON-INTEGER ResTable_type header.size: %p\n", (void*)typeSize);
+                        continue;
+                    }
+                    for (size_t entryIndex=0; entryIndex<entryCount; entryIndex++) {
+                        
+                        const uint8_t* const end = ((const uint8_t*)type)
+                            + dtohl(type->header.size);
+                        const uint32_t* const eindex = (const uint32_t*)
+                            (((const uint8_t*)type) + dtohs(type->header.headerSize));
+                        
+                        uint32_t thisOffset = dtohl(eindex[entryIndex]);
+                        if (thisOffset == ResTable_type::NO_ENTRY) {
+                            continue;
+                        }
+                        
+                        uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
+                                    | (0x00ff0000 & ((typeIndex+1)<<16))
+                                    | (0x0000ffff & (entryIndex));
+                        resource_name resName;
+                        this->getResourceName(resID, &resName);
+                        printf("        resource 0x%08x %s:%s/%s: ", resID,
+                                CHAR16_TO_CSTR(resName.package, resName.packageLen),
+                                CHAR16_TO_CSTR(resName.type, resName.typeLen),
+                                CHAR16_TO_CSTR(resName.name, resName.nameLen));
+                        if ((thisOffset&0x3) != 0) {
+                            printf("NON-INTEGER OFFSET: %p\n", (void*)thisOffset);
+                            continue;
+                        }
+                        if ((thisOffset+sizeof(ResTable_entry)) > typeSize) {
+                            printf("OFFSET OUT OF BOUNDS: %p+%p (size is %p)\n",
+                                   (void*)entriesStart, (void*)thisOffset,
+                                   (void*)typeSize);
+                            continue;
+                        }
+                        
+                        const ResTable_entry* ent = (const ResTable_entry*)
+                            (((const uint8_t*)type) + entriesStart + thisOffset);
+                        if (((entriesStart + thisOffset)&0x3) != 0) {
+                            printf("NON-INTEGER ResTable_entry OFFSET: %p\n",
+                                 (void*)(entriesStart + thisOffset));
+                            continue;
+                        }
+                        if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) {
+                            printf("<bag>");
+                        } else {
+                            uint16_t esize = dtohs(ent->size);
+                            if ((esize&0x3) != 0) {
+                                printf("NON-INTEGER ResTable_entry SIZE: %p\n", (void*)esize);
+                                continue;
+                            }
+                            if ((thisOffset+esize) > typeSize) {
+                                printf("ResTable_entry OUT OF BOUNDS: %p+%p+%p (size is %p)\n",
+                                       (void*)entriesStart, (void*)thisOffset,
+                                       (void*)esize, (void*)typeSize);
+                                continue;
+                            }
+                            
+                            const Res_value* value = (const Res_value*)
+                                (((const uint8_t*)ent) + esize);
+                            printf("t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)",
+                                   (int)value->dataType, (int)dtohl(value->data),
+                                   (int)dtohs(value->size), (int)value->res0);
+                        }
+                        
+                        if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) {
+                            printf(" (PUBLIC)");
+                        }
+                        printf("\n");
+                    }
+                }
+            }
+        }
+    }
+}
+
+#endif // HAVE_ANDROID_OS
+
+}   // namespace android
diff --git a/libs/utils/SharedBuffer.cpp b/libs/utils/SharedBuffer.cpp
new file mode 100644
index 0000000..3555fb7
--- /dev/null
+++ b/libs/utils/SharedBuffer.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2005 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 <stdlib.h>
+#include <string.h>
+
+#include <utils/SharedBuffer.h>
+#include <utils/Atomic.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+SharedBuffer* SharedBuffer::alloc(size_t size)
+{
+    SharedBuffer* sb = static_cast<SharedBuffer *>(malloc(sizeof(SharedBuffer) + size));
+    if (sb) {
+        sb->mRefs = 1;
+        sb->mSize = size;
+    }
+    return sb;
+}
+
+
+ssize_t SharedBuffer::dealloc(const SharedBuffer* released)
+{
+    if (released->mRefs != 0) return -1; // XXX: invalid operation
+    free(const_cast<SharedBuffer*>(released));
+    return 0;
+}
+
+SharedBuffer* SharedBuffer::edit() const
+{
+    if (onlyOwner()) {
+        return const_cast<SharedBuffer*>(this);
+    }
+    SharedBuffer* sb = alloc(mSize);
+    if (sb) {
+        memcpy(sb->data(), data(), size());
+        release();
+    }
+    return sb;    
+}
+
+SharedBuffer* SharedBuffer::editResize(size_t newSize) const
+{
+    if (onlyOwner()) {
+        SharedBuffer* buf = const_cast<SharedBuffer*>(this);
+        if (buf->mSize == newSize) return buf;
+        buf = (SharedBuffer*)realloc(buf, sizeof(SharedBuffer) + newSize);
+        if (buf != NULL) {
+            buf->mSize = newSize;
+            return buf;
+        }
+    }
+    SharedBuffer* sb = alloc(newSize);
+    if (sb) {
+        const size_t mySize = mSize;
+        memcpy(sb->data(), data(), newSize < mySize ? newSize : mySize);
+        release();
+    }
+    return sb;    
+}
+
+SharedBuffer* SharedBuffer::attemptEdit() const
+{
+    if (onlyOwner()) {
+        return const_cast<SharedBuffer*>(this);
+    }
+    return 0;
+}
+
+SharedBuffer* SharedBuffer::reset(size_t new_size) const
+{
+    // cheap-o-reset.
+    SharedBuffer* sb = alloc(new_size);
+    if (sb) {
+        release();
+    }
+    return sb;
+}
+
+void SharedBuffer::acquire() const {
+    android_atomic_inc(&mRefs);
+}
+
+int32_t SharedBuffer::release(uint32_t flags) const
+{
+    int32_t prev = 1;
+    if (onlyOwner() || ((prev = android_atomic_dec(&mRefs)) == 1)) {
+        mRefs = 0;
+        if ((flags & eKeepStorage) == 0) {
+            free(const_cast<SharedBuffer*>(this));
+        }
+    }
+    return prev;
+}
+
+
+}; // namespace android
diff --git a/libs/utils/Socket.cpp b/libs/utils/Socket.cpp
new file mode 100644
index 0000000..51509a3
--- /dev/null
+++ b/libs/utils/Socket.cpp
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+//
+// Internet address class.
+//
+
+#ifdef HAVE_WINSOCK
+// This needs to come first, or Cygwin gets concerned about a potential
+// clash between WinSock and <sys/types.h>.
+# include <winsock2.h>
+#endif
+
+#include <utils/Socket.h>
+#include <utils/inet_address.h>
+#include <utils/Log.h>
+#include <utils/Timers.h>
+
+#ifndef HAVE_WINSOCK
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+
+/*
+ * ===========================================================================
+ *      Socket
+ * ===========================================================================
+ */
+
+#ifndef INVALID_SOCKET
+# define INVALID_SOCKET (-1)
+#endif
+#define UNDEF_SOCKET   ((unsigned long) INVALID_SOCKET)
+
+/*static*/ bool Socket::mBootInitialized = false;
+
+/*
+ * Extract system-dependent error code.
+ */
+static inline int getSocketError(void) {
+#ifdef HAVE_WINSOCK
+    return WSAGetLastError();
+#else
+    return errno;
+#endif
+}
+
+/*
+ * One-time initialization for socket code.
+ */
+/*static*/ bool Socket::bootInit(void)
+{
+#ifdef HAVE_WINSOCK
+    WSADATA wsaData;
+    int err;
+
+    err = WSAStartup(MAKEWORD(2, 0), &wsaData);
+    if (err != 0) {
+        LOG(LOG_ERROR, "socket", "Unable to start WinSock\n");
+        return false;
+    }
+
+    LOG(LOG_INFO, "socket", "Using WinSock v%d.%d\n",
+        LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
+#endif
+
+    mBootInitialized = true;
+    return true;
+}
+
+/*
+ * One-time shutdown for socket code.
+ */
+/*static*/ void Socket::finalShutdown(void)
+{
+#ifdef HAVE_WINSOCK
+    WSACleanup();
+#endif
+    mBootInitialized = false;
+}
+
+
+/*
+ * Simple constructor.  Allow the application to create us and then make
+ * bind/connect calls.
+ */
+Socket::Socket(void)
+    : mSock(UNDEF_SOCKET)
+{
+    if (!mBootInitialized)
+        LOG(LOG_WARN, "socket", "WARNING: sockets not initialized\n");
+}
+
+/*
+ * Destructor.  Closes the socket and resets our storage.
+ */
+Socket::~Socket(void)
+{
+    close();
+}
+
+
+/*
+ * Create a socket and connect to the specified host and port.
+ */
+int Socket::connect(const char* host, int port)
+{
+    if (mSock != UNDEF_SOCKET) {
+        LOG(LOG_WARN, "socket", "Socket already connected\n");
+        return -1;
+    }
+
+    InetSocketAddress sockAddr;
+    if (!sockAddr.create(host, port))
+        return -1;
+
+    //return doConnect(sockAddr);
+    int foo;
+    foo = doConnect(sockAddr);
+    return foo;
+}
+
+/*
+ * Create a socket and connect to the specified host and port.
+ */
+int Socket::connect(const InetAddress* addr, int port)
+{
+    if (mSock != UNDEF_SOCKET) {
+        LOG(LOG_WARN, "socket", "Socket already connected\n");
+        return -1;
+    }
+
+    InetSocketAddress sockAddr;
+    if (!sockAddr.create(addr, port))
+        return -1;
+
+    return doConnect(sockAddr);
+}
+
+/*
+ * Finish creating a socket by connecting to the remote host.
+ *
+ * Returns 0 on success.
+ */
+int Socket::doConnect(const InetSocketAddress& sockAddr)
+{
+#ifdef HAVE_WINSOCK
+    SOCKET sock;
+#else
+    int sock;
+#endif
+    const InetAddress* addr = sockAddr.getAddress();
+    int port = sockAddr.getPort();
+    struct sockaddr_in inaddr;
+    DurationTimer connectTimer;
+
+    assert(sizeof(struct sockaddr_in) == addr->getAddressLength());
+    memcpy(&inaddr, addr->getAddress(), addr->getAddressLength());
+    inaddr.sin_port = htons(port);
+
+    //fprintf(stderr, "--- connecting to %s:%d\n",
+    //    sockAddr.getHostName(), port);
+
+    sock = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (sock == INVALID_SOCKET) {
+        int err = getSocketError();
+        LOG(LOG_ERROR, "socket", "Unable to create socket (err=%d)\n", err);
+        return (err != 0) ? err : -1;
+    }
+
+    connectTimer.start();
+
+    if (::connect(sock, (struct sockaddr*) &inaddr, sizeof(inaddr)) != 0) {
+        int err = getSocketError();
+        LOG(LOG_WARN, "socket", "Connect to %s:%d failed: %d\n",
+            sockAddr.getHostName(), port, err);
+        return (err != 0) ? err : -1;
+    }
+
+    connectTimer.stop();
+    if ((long) connectTimer.durationUsecs() > 100000) {
+        LOG(LOG_INFO, "socket",
+            "Connect to %s:%d took %.3fs\n", sockAddr.getHostName(),
+            port, ((long) connectTimer.durationUsecs()) / 1000000.0);
+    }
+
+    mSock = (unsigned long) sock;
+    LOG(LOG_VERBOSE, "socket",
+        "--- connected to %s:%d\n", sockAddr.getHostName(), port);
+    return 0;
+}
+
+
+/*
+ * Close the socket if it needs closing.
+ */
+bool Socket::close(void)
+{
+    if (mSock != UNDEF_SOCKET) {
+        //fprintf(stderr, "--- closing socket %lu\n", mSock);
+#ifdef HAVE_WINSOCK
+        if (::closesocket((SOCKET) mSock) != 0)
+            return false;
+#else
+        if (::close((int) mSock) != 0)
+            return false;
+#endif
+    }
+
+    mSock = UNDEF_SOCKET;
+
+    return true;
+}
+
+/*
+ * Read data from socket.
+ *
+ * Standard semantics: read up to "len" bytes into "buf".  Returns the
+ * number of bytes read, or less than zero on error.
+ */
+int Socket::read(void* buf, ssize_t len) const
+{
+    if (mSock == UNDEF_SOCKET) {
+        LOG(LOG_ERROR, "socket", "ERROR: read on invalid socket\n");
+        return -500;
+    }
+
+#ifdef HAVE_WINSOCK
+    SOCKET sock = (SOCKET) mSock;
+#else
+    int sock = (int) mSock;
+#endif
+    int cc;
+
+    cc = recv(sock, (char*)buf, len, 0);
+    if (cc < 0) {
+        int err = getSocketError();
+        return (err > 0) ? -err : -1;
+    }
+
+    return cc;
+}
+
+/*
+ * Write data to a socket.
+ *
+ * Standard semantics: write up to "len" bytes into "buf".  Returns the
+ * number of bytes written, or less than zero on error.
+ */
+int Socket::write(const void* buf, ssize_t len) const
+{
+    if (mSock == UNDEF_SOCKET) {
+        LOG(LOG_ERROR, "socket", "ERROR: write on invalid socket\n");
+        return -500;
+    }
+
+#ifdef HAVE_WINSOCK
+    SOCKET sock = (SOCKET) mSock;
+#else
+    int sock = (int) mSock;
+#endif
+    int cc;
+
+    cc = send(sock, (const char*)buf, len, 0);
+    if (cc < 0) {
+        int err = getSocketError();
+        return (err > 0) ? -err : -1;
+    }
+
+    return cc;
+}
+
+
+/*
+ * ===========================================================================
+ *      Socket tests
+ * ===========================================================================
+ */
+
+/*
+ * Read all data from the socket.  The data is read into a buffer that
+ * expands as needed.
+ *
+ * On exit, the buffer is returned, and the length of the data is stored
+ * in "*sz".  A null byte is added to the end, but is not included in
+ * the length.
+ */
+static char* socketReadAll(const Socket& s, int *sz)
+{
+    int max, r;
+    char *data, *ptr, *tmp;
+
+    data = (char*) malloc(max = 32768);
+    if (data == NULL)
+        return NULL;
+
+    ptr = data;
+    
+    for (;;) {
+        if ((ptr - data) == max) {
+            tmp = (char*) realloc(data, max *= 2);
+            if(tmp == 0) {
+                free(data);
+                return 0;
+            }
+        }
+        r = s.read(ptr, max - (ptr - data));
+        if (r == 0)
+            break;
+        if (r < 0) {
+            LOG(LOG_WARN, "socket", "WARNING: socket read failed (res=%d)\n",r);
+            break;
+        }
+        ptr += r;
+    }
+
+    if ((ptr - data) == max) {
+        tmp = (char*) realloc(data, max + 1);
+        if (tmp == NULL) {
+            free(data);
+            return NULL;
+        }
+    }
+    *ptr = '\0';
+    *sz = (ptr - data);
+    return data;
+}
+
+/*
+ * Exercise the Socket class.
+ */
+void android::TestSockets(void)
+{
+    printf("----- SOCKET TEST ------\n");
+    Socket::bootInit();
+
+    char* buf = NULL;
+    int len, cc;
+    const char* kTestStr =
+        "GET / HTTP/1.0\n"
+        "Connection: close\n"
+        "\n";
+
+    Socket sock;
+    if (sock.connect("www.google.com", 80) != 0) {
+        fprintf(stderr, "socket connected failed\n");
+        goto bail;
+    }
+
+    cc = sock.write(kTestStr, strlen(kTestStr));
+    if (cc != (int) strlen(kTestStr)) {
+        fprintf(stderr, "write failed, res=%d\n", cc);
+        goto bail;
+    }
+    buf = socketReadAll(sock, &len);
+
+    printf("GOT '%s'\n", buf);
+
+bail:
+    sock.close();
+    free(buf);
+}
+
diff --git a/libs/utils/Static.cpp b/libs/utils/Static.cpp
new file mode 100644
index 0000000..93f7e4f
--- /dev/null
+++ b/libs/utils/Static.cpp
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+// All static variables go here, to control initialization and
+// destruction order in the library.
+
+#include <private/utils/Static.h>
+
+#include <utils/BufferedTextOutput.h>
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+
+namespace android {
+
+class LibUtilsFirstStatics
+{
+public:
+    LibUtilsFirstStatics()
+    {
+        initialize_string8();
+        initialize_string16();
+    }
+    
+    ~LibUtilsFirstStatics()
+    {
+        terminate_string16();
+        terminate_string8();
+    }
+};
+
+static LibUtilsFirstStatics gFirstStatics;
+int gDarwinCantLoadAllObjects = 1;
+
+// ------------ Text output streams
+
+Vector<int32_t> gTextBuffers;
+
+class LogTextOutput : public BufferedTextOutput
+{
+public:
+    LogTextOutput() : BufferedTextOutput(MULTITHREADED) { }
+    virtual ~LogTextOutput() { };
+
+protected:
+    virtual status_t writeLines(const struct iovec& vec, size_t N)
+    {
+        android_writevLog(&vec, N);
+        return NO_ERROR;
+    }
+};
+
+class FdTextOutput : public BufferedTextOutput
+{
+public:
+    FdTextOutput(int fd) : BufferedTextOutput(MULTITHREADED), mFD(fd) { }
+    virtual ~FdTextOutput() { };
+
+protected:
+    virtual status_t writeLines(const struct iovec& vec, size_t N)
+    {
+        writev(mFD, &vec, N);
+        return NO_ERROR;
+    }
+
+private:
+    int mFD;
+};
+
+static LogTextOutput gLogTextOutput;
+static FdTextOutput gStdoutTextOutput(STDOUT_FILENO);
+static FdTextOutput gStderrTextOutput(STDERR_FILENO);
+
+TextOutput& alog(gLogTextOutput);
+TextOutput& aout(gStdoutTextOutput);
+TextOutput& aerr(gStderrTextOutput);
+
+#ifndef LIBUTILS_NATIVE
+
+// ------------ ProcessState.cpp
+
+Mutex gProcessMutex;
+sp<ProcessState> gProcess;
+
+class LibUtilsIPCtStatics
+{
+public:
+    LibUtilsIPCtStatics()
+    {
+    }
+    
+    ~LibUtilsIPCtStatics()
+    {
+        IPCThreadState::shutdown();
+    }
+};
+
+static LibUtilsIPCtStatics gIPCStatics;
+
+// ------------ ServiceManager.cpp
+
+Mutex gDefaultServiceManagerLock;
+sp<IServiceManager> gDefaultServiceManager;
+sp<IPermissionController> gPermissionController;
+
+#endif
+
+}   // namespace android
diff --git a/libs/utils/StopWatch.cpp b/libs/utils/StopWatch.cpp
new file mode 100644
index 0000000..68a1c52
--- /dev/null
+++ b/libs/utils/StopWatch.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2005 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 "StopWatch"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/StopWatch.h>
+
+/*****************************************************************************/
+
+namespace android {
+
+
+StopWatch::StopWatch(const char *name, int clock, uint32_t flags)
+    :   mName(name), mClock(clock), mFlags(flags),
+        mStartTime(0), mNumLaps(0)
+{
+    mStartTime = systemTime(mClock);
+}
+
+StopWatch::~StopWatch()
+{
+    nsecs_t elapsed = elapsedTime();
+    const int n = mNumLaps;
+    LOGD("StopWatch %s (us): %lld ", mName, ns2us(elapsed));
+    for (int i=0 ; i<n ; i++) {
+        const nsecs_t soFar = mLaps[i].soFar;
+        const nsecs_t thisLap = mLaps[i].thisLap;
+        LOGD(" [%d: %lld, %lld]", i, ns2us(soFar), ns2us(thisLap));
+    }
+}
+
+const char* StopWatch::name() const
+{
+    return mName;
+}
+
+nsecs_t StopWatch::lap()
+{
+    nsecs_t elapsed = elapsedTime();
+    if (mNumLaps >= 8) {
+        elapsed = 0;
+    } else {
+        const int n = mNumLaps;
+        mLaps[n].soFar   = elapsed;
+        mLaps[n].thisLap = n ? (elapsed - mLaps[n-1].soFar) : elapsed;
+        mNumLaps = n+1;
+    }
+    return elapsed;
+}
+
+nsecs_t StopWatch::elapsedTime() const
+{
+    return systemTime(mClock) - mStartTime;
+}
+
+
+/*****************************************************************************/
+
+}; // namespace android
+
diff --git a/libs/utils/String16.cpp b/libs/utils/String16.cpp
new file mode 100644
index 0000000..1f81cad
--- /dev/null
+++ b/libs/utils/String16.cpp
@@ -0,0 +1,609 @@
+/*
+ * Copyright (C) 2005 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 <utils/String16.h>
+
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/TextOutput.h>
+#include <utils/threads.h>
+
+#include <private/utils/Static.h>
+
+#ifdef HAVE_WINSOCK
+# undef  nhtol
+# undef  htonl
+# undef  nhtos
+# undef  htons
+
+# ifdef HAVE_LITTLE_ENDIAN
+#  define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
+#  define htonl(x)    ntohl(x)
+#  define ntohs(x)    ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
+#  define htons(x)    ntohs(x)
+# else
+#  define ntohl(x)    (x)
+#  define htonl(x)    (x)
+#  define ntohs(x)    (x)
+#  define htons(x)    (x)
+# endif
+#else
+# include <netinet/in.h>
+#endif
+
+#include <memory.h>
+#include <stdio.h>
+#include <ctype.h>
+
+// ---------------------------------------------------------------------------
+
+int strcmp16(const char16_t *s1, const char16_t *s2)
+{
+  char16_t ch;
+  int d = 0;
+
+  while ( 1 ) {
+    d = (int)(ch = *s1++) - (int)*s2++;
+    if ( d || !ch )
+      break;
+  }
+
+  return d;
+}
+
+int strncmp16(const char16_t *s1, const char16_t *s2, size_t n)
+{
+  char16_t ch;
+  int d = 0;
+
+  while ( n-- ) {
+    d = (int)(ch = *s1++) - (int)*s2++;
+    if ( d || !ch )
+      break;
+  }
+
+  return d;
+}
+
+char16_t *strcpy16(char16_t *dst, const char16_t *src)
+{
+  char16_t *q = dst;
+  const char16_t *p = src;
+  char16_t ch;
+
+  do {
+    *q++ = ch = *p++;
+  } while ( ch );
+
+  return dst;
+}
+
+size_t strlen16(const char16_t *s)
+{
+  const char16_t *ss = s;
+  while ( *ss )
+    ss++;
+  return ss-s;
+}
+
+
+char16_t *strncpy16(char16_t *dst, const char16_t *src, size_t n)
+{
+  char16_t *q = dst;
+  const char16_t *p = src;
+  char ch;
+
+  while (n) {
+    n--;
+    *q++ = ch = *p++;
+    if ( !ch )
+      break;
+  }
+
+  *q = 0;
+
+  return dst;
+}
+
+size_t strnlen16(const char16_t *s, size_t maxlen)
+{
+  const char16_t *ss = s;
+
+  /* Important: the maxlen test must precede the reference through ss;
+     since the byte beyond the maximum may segfault */
+  while ((maxlen > 0) && *ss) {
+    ss++;
+    maxlen--;
+  }
+  return ss-s;
+}
+
+int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)
+{
+    const char16_t* e1 = s1+n1;
+    const char16_t* e2 = s2+n2;
+
+    while (s1 < e1 && s2 < e2) {
+        const int d = (int)*s1++ - (int)*s2++;
+        if (d) {
+            return d;
+        }
+    }
+
+    return n1 < n2
+        ? (0 - (int)*s2)
+        : (n1 > n2
+           ? ((int)*s1 - 0)
+           : 0);
+}
+
+int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2)
+{
+    const char16_t* e1 = s1H+n1;
+    const char16_t* e2 = s2N+n2;
+
+    while (s1H < e1 && s2N < e2) {
+        const char16_t c2 = ntohs(*s2N);
+        const int d = (int)*s1H++ - (int)c2;
+        s2N++;
+        if (d) {
+            return d;
+        }
+    }
+
+    return n1 < n2
+        ? (0 - (int)ntohs(*s2N))
+        : (n1 > n2
+           ? ((int)*s1H - 0)
+           : 0);
+}
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+static inline size_t
+utf8_char_len(uint8_t ch)
+{
+    return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1;
+}
+
+#define UTF8_SHIFT_AND_MASK(unicode, byte)  (unicode)<<=6; (unicode) |= (0x3f & (byte));
+
+static inline uint32_t
+utf8_to_utf32(const uint8_t *src, size_t length)
+{
+    uint32_t unicode;
+
+    switch (length)
+    {
+        case 1:
+            return src[0];
+        case 2:
+            unicode = src[0] & 0x1f;
+            UTF8_SHIFT_AND_MASK(unicode, src[1])
+            return unicode;
+        case 3:
+            unicode = src[0] & 0x0f;
+            UTF8_SHIFT_AND_MASK(unicode, src[1])
+            UTF8_SHIFT_AND_MASK(unicode, src[2])
+            return unicode;
+        case 4:
+            unicode = src[0] & 0x07;
+            UTF8_SHIFT_AND_MASK(unicode, src[1])
+            UTF8_SHIFT_AND_MASK(unicode, src[2])
+            UTF8_SHIFT_AND_MASK(unicode, src[3])
+            return unicode;
+        default:
+            return 0xffff;
+    }
+    
+    //printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result);
+}
+
+// ---------------------------------------------------------------------------
+
+static SharedBuffer* gEmptyStringBuf = NULL;
+static char16_t* gEmptyString = NULL;
+
+static inline char16_t* getEmptyString()
+{
+    gEmptyStringBuf->acquire();
+   return gEmptyString;
+}
+
+void initialize_string16()
+{
+    SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t));
+    char16_t* str = (char16_t*)buf->data();
+    *str = 0;
+    gEmptyStringBuf = buf;
+    gEmptyString = str;
+}
+
+void terminate_string16()
+{
+    SharedBuffer::bufferFromData(gEmptyString)->release();
+    gEmptyStringBuf = NULL;
+    gEmptyString = NULL;
+}
+
+// ---------------------------------------------------------------------------
+
+// Note: not dealing with generating surrogate pairs.
+static char16_t* allocFromUTF8(const char* in, size_t len)
+{
+    if (len == 0) return getEmptyString();
+    
+    size_t chars = 0;
+    const char* end = in+len;
+    const char* p = in;
+    
+    while (p < end) {
+        chars++;
+        p += utf8_char_len(*p);
+    }
+    
+    SharedBuffer* buf = SharedBuffer::alloc((chars+1)*sizeof(char16_t));
+    if (buf) {
+        p = in;
+        char16_t* str = (char16_t*)buf->data();
+        char16_t* d = str;
+        while (p < end) {
+            size_t len = utf8_char_len(*p);
+            *d++ = (char16_t)utf8_to_utf32((const uint8_t*)p, len);
+            p += len;
+        }
+        *d = 0;
+        
+        //printf("Created UTF-16 string from UTF-8 \"%s\":", in);
+        //printHexData(1, str, buf->size(), 16, 1);
+        //printf("\n");
+        
+        return str;
+    }
+    
+    return getEmptyString();
+}
+
+// ---------------------------------------------------------------------------
+
+String16::String16()
+    : mString(getEmptyString())
+{
+}
+
+String16::String16(const String16& o)
+    : mString(o.mString)
+{
+    SharedBuffer::bufferFromData(mString)->acquire();
+}
+
+String16::String16(const String16& o, size_t len, size_t begin)
+    : mString(getEmptyString())
+{
+    setTo(o, len, begin);
+}
+
+String16::String16(const char16_t* o)
+{
+    size_t len = strlen16(o);
+    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
+    LOG_ASSERT(buf, "Unable to allocate shared buffer");
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        strcpy16(str, o);
+        mString = str;
+        return;
+    }
+    
+    mString = getEmptyString();
+}
+
+String16::String16(const char16_t* o, size_t len)
+{
+    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
+    LOG_ASSERT(buf, "Unable to allocate shared buffer");
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        memcpy(str, o, len*sizeof(char16_t));
+        str[len] = 0;
+        mString = str;
+        return;
+    }
+    
+    mString = getEmptyString();
+}
+
+String16::String16(const String8& o)
+    : mString(allocFromUTF8(o.string(), o.size()))
+{
+}
+
+String16::String16(const char* o)
+    : mString(allocFromUTF8(o, strlen(o)))
+{
+}
+
+String16::String16(const char* o, size_t len)
+    : mString(allocFromUTF8(o, len))
+{
+}
+
+String16::~String16()
+{
+    SharedBuffer::bufferFromData(mString)->release();
+}
+
+void String16::setTo(const String16& other)
+{
+    SharedBuffer::bufferFromData(other.mString)->acquire();
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = other.mString;
+}
+
+status_t String16::setTo(const String16& other, size_t len, size_t begin)
+{
+    const size_t N = other.size();
+    if (begin >= N) {
+        SharedBuffer::bufferFromData(mString)->release();
+        mString = getEmptyString();
+        return NO_ERROR;
+    }
+    if ((begin+len) > N) len = N-begin;
+    if (begin == 0 && len == N) {
+        setTo(other);
+        return NO_ERROR;
+    }
+
+    if (&other == this) {
+        LOG_ALWAYS_FATAL("Not implemented");
+    }
+
+    return setTo(other.string()+begin, len);
+}
+
+status_t String16::setTo(const char16_t* other)
+{
+    return setTo(other, strlen16(other));
+}
+
+status_t String16::setTo(const char16_t* other, size_t len)
+{
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((len+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        memcpy(str, other, len*sizeof(char16_t));
+        str[len] = 0;
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+status_t String16::append(const String16& other)
+{
+    const size_t myLen = size();
+    const size_t otherLen = other.size();
+    if (myLen == 0) {
+        setTo(other);
+        return NO_ERROR;
+    } else if (otherLen == 0) {
+        return NO_ERROR;
+    }
+    
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((myLen+otherLen+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t));
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+status_t String16::append(const char16_t* chrs, size_t otherLen)
+{
+    const size_t myLen = size();
+    if (myLen == 0) {
+        setTo(chrs, otherLen);
+        return NO_ERROR;
+    } else if (otherLen == 0) {
+        return NO_ERROR;
+    }
+    
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((myLen+otherLen+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        memcpy(str+myLen, chrs, otherLen*sizeof(char16_t));
+        str[myLen+otherLen] = 0;
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+status_t String16::insert(size_t pos, const char16_t* chrs)
+{
+    return insert(pos, chrs, strlen16(chrs));
+}
+
+status_t String16::insert(size_t pos, const char16_t* chrs, size_t len)
+{
+    const size_t myLen = size();
+    if (myLen == 0) {
+        return setTo(chrs, len);
+        return NO_ERROR;
+    } else if (len == 0) {
+        return NO_ERROR;
+    }
+
+    if (pos > myLen) pos = myLen;
+
+    #if 0
+    printf("Insert in to %s: pos=%d, len=%d, myLen=%d, chrs=%s\n",
+           String8(*this).string(), pos,
+           len, myLen, String8(chrs, len).string());
+    #endif
+
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((myLen+len+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        if (pos < myLen) {
+            memmove(str+pos+len, str+pos, (myLen-pos)*sizeof(char16_t));
+        }
+        memcpy(str+pos, chrs, len*sizeof(char16_t));
+        str[myLen+len] = 0;
+        mString = str;
+        #if 0
+        printf("Result (%d chrs): %s\n", size(), String8(*this).string());
+        #endif
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+ssize_t String16::findFirst(char16_t c) const
+{
+    const char16_t* str = string();
+    const char16_t* p = str;
+    const char16_t* e = p + size();
+    while (p < e) {
+        if (*p == c) {
+            return p-str;
+        }
+        p++;
+    }
+    return -1;
+}
+
+ssize_t String16::findLast(char16_t c) const
+{
+    const char16_t* str = string();
+    const char16_t* p = str;
+    const char16_t* e = p + size();
+    while (p < e) {
+        e--;
+        if (*e == c) {
+            return e-str;
+        }
+    }
+    return -1;
+}
+
+bool String16::startsWith(const String16& prefix) const
+{
+    const size_t ps = prefix.size();
+    if (ps > size()) return false;
+    return strzcmp16(mString, ps, prefix.string(), ps) == 0;
+}
+
+bool String16::startsWith(const char16_t* prefix) const
+{
+    const size_t ps = strlen16(prefix);
+    if (ps > size()) return false;
+    return strncmp16(mString, prefix, ps) == 0;
+}
+
+status_t String16::makeLower()
+{
+    const size_t N = size();
+    const char16_t* str = string();
+    char16_t* edit = NULL;
+    for (size_t i=0; i<N; i++) {
+        const char16_t v = str[i];
+        if (v >= 'A' && v <= 'Z') {
+            if (!edit) {
+                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
+                if (!buf) {
+                    return NO_MEMORY;
+                }
+                edit = (char16_t*)buf->data();
+                mString = str = edit;
+            }
+            edit[i] = tolower((char)v);
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t String16::replaceAll(char16_t replaceThis, char16_t withThis)
+{
+    const size_t N = size();
+    const char16_t* str = string();
+    char16_t* edit = NULL;
+    for (size_t i=0; i<N; i++) {
+        if (str[i] == replaceThis) {
+            if (!edit) {
+                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
+                if (!buf) {
+                    return NO_MEMORY;
+                }
+                edit = (char16_t*)buf->data();
+                mString = str = edit;
+            }
+            edit[i] = withThis;
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t String16::remove(size_t len, size_t begin)
+{
+    const size_t N = size();
+    if (begin >= N) {
+        SharedBuffer::bufferFromData(mString)->release();
+        mString = getEmptyString();
+        return NO_ERROR;
+    }
+    if ((begin+len) > N) len = N-begin;
+    if (begin == 0 && len == N) {
+        return NO_ERROR;
+    }
+
+    if (begin > 0) {
+        SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+            ->editResize((N+1)*sizeof(char16_t));
+        if (!buf) {
+            return NO_MEMORY;
+        }
+        char16_t* str = (char16_t*)buf->data();
+        memmove(str, str+begin, (N-begin+1)*sizeof(char16_t));
+        mString = str;
+    }
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((len+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        str[len] = 0;
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+TextOutput& operator<<(TextOutput& to, const String16& val)
+{
+    to << String8(val).string();
+    return to;
+}
+
+}; // namespace android
diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp
new file mode 100644
index 0000000..c50d343
--- /dev/null
+++ b/libs/utils/String8.cpp
@@ -0,0 +1,604 @@
+/*
+ * Copyright (C) 2005 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 <utils/String8.h>
+
+#include <utils/Log.h>
+#include <utils/String16.h>
+#include <utils/TextOutput.h>
+#include <utils/threads.h>
+
+#include <private/utils/Static.h>
+
+#include <ctype.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+static const uint32_t kByteMask = 0x000000BF;
+static const uint32_t kByteMark = 0x00000080;
+
+// Surrogates aren't valid for UTF-32 characters, so define some
+// constants that will let us screen them out.
+static const uint32_t kUnicodeSurrogateHighStart  = 0x0000D800;
+static const uint32_t kUnicodeSurrogateHighEnd    = 0x0000DBFF;
+static const uint32_t kUnicodeSurrogateLowStart   = 0x0000DC00;
+static const uint32_t kUnicodeSurrogateLowEnd     = 0x0000DFFF;
+static const uint32_t kUnicodeSurrogateStart      = kUnicodeSurrogateHighStart;
+static const uint32_t kUnicodeSurrogateEnd        = kUnicodeSurrogateLowEnd;
+
+// Mask used to set appropriate bits in first byte of UTF-8 sequence,
+// indexed by number of bytes in the sequence.
+static const uint32_t kFirstByteMark[] = {
+    0x00000000, 0x00000000, 0x000000C0, 0x000000E0, 0x000000F0
+};
+
+// Separator used by resource paths. This is not platform dependent contrary
+// to OS_PATH_SEPARATOR.
+#define RES_PATH_SEPARATOR '/'
+
+// Return number of utf8 bytes required for the character.
+static size_t utf32_to_utf8_bytes(uint32_t srcChar)
+{
+    size_t bytesToWrite;
+
+    // Figure out how many bytes the result will require.
+    if (srcChar < 0x00000080)
+    {
+        bytesToWrite = 1;
+    }
+    else if (srcChar < 0x00000800)
+    {
+        bytesToWrite = 2;
+    }
+    else if (srcChar < 0x00010000)
+    {
+        if ((srcChar < kUnicodeSurrogateStart)
+         || (srcChar > kUnicodeSurrogateEnd))
+        {
+            bytesToWrite = 3;
+        }
+        else
+        {
+            // Surrogates are invalid UTF-32 characters.
+            return 0;
+        }
+    }
+    // Max code point for Unicode is 0x0010FFFF.
+    else if (srcChar < 0x00110000)
+    {
+        bytesToWrite = 4;
+    }
+    else
+    {
+        // Invalid UTF-32 character.
+        return 0;
+    }
+
+    return bytesToWrite;
+}
+
+// Write out the source character to <dstP>.
+
+static void utf32_to_utf8(uint8_t* dstP, uint32_t srcChar, size_t bytes)
+{
+    dstP += bytes;
+    switch (bytes)
+    {   /* note: everything falls through. */
+        case 4: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+        case 3: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+        case 2: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+        case 1: *--dstP = (uint8_t)(srcChar | kFirstByteMark[bytes]);
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+static SharedBuffer* gEmptyStringBuf = NULL;
+static char* gEmptyString = NULL;
+
+extern int gDarwinCantLoadAllObjects;
+int gDarwinIsReallyAnnoying;
+
+static inline char* getEmptyString()
+{
+    gEmptyStringBuf->acquire();
+    return gEmptyString;
+}
+
+void initialize_string8()
+{
+#ifdef LIBUTILS_NATIVE
+	  // Bite me, Darwin!
+		gDarwinIsReallyAnnoying = gDarwinCantLoadAllObjects;
+#endif
+			
+    SharedBuffer* buf = SharedBuffer::alloc(1);
+    char* str = (char*)buf->data();
+    *str = 0;
+    gEmptyStringBuf = buf;
+    gEmptyString = str;
+}
+
+void terminate_string8()
+{
+    SharedBuffer::bufferFromData(gEmptyString)->release();
+    gEmptyStringBuf = NULL;
+    gEmptyString = NULL;
+}
+
+// ---------------------------------------------------------------------------
+
+static char* allocFromUTF8(const char* in, size_t len)
+{
+    if (len > 0) {
+        SharedBuffer* buf = SharedBuffer::alloc(len+1);
+        LOG_ASSERT(buf, "Unable to allocate shared buffer");
+        if (buf) {
+            char* str = (char*)buf->data();
+            memcpy(str, in, len);
+            str[len] = 0;
+            return str;
+        }
+        return NULL;
+    }
+
+    return getEmptyString();
+}
+
+// Note: not dealing with expanding surrogate pairs.
+static char* allocFromUTF16(const char16_t* in, size_t len)
+{
+    if (len == 0) return getEmptyString();
+    
+    size_t bytes = 0;
+    const char16_t* end = in+len;
+    const char16_t* p = in;
+    
+    while (p < end) {
+        bytes += utf32_to_utf8_bytes(*p);
+        p++;
+    }
+    
+    SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
+    LOG_ASSERT(buf, "Unable to allocate shared buffer");
+    if (buf) {
+        p = in;
+        char* str = (char*)buf->data();
+        char* d = str;
+        while (p < end) {
+            uint32_t c = *p++;
+            size_t len = utf32_to_utf8_bytes(c);
+            utf32_to_utf8((uint8_t*)d, c, len);
+            d += len;
+        }
+        *d = 0;
+        
+        return str;
+    }
+    
+    return getEmptyString();
+}
+
+// ---------------------------------------------------------------------------
+
+String8::String8()
+    : mString(getEmptyString())
+{
+}
+
+String8::String8(const String8& o)
+    : mString(o.mString)
+{
+    SharedBuffer::bufferFromData(mString)->acquire();
+}
+
+String8::String8(const char* o)
+    : mString(allocFromUTF8(o, strlen(o)))
+{
+    if (mString == NULL) {
+        mString = getEmptyString();
+    }
+}
+
+String8::String8(const char* o, size_t len)
+    : mString(allocFromUTF8(o, len))
+{
+    if (mString == NULL) {
+        mString = getEmptyString();
+    }
+}
+
+String8::String8(const String16& o)
+    : mString(allocFromUTF16(o.string(), o.size()))
+{
+}
+
+String8::String8(const char16_t* o)
+    : mString(allocFromUTF16(o, strlen16(o)))
+{
+}
+
+String8::String8(const char16_t* o, size_t len)
+    : mString(allocFromUTF16(o, len))
+{
+}
+
+String8::~String8()
+{
+    SharedBuffer::bufferFromData(mString)->release();
+}
+
+void String8::setTo(const String8& other)
+{
+    SharedBuffer::bufferFromData(other.mString)->acquire();
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = other.mString;
+}
+
+status_t String8::setTo(const char* other)
+{
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = allocFromUTF8(other, strlen(other));
+    if (mString) return NO_ERROR;
+
+    mString = getEmptyString();
+    return NO_MEMORY;
+}
+
+status_t String8::setTo(const char* other, size_t len)
+{
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = allocFromUTF8(other, len);
+    if (mString) return NO_ERROR;
+
+    mString = getEmptyString();
+    return NO_MEMORY;
+}
+
+status_t String8::setTo(const char16_t* other, size_t len)
+{
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = allocFromUTF16(other, len);
+    if (mString) return NO_ERROR;
+
+    mString = getEmptyString();
+    return NO_MEMORY;
+}
+
+status_t String8::append(const String8& other)
+{
+    const size_t otherLen = other.bytes();
+    if (bytes() == 0) {
+        setTo(other);
+        return NO_ERROR;
+    } else if (otherLen == 0) {
+        return NO_ERROR;
+    }
+
+    return real_append(other.string(), otherLen);
+}
+
+status_t String8::append(const char* other)
+{
+    return append(other, strlen(other));
+}
+
+status_t String8::append(const char* other, size_t otherLen)
+{
+    if (bytes() == 0) {
+        return setTo(other, otherLen);
+    } else if (otherLen == 0) {
+        return NO_ERROR;
+    }
+
+    return real_append(other, otherLen);
+}
+
+status_t String8::real_append(const char* other, size_t otherLen)
+{
+    const size_t myLen = bytes();
+    
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize(myLen+otherLen+1);
+    if (buf) {
+        char* str = (char*)buf->data();
+        mString = str;
+        str += myLen;
+        memcpy(str, other, otherLen);
+        str[otherLen] = '\0';
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+char* String8::lockBuffer(size_t size)
+{
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize(size+1);
+    if (buf) {
+        char* str = (char*)buf->data();
+        mString = str;
+        return str;
+    }
+    return NULL;
+}
+
+void String8::unlockBuffer()
+{
+    unlockBuffer(strlen(mString));
+}
+
+status_t String8::unlockBuffer(size_t size)
+{
+    if (size != this->size()) {
+        SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+            ->editResize(size+1);
+        if (buf) {
+            char* str = (char*)buf->data();
+            str[size] = 0;
+            mString = str;
+            return NO_ERROR;
+        }
+    }
+    
+    return NO_MEMORY;
+}
+
+ssize_t String8::find(const char* other, size_t start) const
+{
+    size_t len = size();
+    if (start >= len) {
+        return -1;
+    }
+    const char* s = mString+start;
+    const char* p = strstr(s, other);
+    return p ? p-mString : -1;
+}
+
+void String8::toLower()
+{
+    toLower(0, size());
+}
+
+void String8::toLower(size_t start, size_t length)
+{
+    const size_t len = size();
+    if (start >= len) {
+        return;
+    }
+    if (start+length > len) {
+        length = len-start;
+    }
+    char* buf = lockBuffer(len);
+    buf += start;
+    while (length > 0) {
+        *buf = tolower(*buf);
+        buf++;
+        length--;
+    }
+    unlockBuffer(len);
+}
+
+void String8::toUpper()
+{
+    toUpper(0, size());
+}
+
+void String8::toUpper(size_t start, size_t length)
+{
+    const size_t len = size();
+    if (start >= len) {
+        return;
+    }
+    if (start+length > len) {
+        length = len-start;
+    }
+    char* buf = lockBuffer(len);
+    buf += start;
+    while (length > 0) {
+        *buf = toupper(*buf);
+        buf++;
+        length--;
+    }
+    unlockBuffer(len);
+}
+
+TextOutput& operator<<(TextOutput& to, const String8& val)
+{
+    to << val.string();
+    return to;
+}
+
+// ---------------------------------------------------------------------------
+// Path functions
+
+
+void String8::setPathName(const char* name)
+{
+    setPathName(name, strlen(name));
+}
+
+void String8::setPathName(const char* name, size_t len)
+{
+    char* buf = lockBuffer(len);
+
+    memcpy(buf, name, len);
+
+    // remove trailing path separator, if present
+    if (len > 0 && buf[len-1] == OS_PATH_SEPARATOR)
+        len--;
+
+    buf[len] = '\0';
+
+    unlockBuffer(len);
+}
+
+String8 String8::getPathLeaf(void) const
+{
+    const char* cp;
+    const char*const buf = mString;
+
+    cp = strrchr(buf, OS_PATH_SEPARATOR);
+    if (cp == NULL)
+        return String8(*this);
+    else
+        return String8(cp+1);
+}
+
+String8 String8::getPathDir(void) const
+{
+    const char* cp;
+    const char*const str = mString;
+
+    cp = strrchr(str, OS_PATH_SEPARATOR);
+    if (cp == NULL)
+        return String8("");
+    else
+        return String8(str, cp - str);
+}
+
+String8 String8::walkPath(String8* outRemains) const
+{
+    const char* cp;
+    const char*const str = mString;
+    const char* buf = str;
+
+    cp = strchr(buf, OS_PATH_SEPARATOR);
+    if (cp == buf) {
+        // don't include a leading '/'.
+        buf = buf+1;
+        cp = strchr(buf, OS_PATH_SEPARATOR);
+    }
+
+    if (cp == NULL) {
+        String8 res = buf != str ? String8(buf) : *this;
+        if (outRemains) *outRemains = String8("");
+        return res;
+    }
+
+    String8 res(buf, cp-buf);
+    if (outRemains) *outRemains = String8(cp+1);
+    return res;
+}
+
+/*
+ * Helper function for finding the start of an extension in a pathname.
+ *
+ * Returns a pointer inside mString, or NULL if no extension was found.
+ */
+char* String8::find_extension(void) const
+{
+    const char* lastSlash;
+    const char* lastDot;
+    int extLen;
+    const char* const str = mString;
+
+    // only look at the filename
+    lastSlash = strrchr(str, OS_PATH_SEPARATOR);
+    if (lastSlash == NULL)
+        lastSlash = str;
+    else
+        lastSlash++;
+
+    // find the last dot
+    lastDot = strrchr(lastSlash, '.');
+    if (lastDot == NULL)
+        return NULL;
+
+    // looks good, ship it
+    return const_cast<char*>(lastDot);
+}
+
+String8 String8::getPathExtension(void) const
+{
+    char* ext;
+
+    ext = find_extension();
+    if (ext != NULL)
+        return String8(ext);
+    else
+        return String8("");
+}
+
+String8 String8::getBasePath(void) const
+{
+    char* ext;
+    const char* const str = mString;
+
+    ext = find_extension();
+    if (ext == NULL)
+        return String8(*this);
+    else
+        return String8(str, ext - str);
+}
+
+String8& String8::appendPath(const char* name)
+{
+    // TODO: The test below will fail for Win32 paths. Fix later or ignore.
+    if (name[0] != OS_PATH_SEPARATOR) {
+        if (*name == '\0') {
+            // nothing to do
+            return *this;
+        }
+
+        size_t len = length();
+        if (len == 0) {
+            // no existing filename, just use the new one
+            setPathName(name);
+            return *this;
+        }
+
+        // make room for oldPath + '/' + newPath
+        int newlen = strlen(name);
+
+        char* buf = lockBuffer(len+1+newlen);
+
+        // insert a '/' if needed
+        if (buf[len-1] != OS_PATH_SEPARATOR)
+            buf[len++] = OS_PATH_SEPARATOR;
+
+        memcpy(buf+len, name, newlen+1);
+        len += newlen;
+
+        unlockBuffer(len);
+
+        return *this;
+    } else {
+        setPathName(name);
+        return *this;
+    }
+}
+
+String8& String8::convertToResPath()
+{
+#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR
+    size_t len = length();
+    if (len > 0) {
+        char * buf = lockBuffer(len);
+        for (char * end = buf + len; buf < end; ++buf) {
+            if (*buf == OS_PATH_SEPARATOR)
+                *buf = RES_PATH_SEPARATOR;
+        }
+        unlockBuffer(len);
+    }
+#endif
+    return *this;
+}
+
+
+}; // namespace android
diff --git a/libs/utils/SystemClock.cpp b/libs/utils/SystemClock.cpp
new file mode 100644
index 0000000..2bdc0ce
--- /dev/null
+++ b/libs/utils/SystemClock.cpp
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * System clock functions.
+ */
+
+#if HAVE_ANDROID_OS
+#include <linux/ioctl.h>
+#include <linux/rtc.h>
+#include <utils/Atomic.h>
+#include <linux/android_alarm.h>
+#endif
+
+#include <sys/time.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#include <utils/SystemClock.h>
+#include <utils/Timers.h>
+
+#define LOG_TAG "SystemClock"
+#include "utils/Log.h"
+
+namespace android {
+
+/*
+ * Set the current time.  This only works when running as root.
+ */
+int setCurrentTimeMillis(int64_t millis)
+{
+#if WIN32
+    // not implemented
+    return -1;
+#else
+    struct timeval tv;
+#if HAVE_ANDROID_OS
+    struct timespec ts;
+    int fd;
+    int res;
+#endif
+    int ret = 0;
+
+    if (millis <= 0 || millis / 1000LL >= INT_MAX) {
+        return -1;
+    }
+
+    tv.tv_sec = (time_t) (millis / 1000LL);
+    tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL);
+
+    LOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
+
+#if HAVE_ANDROID_OS
+    fd = open("/dev/alarm", O_RDWR);
+    if(fd < 0) {
+        LOGW("Unable to open alarm driver: %s\n", strerror(errno));
+        return -1;
+    }
+    ts.tv_sec = tv.tv_sec;
+    ts.tv_nsec = tv.tv_usec * 1000;
+    res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
+    if(res < 0) {
+        LOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno));
+        ret = -1;
+    }
+    close(fd);
+#else
+    if (settimeofday(&tv, NULL) != 0) {
+        LOGW("Unable to set clock to %d.%d: %s\n",
+            (int) tv.tv_sec, (int) tv.tv_usec, strerror(errno));
+        ret = -1;
+    }
+#endif
+
+    return ret;
+#endif // WIN32
+}
+
+/*
+ * native public static long uptimeMillis();
+ */
+int64_t uptimeMillis()
+{
+    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+    return (int64_t) nanoseconds_to_milliseconds(when);
+}
+
+/*
+ * native public static long elapsedRealtime();
+ */
+int64_t elapsedRealtime()
+{
+#if HAVE_ANDROID_OS
+    static int s_fd = -1;
+
+    if (s_fd == -1) {
+        int fd = open("/dev/alarm", O_RDONLY);
+        if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
+            close(fd);
+        }
+    }
+
+    struct timespec ts;
+    int result = ioctl(s_fd,
+            ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
+
+    if (result == 0) {
+        int64_t when = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
+        return (int64_t) nanoseconds_to_milliseconds(when);
+    } else {
+        // XXX: there was an error, probably because the driver didn't
+        // exist ... this should return
+        // a real error, like an exception!
+        int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+        return (int64_t) nanoseconds_to_milliseconds(when);
+    }
+#else
+    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+    return (int64_t) nanoseconds_to_milliseconds(when);
+#endif
+}
+
+}; // namespace android
diff --git a/libs/utils/TextOutput.cpp b/libs/utils/TextOutput.cpp
new file mode 100644
index 0000000..cebee99
--- /dev/null
+++ b/libs/utils/TextOutput.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2005 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 <utils/TextOutput.h>
+
+#include <utils/Debug.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+TextOutput& operator<<(TextOutput& to, bool val)
+{
+    if (val) to.print("true", 4);
+    else to.print("false", 5);
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, int val)
+{
+    char buf[16];
+    sprintf(buf, "%d", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, long val)
+{
+    char buf[16];
+    sprintf(buf, "%ld", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, unsigned int val)
+{
+    char buf[16];
+    sprintf(buf, "%u", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, unsigned long val)
+{
+    char buf[16];
+    sprintf(buf, "%lu", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, long long val)
+{
+    char buf[32];
+    sprintf(buf, "%Ld", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, unsigned long long val)
+{
+    char buf[32];
+    sprintf(buf, "%Lu", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+static TextOutput& print_float(TextOutput& to, double value)
+{
+    char buf[64];
+    sprintf(buf, "%g", value);
+    if( !strchr(buf, '.') && !strchr(buf, 'e') &&
+        !strchr(buf, 'E') ) {
+        strncat(buf, ".0", sizeof(buf)-1);
+    }
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, float val)
+{
+    return print_float(to,val);
+}
+
+TextOutput& operator<<(TextOutput& to, double val)
+{
+    return print_float(to,val);
+}
+
+TextOutput& operator<<(TextOutput& to, const void* val)
+{
+    char buf[16];
+    sprintf(buf, "%p", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+static void textOutputPrinter(void* cookie, const char* txt)
+{
+    ((TextOutput*)cookie)->print(txt, strlen(txt));
+}
+
+TextOutput& operator<<(TextOutput& to, const TypeCode& val)
+{
+    printTypeCode(val.typeCode(), textOutputPrinter, (void*)&to);
+    return to;
+}
+
+HexDump::HexDump(const void *buf, size_t size, size_t bytesPerLine)
+    : mBuffer(buf)
+    , mSize(size)
+    , mBytesPerLine(bytesPerLine)
+    , mSingleLineCutoff(16)
+    , mAlignment(4)
+    , mCArrayStyle(false)
+{
+    if (bytesPerLine >= 16) mAlignment = 4;
+    else if (bytesPerLine >= 8) mAlignment = 2;
+    else mAlignment = 1;
+}
+
+TextOutput& operator<<(TextOutput& to, const HexDump& val)
+{
+    printHexData(0, val.buffer(), val.size(), val.bytesPerLine(),
+        val.singleLineCutoff(), val.alignment(), val.carrayStyle(),
+        textOutputPrinter, (void*)&to);
+    return to;
+}
+
+}; // namespace android
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
new file mode 100644
index 0000000..5f407a9
--- /dev/null
+++ b/libs/utils/Threads.cpp
@@ -0,0 +1,1128 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "libutils.threads"
+
+#include <utils/threads.h>
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <errno.h>
+#include <assert.h>
+#include <unistd.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+# include <sched.h>
+# include <sys/resource.h>
+#elif defined(HAVE_WIN32_THREADS)
+# include <windows.h>
+# include <stdint.h>
+# include <process.h>
+# define HAVE_CREATETHREAD  // Cygwin, vs. HAVE__BEGINTHREADEX for MinGW
+#endif
+
+#if defined(HAVE_FUTEX)
+#include <private/utils/futex_synchro.h>
+#endif
+
+#if defined(HAVE_PRCTL)
+#include <sys/prctl.h>
+#endif
+
+/*
+ * ===========================================================================
+ *      Thread wrappers
+ * ===========================================================================
+ */
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+#if defined(HAVE_PTHREADS)
+#if 0
+#pragma mark -
+#pragma mark PTHREAD
+#endif
+// ----------------------------------------------------------------------------
+
+/*
+ * Create and run a new thead.
+ *
+ * We create it "detached", so it cleans up after itself.
+ */
+
+typedef void* (*android_pthread_entry)(void*);
+
+struct thread_data_t {
+    thread_func_t   entryFunction;
+    void*           userData;
+    int             priority;
+    char *          threadName;
+
+    // we use this trampoline when we need to set the priority with
+    // nice/setpriority.
+    static int trampoline(const thread_data_t* t) {
+        thread_func_t f = t->entryFunction;
+        void* u = t->userData;
+        int prio = t->priority;
+        char * name = t->threadName;
+        delete t;
+        setpriority(PRIO_PROCESS, 0, prio);
+        if (name) {
+#if defined(HAVE_PRCTL)
+            // Mac OS doesn't have this, and we build libutil for the host too
+            int hasAt = 0;
+            int hasDot = 0;
+            char *s = name;
+            while (*s) {
+                if (*s == '.') hasDot = 1;
+                else if (*s == '@') hasAt = 1;
+                s++;
+            }
+            int len = s - name;
+            if (len < 15 || hasAt || !hasDot) {
+                s = name;
+            } else {
+                s = name + len - 15;
+            }
+            prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
+#endif
+            free(name);
+        }
+        return f(u);
+    }
+};
+
+int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
+                               void *userData,
+                               const char* threadName,
+                               int32_t threadPriority,
+                               size_t threadStackSize,
+                               android_thread_id_t *threadId)
+{
+    pthread_attr_t attr; 
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+#ifdef HAVE_ANDROID_OS  /* valgrind is rejecting RT-priority create reqs */
+    if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
+        // We could avoid the trampoline if there was a way to get to the
+        // android_thread_id_t (pid) from pthread_t
+        thread_data_t* t = new thread_data_t;
+        t->priority = threadPriority;
+        t->threadName = threadName ? strdup(threadName) : NULL;
+        t->entryFunction = entryFunction;
+        t->userData = userData;
+        entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
+        userData = t;            
+    }
+#endif
+
+    if (threadStackSize) {
+        pthread_attr_setstacksize(&attr, threadStackSize);
+    }
+    
+    errno = 0;
+    pthread_t thread;
+    int result = pthread_create(&thread, &attr,
+                    (android_pthread_entry)entryFunction, userData);
+    if (result != 0) {
+        LOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
+             "(android threadPriority=%d)",
+            entryFunction, result, errno, threadPriority);
+        return 0;
+    }
+
+    if (threadId != NULL) {
+        *threadId = (android_thread_id_t)thread; // XXX: this is not portable
+    }
+    return 1;
+}
+
+android_thread_id_t androidGetThreadId()
+{
+    return (android_thread_id_t)pthread_self();
+}
+
+// ----------------------------------------------------------------------------
+#elif defined(HAVE_WIN32_THREADS)
+#if 0
+#pragma mark -
+#pragma mark WIN32_THREADS
+#endif
+// ----------------------------------------------------------------------------
+
+/*
+ * Trampoline to make us __stdcall-compliant.
+ *
+ * We're expected to delete "vDetails" when we're done.
+ */
+struct threadDetails {
+    int (*func)(void*);
+    void* arg;
+};
+static __stdcall unsigned int threadIntermediary(void* vDetails)
+{
+    struct threadDetails* pDetails = (struct threadDetails*) vDetails;
+    int result;
+
+    result = (*(pDetails->func))(pDetails->arg);
+
+    delete pDetails;
+
+    LOG(LOG_VERBOSE, "thread", "thread exiting\n");
+    return (unsigned int) result;
+}
+
+/*
+ * Create and run a new thread.
+ */
+static bool doCreateThread(android_thread_func_t fn, void* arg, android_thread_id_t *id)
+{
+    HANDLE hThread;
+    struct threadDetails* pDetails = new threadDetails; // must be on heap
+    unsigned int thrdaddr;
+
+    pDetails->func = fn;
+    pDetails->arg = arg;
+
+#if defined(HAVE__BEGINTHREADEX)
+    hThread = (HANDLE) _beginthreadex(NULL, 0, threadIntermediary, pDetails, 0,
+                    &thrdaddr);
+    if (hThread == 0)
+#elif defined(HAVE_CREATETHREAD)
+    hThread = CreateThread(NULL, 0,
+                    (LPTHREAD_START_ROUTINE) threadIntermediary,
+                    (void*) pDetails, 0, (DWORD*) &thrdaddr);
+    if (hThread == NULL)
+#endif
+    {
+        LOG(LOG_WARN, "thread", "WARNING: thread create failed\n");
+        return false;
+    }
+
+#if defined(HAVE_CREATETHREAD)
+    /* close the management handle */
+    CloseHandle(hThread);
+#endif
+
+    if (id != NULL) {
+      	*id = (android_thread_id_t)thrdaddr;
+    }
+
+    return true;
+}
+
+int androidCreateRawThreadEtc(android_thread_func_t fn,
+                               void *userData,
+                               const char* threadName,
+                               int32_t threadPriority,
+                               size_t threadStackSize,
+                               android_thread_id_t *threadId)
+{
+    return doCreateThread(  fn, userData, threadId);
+}
+
+android_thread_id_t androidGetThreadId()
+{
+    return (android_thread_id_t)GetCurrentThreadId();
+}
+
+// ----------------------------------------------------------------------------
+#else
+#error "Threads not supported"
+#endif
+
+// ----------------------------------------------------------------------------
+
+#if 0
+#pragma mark -
+#pragma mark Common Thread functions
+#endif
+
+int androidCreateThread(android_thread_func_t fn, void* arg)
+{
+    return createThreadEtc(fn, arg);
+}
+
+int androidCreateThreadGetID(android_thread_func_t fn, void *arg, android_thread_id_t *id)
+{
+    return createThreadEtc(fn, arg, "android:unnamed_thread",
+                           PRIORITY_DEFAULT, 0, id);
+}
+
+static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc;
+
+int androidCreateThreadEtc(android_thread_func_t entryFunction,
+                            void *userData,
+                            const char* threadName,
+                            int32_t threadPriority,
+                            size_t threadStackSize,
+                            android_thread_id_t *threadId)
+{
+    return gCreateThreadFn(entryFunction, userData, threadName,
+        threadPriority, threadStackSize, threadId);
+}
+
+void androidSetCreateThreadFunc(android_create_thread_fn func)
+{
+    gCreateThreadFn = func;
+}
+
+namespace android {
+
+/*
+ * ===========================================================================
+ *      Mutex class
+ * ===========================================================================
+ */
+
+#if 0
+#pragma mark -
+#pragma mark Mutex
+#endif
+
+#if defined(HAVE_PTHREADS) && !defined(HAVE_FUTEX)
+/*
+ * Simple pthread wrapper.
+ */
+
+Mutex::Mutex()
+{
+    _init();
+}
+
+Mutex::Mutex(const char* name)
+{
+    // XXX: name not used for now
+    _init();
+}
+
+void Mutex::_init()
+{
+    pthread_mutex_t* pMutex = new pthread_mutex_t;
+    pthread_mutex_init(pMutex, NULL);
+    mState = pMutex;
+}
+
+Mutex::~Mutex()
+{
+    delete (pthread_mutex_t*) mState;
+}
+
+status_t Mutex::lock()
+{
+    int res;
+    while ((res=pthread_mutex_lock((pthread_mutex_t*) mState)) == EINTR) ;
+    return -res;
+}
+
+void Mutex::unlock()
+{
+    pthread_mutex_unlock((pthread_mutex_t*) mState);
+}
+
+status_t Mutex::tryLock()
+{
+    int res;
+    while ((res=pthread_mutex_trylock((pthread_mutex_t*) mState)) == EINTR) ;
+    return -res;
+}
+
+#elif defined(HAVE_FUTEX)
+#if 0
+#pragma mark -
+#endif
+
+#define STATE ((futex_mutex_t*) (&mState))
+
+Mutex::Mutex()
+{
+    _init();
+}
+
+Mutex::Mutex(const char* name)
+{
+    _init();
+}
+
+void
+Mutex::_init()
+{
+    futex_mutex_init(STATE);
+}
+
+Mutex::~Mutex()
+{
+}
+
+status_t Mutex::lock()
+{
+    int res;
+    while ((res=futex_mutex_lock(STATE, FUTEX_WAIT_INFINITE)) == EINTR) ;
+    return -res;
+}
+
+void Mutex::unlock()
+{
+    futex_mutex_unlock(STATE);
+}
+
+status_t Mutex::tryLock()
+{
+    int res;
+    while ((res=futex_mutex_trylock(STATE)) == EINTR) ;
+    return -res;
+}
+#undef STATE
+
+#elif defined(HAVE_WIN32_THREADS)
+#if 0
+#pragma mark -
+#endif
+
+Mutex::Mutex()
+{
+    HANDLE hMutex;
+
+    assert(sizeof(hMutex) == sizeof(mState));
+
+    hMutex = CreateMutex(NULL, FALSE, NULL);
+    mState = (void*) hMutex;
+}
+
+Mutex::Mutex(const char* name)
+{
+    // XXX: name not used for now
+    HANDLE hMutex;
+
+    hMutex = CreateMutex(NULL, FALSE, NULL);
+    mState = (void*) hMutex;
+}
+
+Mutex::~Mutex()
+{
+    CloseHandle((HANDLE) mState);
+}
+
+status_t Mutex::lock()
+{
+    DWORD dwWaitResult;
+    dwWaitResult = WaitForSingleObject((HANDLE) mState, INFINITE);
+    return dwWaitResult != WAIT_OBJECT_0 ? -1 : NO_ERROR;
+}
+
+void Mutex::unlock()
+{
+    if (!ReleaseMutex((HANDLE) mState))
+        LOG(LOG_WARN, "thread", "WARNING: bad result from unlocking mutex\n");
+}
+
+status_t Mutex::tryLock()
+{
+    DWORD dwWaitResult;
+
+    dwWaitResult = WaitForSingleObject((HANDLE) mState, 0);
+    if (dwWaitResult != WAIT_OBJECT_0 && dwWaitResult != WAIT_TIMEOUT)
+        LOG(LOG_WARN, "thread", "WARNING: bad result from try-locking mutex\n");
+    return (dwWaitResult == WAIT_OBJECT_0) ? 0 : -1;
+}
+
+#else
+#error "Somebody forgot to implement threads for this platform."
+#endif
+
+
+/*
+ * ===========================================================================
+ *      Condition class
+ * ===========================================================================
+ */
+
+#if 0
+#pragma mark -
+#pragma mark Condition
+#endif
+
+#if defined(HAVE_PTHREADS) && !defined(HAVE_FUTEX)
+
+/*
+ * Constructor.  This is a simple pthread wrapper.
+ */
+Condition::Condition()
+{
+    pthread_cond_t* pCond = new pthread_cond_t;
+
+    pthread_cond_init(pCond, NULL);
+    mState = pCond;
+}
+
+/*
+ * Destructor.
+ */
+Condition::~Condition()
+{
+    pthread_cond_destroy((pthread_cond_t*) mState);
+    delete (pthread_cond_t*) mState;
+}
+
+/*
+ * Wait on a condition variable.  Lock the mutex before calling.
+ */
+
+status_t Condition::wait(Mutex& mutex)
+{
+    assert(mutex.mState != NULL);
+
+    int cc;
+    while ((cc = pthread_cond_wait((pthread_cond_t*)mState,
+                (pthread_mutex_t*) mutex.mState)) == EINTR) ;
+    return -cc;
+}
+
+status_t Condition::wait(Mutex& mutex, nsecs_t abstime)
+{
+    assert(mutex.mState != NULL);
+
+    struct timespec ts;
+    ts.tv_sec = abstime/1000000000;
+    ts.tv_nsec = abstime-(ts.tv_sec*1000000000);
+    
+    int cc;
+    while ((cc = pthread_cond_timedwait((pthread_cond_t*)mState,
+            (pthread_mutex_t*) mutex.mState, &ts)) == EINTR) ;
+    return -cc;
+}
+
+status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
+{
+    return wait(mutex, systemTime()+reltime);
+}
+
+/*
+ * Signal the condition variable, allowing one thread to continue.
+ */
+void Condition::signal()
+{
+    pthread_cond_signal((pthread_cond_t*) mState);
+}
+
+/*
+ * Signal the condition variable, allowing all threads to continue.
+ */
+void Condition::broadcast()
+{
+    pthread_cond_broadcast((pthread_cond_t*) mState);
+}
+
+#elif defined(HAVE_FUTEX)
+#if 0
+#pragma mark -
+#endif
+
+#define STATE ((futex_cond_t*) (&mState))
+
+/*
+ * Constructor.  This is a simple pthread wrapper.
+ */
+Condition::Condition()
+{
+    futex_cond_init(STATE);
+}
+
+/*
+ * Destructor.
+ */
+Condition::~Condition()
+{
+}
+
+/*
+ * Wait on a condition variable.  Lock the mutex before calling.
+ */
+
+status_t Condition::wait(Mutex& mutex)
+{
+    assert(mutex.mState != NULL);
+
+    int res;
+    while ((res = futex_cond_wait(STATE,
+        (futex_mutex_t*)(&mutex.mState), FUTEX_WAIT_INFINITE)) == -EINTR) ;
+
+    return -res;
+}
+
+status_t Condition::wait(Mutex& mutex, nsecs_t abstime)
+{
+    nsecs_t reltime = abstime - systemTime();
+    if (reltime <= 0) return true;
+    return waitRelative(mutex, reltime);
+}
+
+status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
+{
+    assert(mutex.mState != NULL);
+    int res;
+    unsigned msec = ns2ms(reltime);
+    if(msec == 0)
+        return true;
+    // This code will not time out at the correct time if interrupted by signals
+    while ((res = futex_cond_wait(STATE,
+        (futex_mutex_t*)(&mutex.mState), msec)) == -EINTR) ;
+    return res;
+}
+
+/*
+ * Signal the condition variable, allowing one thread to continue.
+ */
+void Condition::signal()
+{
+    futex_cond_signal(STATE);
+}
+
+/*
+ * Signal the condition variable, allowing all threads to continue.
+ */
+void Condition::broadcast()
+{
+    futex_cond_broadcast(STATE);
+}
+
+#undef STATE
+
+#elif defined(HAVE_WIN32_THREADS)
+#if 0
+#pragma mark -
+#endif
+
+/*
+ * Windows doesn't have a condition variable solution.  It's possible
+ * to create one, but it's easy to get it wrong.  For a discussion, and
+ * the origin of this implementation, see:
+ *
+ *  http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+ *
+ * The implementation shown on the page does NOT follow POSIX semantics.
+ * As an optimization they require acquiring the external mutex before
+ * calling signal() and broadcast(), whereas POSIX only requires grabbing
+ * it before calling wait().  The implementation here has been un-optimized
+ * to have the correct behavior.
+ */
+typedef struct WinCondition {
+    // Number of waiting threads.
+    int                 waitersCount;
+
+    // Serialize access to waitersCount.
+    CRITICAL_SECTION    waitersCountLock;
+
+    // Semaphore used to queue up threads waiting for the condition to
+    // become signaled.
+    HANDLE              sema;
+
+    // An auto-reset event used by the broadcast/signal thread to wait
+    // for all the waiting thread(s) to wake up and be released from
+    // the semaphore.
+    HANDLE              waitersDone;
+
+    // This mutex wouldn't be necessary if we required that the caller
+    // lock the external mutex before calling signal() and broadcast().
+    // I'm trying to mimic pthread semantics though.
+    HANDLE              internalMutex;
+
+    // Keeps track of whether we were broadcasting or signaling.  This
+    // allows us to optimize the code if we're just signaling.
+    bool                wasBroadcast;
+
+    status_t wait(WinCondition* condState, HANDLE hMutex, nsecs_t* abstime)
+    {
+        // Increment the wait count, avoiding race conditions.
+        EnterCriticalSection(&condState->waitersCountLock);
+        condState->waitersCount++;
+        //printf("+++ wait: incr waitersCount to %d (tid=%ld)\n",
+        //    condState->waitersCount, getThreadId());
+        LeaveCriticalSection(&condState->waitersCountLock);
+    
+        DWORD timeout = INFINITE;
+        if (abstime) {
+            nsecs_t reltime = *abstime - systemTime();
+            if (reltime < 0)
+                reltime = 0;
+            timeout = reltime/1000000;
+        }
+        
+        // Atomically release the external mutex and wait on the semaphore.
+        DWORD res =
+            SignalObjectAndWait(hMutex, condState->sema, timeout, FALSE);
+    
+        //printf("+++ wait: awake (tid=%ld)\n", getThreadId());
+    
+        // Reacquire lock to avoid race conditions.
+        EnterCriticalSection(&condState->waitersCountLock);
+    
+        // No longer waiting.
+        condState->waitersCount--;
+    
+        // Check to see if we're the last waiter after a broadcast.
+        bool lastWaiter = (condState->wasBroadcast && condState->waitersCount == 0);
+    
+        //printf("+++ wait: lastWaiter=%d (wasBc=%d wc=%d)\n",
+        //    lastWaiter, condState->wasBroadcast, condState->waitersCount);
+    
+        LeaveCriticalSection(&condState->waitersCountLock);
+    
+        // If we're the last waiter thread during this particular broadcast
+        // then signal broadcast() that we're all awake.  It'll drop the
+        // internal mutex.
+        if (lastWaiter) {
+            // Atomically signal the "waitersDone" event and wait until we
+            // can acquire the internal mutex.  We want to do this in one step
+            // because it ensures that everybody is in the mutex FIFO before
+            // any thread has a chance to run.  Without it, another thread
+            // could wake up, do work, and hop back in ahead of us.
+            SignalObjectAndWait(condState->waitersDone, condState->internalMutex,
+                INFINITE, FALSE);
+        } else {
+            // Grab the internal mutex.
+            WaitForSingleObject(condState->internalMutex, INFINITE);
+        }
+    
+        // Release the internal and grab the external.
+        ReleaseMutex(condState->internalMutex);
+        WaitForSingleObject(hMutex, INFINITE);
+    
+        return res == WAIT_OBJECT_0 ? NO_ERROR : -1;
+    }
+} WinCondition;
+
+/*
+ * Constructor.  Set up the WinCondition stuff.
+ */
+Condition::Condition()
+{
+    WinCondition* condState = new WinCondition;
+
+    condState->waitersCount = 0;
+    condState->wasBroadcast = false;
+    // semaphore: no security, initial value of 0
+    condState->sema = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
+    InitializeCriticalSection(&condState->waitersCountLock);
+    // auto-reset event, not signaled initially
+    condState->waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);
+    // used so we don't have to lock external mutex on signal/broadcast
+    condState->internalMutex = CreateMutex(NULL, FALSE, NULL);
+
+    mState = condState;
+}
+
+/*
+ * Destructor.  Free Windows resources as well as our allocated storage.
+ */
+Condition::~Condition()
+{
+    WinCondition* condState = (WinCondition*) mState;
+    if (condState != NULL) {
+        CloseHandle(condState->sema);
+        CloseHandle(condState->waitersDone);
+        delete condState;
+    }
+}
+
+
+status_t Condition::wait(Mutex& mutex)
+{
+    WinCondition* condState = (WinCondition*) mState;
+    HANDLE hMutex = (HANDLE) mutex.mState;
+    
+    return ((WinCondition*)mState)->wait(condState, hMutex, NULL);
+}
+
+status_t Condition::wait(Mutex& mutex, nsecs_t abstime)
+{
+    WinCondition* condState = (WinCondition*) mState;
+    HANDLE hMutex = (HANDLE) mutex.mState;
+
+    return ((WinCondition*)mState)->wait(condState, hMutex, &abstime);
+}
+
+status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
+{
+    return wait(mutex, systemTime()+reltime);
+}
+
+/*
+ * Signal the condition variable, allowing one thread to continue.
+ */
+void Condition::signal()
+{
+    WinCondition* condState = (WinCondition*) mState;
+
+    // Lock the internal mutex.  This ensures that we don't clash with
+    // broadcast().
+    WaitForSingleObject(condState->internalMutex, INFINITE);
+
+    EnterCriticalSection(&condState->waitersCountLock);
+    bool haveWaiters = (condState->waitersCount > 0);
+    LeaveCriticalSection(&condState->waitersCountLock);
+
+    // If no waiters, then this is a no-op.  Otherwise, knock the semaphore
+    // down a notch.
+    if (haveWaiters)
+        ReleaseSemaphore(condState->sema, 1, 0);
+
+    // Release internal mutex.
+    ReleaseMutex(condState->internalMutex);
+}
+
+/*
+ * Signal the condition variable, allowing all threads to continue.
+ *
+ * First we have to wake up all threads waiting on the semaphore, then
+ * we wait until all of the threads have actually been woken before
+ * releasing the internal mutex.  This ensures that all threads are woken.
+ */
+void Condition::broadcast()
+{
+    WinCondition* condState = (WinCondition*) mState;
+
+    // Lock the internal mutex.  This keeps the guys we're waking up
+    // from getting too far.
+    WaitForSingleObject(condState->internalMutex, INFINITE);
+
+    EnterCriticalSection(&condState->waitersCountLock);
+    bool haveWaiters = false;
+
+    if (condState->waitersCount > 0) {
+        haveWaiters = true;
+        condState->wasBroadcast = true;
+    }
+
+    if (haveWaiters) {
+        // Wake up all the waiters.
+        ReleaseSemaphore(condState->sema, condState->waitersCount, 0);
+
+        LeaveCriticalSection(&condState->waitersCountLock);
+
+        // Wait for all awakened threads to acquire the counting semaphore.
+        // The last guy who was waiting sets this.
+        WaitForSingleObject(condState->waitersDone, INFINITE);
+
+        // Reset wasBroadcast.  (No crit section needed because nobody
+        // else can wake up to poke at it.)
+        condState->wasBroadcast = 0;
+    } else {
+        // nothing to do
+        LeaveCriticalSection(&condState->waitersCountLock);
+    }
+
+    // Release internal mutex.
+    ReleaseMutex(condState->internalMutex);
+}
+
+#else
+#error "condition variables not supported on this platform"
+#endif
+
+
+/*
+ * ===========================================================================
+ *      ReadWriteLock class
+ * ===========================================================================
+ */
+
+#if 0
+#pragma mark -
+#pragma mark ReadWriteLock
+#endif
+
+/*
+ * Add a reader.  Readers are nice.  They share.
+ */
+void ReadWriteLock::lockForRead()
+{
+    mLock.lock();
+    while (mNumWriters > 0) {
+        LOG(LOG_DEBUG, "thread", "+++ lockForRead: waiting\n");
+        mReadWaiter.wait(mLock);
+    }
+    assert(mNumWriters == 0);
+    mNumReaders++;
+#if defined(PRINT_RENDER_TIMES)
+    if (mNumReaders == 1)
+        mDebugTimer.start();
+#endif
+    mLock.unlock();
+}
+
+/*
+ * Try to add a reader.  If it doesn't work right away, return "false".
+ */
+bool ReadWriteLock::tryLockForRead()
+{
+    mLock.lock();
+    if (mNumWriters > 0) {
+        mLock.unlock();
+        return false;
+    }
+    assert(mNumWriters == 0);
+    mNumReaders++;
+#if defined(PRINT_RENDER_TIMES)
+    if (mNumReaders == 1)
+        mDebugTimer.start();
+#endif
+    mLock.unlock();
+    return true;
+}
+
+/*
+ * Remove a reader.
+ */
+void ReadWriteLock::unlockForRead()
+{
+    mLock.lock();
+    if (mNumReaders == 0) {
+        mLock.unlock();
+        LOG(LOG_WARN, "thread",
+            "WARNING: unlockForRead requested, but not locked\n");
+        return;
+    }
+    assert(mNumReaders > 0);
+    assert(mNumWriters == 0);
+    mNumReaders--;
+    if (mNumReaders == 0) {           // last reader?
+#if defined(PRINT_RENDER_TIMES)
+        mDebugTimer.stop();
+        printf(" rdlk held %.3f msec\n",
+            (double) mDebugTimer.durationUsecs() / 1000.0);
+#endif
+        //printf("+++ signaling writers (if any)\n");
+        mWriteWaiter.signal();      // wake one writer (if any)
+    }
+    mLock.unlock();
+}
+
+/*
+ * Add a writer.  This requires exclusive access to the object.
+ */
+void ReadWriteLock::lockForWrite()
+{
+    mLock.lock();
+    while (mNumReaders > 0 || mNumWriters > 0) {
+        LOG(LOG_DEBUG, "thread", "+++ lockForWrite: waiting\n");
+        mWriteWaiter.wait(mLock);
+    }
+    assert(mNumReaders == 0);
+    assert(mNumWriters == 0);
+    mNumWriters++;
+#if defined(PRINT_RENDER_TIMES)
+    mDebugTimer.start();
+#endif
+    mLock.unlock();
+}
+
+/*
+ * Try to add a writer.  If it doesn't work right away, return "false".
+ */
+bool ReadWriteLock::tryLockForWrite()
+{
+    mLock.lock();
+    if (mNumReaders > 0 || mNumWriters > 0) {
+        mLock.unlock();
+        return false;
+    }
+    assert(mNumReaders == 0);
+    assert(mNumWriters == 0);
+    mNumWriters++;
+#if defined(PRINT_RENDER_TIMES)
+    mDebugTimer.start();
+#endif
+    mLock.unlock();
+    return true;
+}
+
+/*
+ * Remove a writer.
+ */
+void ReadWriteLock::unlockForWrite()
+{
+    mLock.lock();
+    if (mNumWriters == 0) {
+        mLock.unlock();
+        LOG(LOG_WARN, "thread",
+            "WARNING: unlockForWrite requested, but not locked\n");
+        return;
+    }
+    assert(mNumWriters == 1);
+    mNumWriters--;
+#if defined(PRINT_RENDER_TIMES)
+    mDebugTimer.stop();
+    //printf(" wrlk held %.3f msec\n",
+    //    (double) mDebugTimer.durationUsecs() / 1000.0);
+#endif
+    mWriteWaiter.signal();         // should other writers get first dibs?
+    //printf("+++ signaling readers (if any)\n");
+    mReadWaiter.broadcast();        // wake all readers (if any)
+    mLock.unlock();
+}
+
+// ----------------------------------------------------------------------------
+
+#if 0
+#pragma mark -
+#pragma mark Thread::Thread
+#endif
+
+/*
+ * This is our thread object!
+ */
+
+Thread::Thread(bool canCallJava)
+    :   mCanCallJava(canCallJava),
+        mThread(thread_id_t(-1)),
+        mLock("Thread::mLock"),
+        mStatus(NO_ERROR),
+        mExitPending(false), mRunning(false)
+{
+}
+
+Thread::~Thread()
+{
+}
+
+status_t Thread::readyToRun()
+{
+    return NO_ERROR;
+}
+
+status_t Thread::run(const char* name, int32_t priority, size_t stack)
+{
+    Mutex::Autolock _l(mLock);
+
+    if (mRunning) {
+        // thread already started
+        return INVALID_OPERATION;
+    }
+
+    // reset status and exitPending to their default value, so we can
+    // try again after an error happened (either below, or in readyToRun())
+    mStatus = NO_ERROR;
+    mExitPending = false;
+    mThread = thread_id_t(-1);
+    
+    // hold a strong reference on ourself
+    mHoldSelf = this;
+
+    bool res;
+    if (mCanCallJava) {
+        res = createThreadEtc(_threadLoop,
+                this, name, priority, stack, &mThread);
+    } else {
+        res = androidCreateRawThreadEtc(_threadLoop,
+                this, name, priority, stack, &mThread);
+    }
+    
+    if (res == false) {
+        mStatus = UNKNOWN_ERROR;   // something happened!
+        mRunning = false;
+        mThread = thread_id_t(-1);
+    }
+    
+    if (mStatus < 0) {
+        // something happened, don't leak
+        mHoldSelf.clear();
+    }
+    
+    return mStatus;
+}
+
+int Thread::_threadLoop(void* user)
+{
+    Thread* const self = static_cast<Thread*>(user);
+    sp<Thread> strong(self->mHoldSelf);
+    wp<Thread> weak(strong);
+    self->mHoldSelf.clear();
+
+    // we're about to run...
+    self->mStatus = self->readyToRun();
+    if (self->mStatus!=NO_ERROR || self->mExitPending) {
+        // pretend the thread never started...
+        self->mExitPending = false;
+        self->mRunning = false;
+        return 0;
+    }
+    
+    // thread is running now
+    self->mRunning = true;
+
+    do {
+        bool result = self->threadLoop();
+        if (result == false || self->mExitPending) {
+            self->mExitPending = true;
+            self->mLock.lock();
+            self->mRunning = false;
+            self->mThreadExitedCondition.signal();
+            self->mLock.unlock();
+            break;
+        }
+        
+        // Release our strong reference, to let a chance to the thread
+        // to die a peaceful death.
+        strong.clear();
+        // And immediately, reacquire a strong reference for the next loop
+        strong = weak.promote();
+    } while(strong != 0);
+    
+    return 0;
+}
+
+void Thread::requestExit()
+{
+    mExitPending = true;
+}
+
+status_t Thread::requestExitAndWait()
+{
+    if (mStatus == OK) {
+
+        if (mThread == getThreadId()) {
+            LOGW(
+            "Thread (this=%p): don't call waitForExit() from this "
+            "Thread object's thread. It's a guaranteed deadlock!",
+            this);
+            return WOULD_BLOCK;
+        }
+        
+        requestExit();
+
+        Mutex::Autolock _l(mLock);
+        while (mRunning == true) {
+            mThreadExitedCondition.wait(mLock);
+        }
+        mExitPending = false;
+    }
+    return mStatus;
+}
+
+bool Thread::exitPending() const
+{
+    return mExitPending;
+}
+
+
+
+};  // namespace android
diff --git a/libs/utils/TimerProbe.cpp b/libs/utils/TimerProbe.cpp
new file mode 100644
index 0000000..835480d
--- /dev/null
+++ b/libs/utils/TimerProbe.cpp
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+#include <utils/TimerProbe.h>
+ 
+#if ENABLE_TIMER_PROBE
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "time"
+
+namespace android {
+
+Vector<TimerProbe::Bucket> TimerProbe::gBuckets;
+TimerProbe* TimerProbe::gExecuteChain;
+int TimerProbe::gIndent;
+timespec TimerProbe::gRealBase;
+
+TimerProbe::TimerProbe(const char tag[], int* slot) : mTag(tag)
+{
+    mNext = gExecuteChain;
+    gExecuteChain = this;
+    mIndent = gIndent;
+    gIndent += 1;
+    if (mIndent > 0) {
+        if (*slot == 0) {
+            int count = gBuckets.add();
+            *slot = count;
+            Bucket& bucket = gBuckets.editItemAt(count);
+            memset(&bucket, 0, sizeof(Bucket));
+            bucket.mTag = tag;
+            bucket.mSlotPtr = slot;
+            bucket.mIndent = mIndent;
+        }
+        mBucket = *slot;
+    }
+    clock_gettime(CLOCK_REALTIME, &mRealStart);
+    if (gRealBase.tv_sec == 0)
+        gRealBase = mRealStart;
+    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &mPStart);
+    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &mTStart);
+}
+
+void TimerProbe::end()
+{
+    timespec realEnd, pEnd, tEnd;
+    clock_gettime(CLOCK_REALTIME, &realEnd);
+    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &pEnd);
+    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tEnd);
+    print(realEnd, pEnd, tEnd);
+    mTag = NULL;
+}
+
+TimerProbe::~TimerProbe()
+{
+    if (mTag != NULL)
+        end();
+    gExecuteChain = mNext;
+    gIndent--;
+}
+
+
+uint32_t TimerProbe::ElapsedTime(const timespec& start, const timespec& end)
+{
+    int sec = end.tv_sec - start.tv_sec;
+    int nsec = end.tv_nsec - start.tv_nsec;
+    if (nsec < 0) {
+        sec--;
+        nsec += 1000000000;
+    }
+    return sec * 1000000 + nsec / 1000;
+}
+
+void TimerProbe::print(const timespec& r, const timespec& p,
+        const timespec& t) const
+{
+    uint32_t es = ElapsedTime(gRealBase, mRealStart);
+    uint32_t er = ElapsedTime(mRealStart, r);
+    uint32_t ep = ElapsedTime(mPStart, p);
+    uint32_t et = ElapsedTime(mTStart, t);
+    if (mIndent > 0) {
+        Bucket& bucket = gBuckets.editItemAt(mBucket);
+        if (bucket.mStart == 0)
+            bucket.mStart = es;
+        bucket.mReal += er;
+        bucket.mProcess += ep;
+        bucket.mThread += et;
+        bucket.mCount++;
+        return;
+    }
+    int index = 0;
+    int buckets = gBuckets.size();
+    int count = 1;
+    const char* tag = mTag;
+    int indent = mIndent;
+    do {
+        LOGD("%-30.30s: (%3d) %-5.*s time=%-10.3f real=%7dus process=%7dus (%3d%%) thread=%7dus (%3d%%)\n", 
+            tag, count, indent > 5 ? 5 : indent, "+++++", es / 1000000.0,
+            er, ep, ep * 100 / er, et, et * 100 / er);
+        if (index >= buckets)
+            break;
+        Bucket& bucket = gBuckets.editItemAt(index);
+        count = bucket.mCount;
+        es = bucket.mStart;
+        er = bucket.mReal;
+        ep = bucket.mProcess;
+        et = bucket.mThread;
+        tag = bucket.mTag;
+        indent = bucket.mIndent;
+        *bucket.mSlotPtr = 0;
+    } while (++index); // always true
+    gBuckets.clear();
+}
+
+}; // namespace android
+
+#endif
diff --git a/libs/utils/Timers.cpp b/libs/utils/Timers.cpp
new file mode 100644
index 0000000..2abc811
--- /dev/null
+++ b/libs/utils/Timers.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+//
+// Timer functions.
+//
+#include <utils/Timers.h>
+#include <utils/ported.h>     // may need usleep
+#include <utils/Log.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+
+#ifdef HAVE_WIN32_THREADS
+#include <windows.h>
+#endif
+
+nsecs_t systemTime(int clock)
+{
+#if defined(HAVE_POSIX_CLOCKS)
+    static const clockid_t clocks[] = {
+            CLOCK_REALTIME,
+            CLOCK_MONOTONIC,
+            CLOCK_PROCESS_CPUTIME_ID,
+            CLOCK_THREAD_CPUTIME_ID
+    };
+    struct timespec t;
+    t.tv_sec = t.tv_nsec = 0;
+    clock_gettime(clocks[clock], &t);
+    return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
+#else
+    // we don't support the clocks here.
+    struct timeval t;
+    t.tv_sec = t.tv_usec = 0;
+    gettimeofday(&t, NULL);
+    return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL;
+#endif
+}
+
+//#define MONITOR_USLEEP
+
+/*
+ * Sleep long enough that we'll wake up "interval" milliseconds after
+ * the previous snooze.
+ *
+ * The "nextTick" argument is updated on each call, and should be passed
+ * in every time.  Set its fields to zero on the first call.
+ *
+ * Returns the #of intervals we have overslept, which will be zero if we're
+ * on time.  [Currently just returns 0 or 1.]
+ */
+int sleepForInterval(long interval, struct timeval* pNextTick)
+{
+    struct timeval now;
+    long long timeBeforeNext;
+    long sleepTime = 0;
+    bool overSlept = false;
+    //int usleepBias = 0;
+
+#ifdef USLEEP_BIAS
+    /*
+     * Linux likes to add 9000ms or so.
+     * [not using this for now]
+     */
+    //usleepBias = USLEEP_BIAS;
+#endif
+
+    gettimeofday(&now, NULL);
+
+    if (pNextTick->tv_sec == 0) {
+        /* special-case for first time through */
+        *pNextTick = now;
+        sleepTime = interval;
+        android::DurationTimer::addToTimeval(pNextTick, interval);
+    } else {
+        /*
+         * Compute how much time there is before the next tick.  If this
+         * value is negative, we've run over.  If we've run over a little
+         * bit we can shorten the next frame to keep the pace steady, but
+         * if we've dramatically overshot we need to re-sync.
+         */
+        timeBeforeNext = android::DurationTimer::subtractTimevals(pNextTick, &now);
+        //printf("TOP: now=%ld.%ld next=%ld.%ld diff=%ld\n",
+        //    now.tv_sec, now.tv_usec, pNextTick->tv_sec, pNextTick->tv_usec,
+        //    (long) timeBeforeNext);
+        if (timeBeforeNext < -interval) {
+            /* way over */
+            overSlept = true;
+            sleepTime = 0;
+            *pNextTick = now;
+        } else if (timeBeforeNext <= 0) {
+            /* slightly over, keep the pace steady */
+            overSlept = true;
+            sleepTime = 0;
+        } else if (timeBeforeNext <= interval) {
+            /* right on schedule */
+            sleepTime = timeBeforeNext;
+        } else if (timeBeforeNext > interval && timeBeforeNext <= 2*interval) {
+            /* sleep call returned early; do a longer sleep this time */
+            sleepTime = timeBeforeNext;
+        } else if (timeBeforeNext > interval) {
+            /* we went back in time -- somebody updated system clock? */
+            /* (could also be a *seriously* broken usleep()) */
+            LOG(LOG_DEBUG, "",
+                " Impossible: timeBeforeNext = %ld\n", (long)timeBeforeNext);
+            sleepTime = 0;
+            *pNextTick = now;
+        }
+        android::DurationTimer::addToTimeval(pNextTick, interval);
+    }
+    //printf(" Before sleep: now=%ld.%ld next=%ld.%ld sleepTime=%ld\n",
+    //    now.tv_sec, now.tv_usec, pNextTick->tv_sec, pNextTick->tv_usec,
+    //    sleepTime);
+
+    /*
+     * Sleep for the designated period of time.
+     *
+     * Linux tends to sleep for longer than requested, often by 17-18ms.
+     * MinGW tends to sleep for less than requested, by as much as 14ms,
+     * but occasionally oversleeps for 40+ms (looks like some external
+     * factors plus round-off on a 64Hz clock).  Cygwin is pretty steady.
+     *
+     * If you start the MinGW version, and then launch the Cygwin version,
+     * the MinGW clock becomes more erratic.  Not entirely sure why.
+     *
+     * (There's a lot of stuff here; it's really just a usleep() call with
+     * a bunch of instrumentation.)
+     */
+    if (sleepTime > 0) {
+#if defined(MONITOR_USLEEP)
+        struct timeval before, after;
+        long long actual;
+
+        gettimeofday(&before, NULL);
+        usleep((long) sleepTime);
+        gettimeofday(&after, NULL);
+
+        /* check usleep() accuracy; default Linux threads are pretty sloppy */
+        actual = android::DurationTimer::subtractTimevals(&after, &before);
+        if ((long) actual < sleepTime - 14000 /*(sleepTime/10)*/ ||
+            (long) actual > sleepTime + 20000 /*(sleepTime/10)*/)
+        {
+            LOG(LOG_DEBUG, "", " Odd usleep: req=%ld, actual=%ld\n", sleepTime,
+                (long) actual);
+        }
+#else
+#ifdef HAVE_WIN32_THREADS
+        Sleep( sleepTime/1000 );
+#else        
+        usleep((long) sleepTime);
+#endif        
+#endif
+    }
+
+    //printf("slept %d\n", sleepTime);
+
+    if (overSlept)
+        return 1;       // close enough
+    else
+        return 0;
+}
+
+
+/*
+ * ===========================================================================
+ *      DurationTimer
+ * ===========================================================================
+ */
+
+using namespace android;
+
+// Start the timer.
+void DurationTimer::start(void)
+{
+    gettimeofday(&mStartWhen, NULL);
+}
+
+// Stop the timer.
+void DurationTimer::stop(void)
+{
+    gettimeofday(&mStopWhen, NULL);
+}
+
+// Get the duration in microseconds.
+long long DurationTimer::durationUsecs(void) const
+{
+    return (long) subtractTimevals(&mStopWhen, &mStartWhen);
+}
+
+// Subtract two timevals.  Returns the difference (ptv1-ptv2) in
+// microseconds.
+/*static*/ long long DurationTimer::subtractTimevals(const struct timeval* ptv1,
+    const struct timeval* ptv2)
+{
+    long long stop  = ((long long) ptv1->tv_sec) * 1000000LL +
+                      ((long long) ptv1->tv_usec);
+    long long start = ((long long) ptv2->tv_sec) * 1000000LL +
+                      ((long long) ptv2->tv_usec);
+    return stop - start;
+}
+
+// Add the specified amount of time to the timeval.
+/*static*/ void DurationTimer::addToTimeval(struct timeval* ptv, long usec)
+{
+    if (usec < 0) {
+        LOG(LOG_WARN, "", "Negative values not supported in addToTimeval\n");
+        return;
+    }
+
+    // normalize tv_usec if necessary
+    if (ptv->tv_usec >= 1000000) {
+        ptv->tv_sec += ptv->tv_usec / 1000000;
+        ptv->tv_usec %= 1000000;
+    }
+
+    ptv->tv_usec += usec % 1000000;
+    if (ptv->tv_usec >= 1000000) {
+        ptv->tv_usec -= 1000000;
+        ptv->tv_sec++;
+    }
+    ptv->tv_sec += usec / 1000000;
+}
+
diff --git a/libs/utils/Unicode.cpp b/libs/utils/Unicode.cpp
new file mode 100644
index 0000000..33f535f
--- /dev/null
+++ b/libs/utils/Unicode.cpp
@@ -0,0 +1,193 @@
+/*
+ * 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.
+ */
+
+#include "utils/AndroidUnicode.h"
+#include "characterData.h"
+
+#define LOG_TAG "Unicode"
+#include "utils/Log.h"
+
+// ICU headers for using macros
+#include <unicode/utf16.h>
+
+#define MIN_RADIX 2
+#define MAX_RADIX 36
+
+#define TYPE_SHIFT 0
+#define TYPE_MASK ((1<<5)-1)
+
+#define DIRECTION_SHIFT (TYPE_SHIFT+5)
+#define DIRECTION_MASK ((1<<5)-1)
+
+#define MIRRORED_SHIFT (DIRECTION_SHIFT+5)
+#define MIRRORED_MASK ((1<<1)-1)
+
+#define TOUPPER_SHIFT (MIRRORED_SHIFT+1)
+#define TOUPPER_MASK ((1<<6)-1)
+
+#define TOLOWER_SHIFT (TOUPPER_SHIFT+6)
+#define TOLOWER_MASK ((1<<6)-1)
+
+#define TOTITLE_SHIFT (TOLOWER_SHIFT+6)
+#define TOTITLE_MASK ((1<<2)-1)
+
+#define MIRROR_SHIFT (TOTITLE_SHIFT+2)
+#define MIRROR_MASK ((1<<5)-1)
+
+#define NUMERIC_SHIFT (TOTITLE_SHIFT+2)
+#define NUMERIC_MASK ((1<<7)-1)
+
+#define DECOMPOSITION_SHIFT (11)
+#define DECOMPOSITION_MASK ((1<<5)-1)
+
+/*
+ * Returns the value stored in the CharacterData tables that contains
+ * an index into the packed data table and the decomposition type.
+ */
+static uint16_t findCharacterValue(UChar32 c)
+{
+    LOG_ASSERT(c >= 0 && c <= 0x10FFFF, "findCharacterValue received an invalid codepoint");
+    if (c < 256)
+        return CharacterData::LATIN1_DATA[c];
+
+    // Rotate the bits because the tables are separated into even and odd codepoints
+    c = (c >> 1) | ((c & 1) << 20);
+
+    CharacterData::Range search = CharacterData::FULL_DATA[c >> 16];
+    const uint32_t* array = search.array;
+ 
+    // This trick is so that that compare in the while loop does not
+    // need to shift the array entry down by 16
+    c <<= 16;
+    c |= 0xFFFF;
+
+    int high = (int)search.length - 1;
+    int low = 0;
+
+    if (high < 0)
+        return 0;
+    
+    while (low < high - 1)
+    {
+        int probe = (high + low) >> 1;
+
+        // The entries contain the codepoint in the high 16 bits and the index
+        // into PACKED_DATA in the low 16.
+        if (array[probe] > (unsigned)c)
+            high = probe;
+        else
+            low = probe;
+    }
+
+    LOG_ASSERT((array[low] <= (unsigned)c), "A suitable range was not found");
+    return array[low] & 0xFFFF;
+}
+
+uint32_t android::Unicode::getPackedData(UChar32 c)
+{
+    // findCharacterValue returns a 16-bit value with the top 5 bits containing a decomposition type
+    // and the remaining bits containing an index.
+    return CharacterData::PACKED_DATA[findCharacterValue(c) & 0x7FF];
+}
+
+android::Unicode::CharType android::Unicode::getType(UChar32 c)
+{
+    if (c < 0 || c >= 0x10FFFF)
+        return CHARTYPE_UNASSIGNED;
+    return (CharType)((getPackedData(c) >> TYPE_SHIFT) & TYPE_MASK);
+}
+
+android::Unicode::DecompositionType android::Unicode::getDecompositionType(UChar32 c)
+{
+    // findCharacterValue returns a 16-bit value with the top 5 bits containing a decomposition type
+    // and the remaining bits containing an index.
+    return (DecompositionType)((findCharacterValue(c) >> DECOMPOSITION_SHIFT) & DECOMPOSITION_MASK);
+}
+
+int android::Unicode::getDigitValue(UChar32 c, int radix)
+{
+    if (radix < MIN_RADIX || radix > MAX_RADIX)
+        return -1;
+
+    int tempValue = radix;
+    
+    if (c >= '0' && c <= '9')
+        tempValue = c - '0';
+    else if (c >= 'a' && c <= 'z')
+        tempValue = c - 'a' + 10;
+    else if (c >= 'A' && c <= 'Z')
+        tempValue = c - 'A' + 10;
+    
+    return tempValue < radix ? tempValue : -1;
+}
+
+int android::Unicode::getNumericValue(UChar32 c)
+{
+    if (isMirrored(c))
+        return -1;
+    
+    return (int) CharacterData::NUMERICS[((getPackedData(c) >> NUMERIC_SHIFT) & NUMERIC_MASK)];
+}
+
+UChar32 android::Unicode::toLower(UChar32 c)
+{
+    return c + CharacterData::LCDIFF[(getPackedData(c) >> TOLOWER_SHIFT) & TOLOWER_MASK];
+}
+
+UChar32 android::Unicode::toUpper(UChar32 c)
+{
+    return c + CharacterData::UCDIFF[(getPackedData(c) >> TOUPPER_SHIFT) & TOUPPER_MASK];
+}
+
+android::Unicode::Direction android::Unicode::getDirectionality(UChar32 c)
+{
+    uint32_t data = getPackedData(c);
+
+    if (0 == data)
+        return DIRECTIONALITY_UNDEFINED;
+
+    Direction d = (Direction) ((data >> DIRECTION_SHIFT) & DIRECTION_MASK);
+
+    if (DIRECTION_MASK == d)
+        return DIRECTIONALITY_UNDEFINED;
+    
+    return d;
+}
+
+bool android::Unicode::isMirrored(UChar32 c)
+{
+    return ((getPackedData(c) >> MIRRORED_SHIFT) & MIRRORED_MASK) != 0;
+}
+
+UChar32 android::Unicode::toMirror(UChar32 c)
+{
+    if (!isMirrored(c))
+        return c;
+
+    return c + CharacterData::MIRROR_DIFF[(getPackedData(c) >> MIRROR_SHIFT) & MIRROR_MASK];
+}
+
+UChar32 android::Unicode::toTitle(UChar32 c)
+{
+    int32_t diff = CharacterData::TCDIFF[(getPackedData(c) >> TOTITLE_SHIFT) & TOTITLE_MASK];
+
+    if (TOTITLE_MASK == diff)
+        return toUpper(c);
+    
+    return c + diff;
+}
+
+
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
new file mode 100644
index 0000000..2c2d667
--- /dev/null
+++ b/libs/utils/VectorImpl.cpp
@@ -0,0 +1,611 @@
+/*
+ * Copyright (C) 2005 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 "Vector"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/SharedBuffer.h>
+#include <utils/VectorImpl.h>
+
+/*****************************************************************************/
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+const size_t kMinVectorCapacity = 4;
+
+static inline size_t max(size_t a, size_t b) {
+    return a>b ? a : b;
+}
+
+// ----------------------------------------------------------------------------
+
+VectorImpl::VectorImpl(size_t itemSize, uint32_t flags)
+    : mStorage(0), mCount(0), mFlags(flags), mItemSize(itemSize)
+{
+}
+
+VectorImpl::VectorImpl(const VectorImpl& rhs)
+    :   mStorage(rhs.mStorage), mCount(rhs.mCount),
+        mFlags(rhs.mFlags), mItemSize(rhs.mItemSize)
+{
+    if (mStorage) {
+        SharedBuffer::sharedBuffer(mStorage)->acquire();
+    }
+}
+
+VectorImpl::~VectorImpl()
+{
+    LOG_ASSERT(!mCount,
+        "[%p] "
+        "subclasses of VectorImpl must call finish_vector()"
+        " in their destructor. Leaking %d bytes.",
+        this, (int)(mCount*mItemSize));
+    // We can't call _do_destroy() here because the vtable is already gone. 
+}
+
+VectorImpl& VectorImpl::operator = (const VectorImpl& rhs)
+{
+    LOG_ASSERT(mItemSize == rhs.mItemSize,
+        "Vector<> have different types (this=%p, rhs=%p)", this, &rhs);
+    if (this != &rhs) {
+        release_storage();
+        if (rhs.mCount) {
+            mStorage = rhs.mStorage;
+            mCount = rhs.mCount;
+            SharedBuffer::sharedBuffer(mStorage)->acquire();
+        } else {
+            mStorage = 0;
+            mCount = 0;
+        }
+    }
+    return *this;
+}
+
+void* VectorImpl::editArrayImpl()
+{
+    if (mStorage) {
+        SharedBuffer* sb = SharedBuffer::sharedBuffer(mStorage)->attemptEdit();
+        if (sb == 0) {
+            sb = SharedBuffer::alloc(capacity() * mItemSize);
+            if (sb) {
+                _do_copy(sb->data(), mStorage, mCount);
+                release_storage();
+                mStorage = sb->data();
+            }
+        }
+    }
+    return mStorage;
+}
+
+size_t VectorImpl::capacity() const
+{
+    if (mStorage) {
+        return SharedBuffer::sharedBuffer(mStorage)->size() / mItemSize;
+    }
+    return 0;
+}
+
+ssize_t VectorImpl::insertVectorAt(const VectorImpl& vector, size_t index)
+{
+    if (index > size())
+        return BAD_INDEX;
+    void* where = _grow(index, vector.size());
+    if (where) {
+        _do_copy(where, vector.arrayImpl(), vector.size());
+    }
+    return where ? index : (ssize_t)NO_MEMORY;
+}
+
+ssize_t VectorImpl::appendVector(const VectorImpl& vector)
+{
+    return insertVectorAt(vector, size());
+}
+
+ssize_t VectorImpl::insertAt(size_t index, size_t numItems)
+{
+    return insertAt(0, index, numItems);
+}
+
+ssize_t VectorImpl::insertAt(const void* item, size_t index, size_t numItems)
+{
+    if (index > size())
+        return BAD_INDEX;
+    void* where = _grow(index, numItems);
+    if (where) {
+        if (item) {
+            _do_splat(where, item, numItems);
+        } else {
+            _do_construct(where, numItems);
+        }
+    }
+    return where ? index : (ssize_t)NO_MEMORY;
+}
+
+static int sortProxy(const void* lhs, const void* rhs, void* func)
+{
+    return (*(VectorImpl::compar_t)func)(lhs, rhs);
+}
+
+status_t VectorImpl::sort(VectorImpl::compar_t cmp)
+{
+    return sort(sortProxy, (void*)cmp);
+}
+
+status_t VectorImpl::sort(VectorImpl::compar_r_t cmp, void* state)
+{
+    // the sort must be stable. we're using insertion sort which
+    // is well suited for small and already sorted arrays
+    // for big arrays, it could be better to use mergesort
+    const ssize_t count = size();
+    if (count > 1) {
+        void* array = const_cast<void*>(arrayImpl());
+        void* temp = 0;
+        ssize_t i = 1;
+        while (i < count) {
+            void* item = reinterpret_cast<char*>(array) + mItemSize*(i);
+            void* curr = reinterpret_cast<char*>(array) + mItemSize*(i-1);
+            if (cmp(curr, item, state) > 0) {
+
+                if (!temp) {
+                    // we're going to have to modify the array...
+                    array = editArrayImpl();
+                    if (!array) return NO_MEMORY;
+                    temp = malloc(mItemSize);
+                    if (!temp) return NO_MEMORY;
+                    _do_construct(temp, 1);
+                    item = reinterpret_cast<char*>(array) + mItemSize*(i);
+                    curr = reinterpret_cast<char*>(array) + mItemSize*(i-1);
+                }
+
+                _do_copy(temp, item, 1);
+
+                ssize_t j = i-1;
+                void* next = reinterpret_cast<char*>(array) + mItemSize*(i);                    
+                do {
+                    _do_copy(next, curr, 1);
+                    next = curr;
+                    --j;
+                    curr = reinterpret_cast<char*>(array) + mItemSize*(j);                    
+                } while (j>=0 && (cmp(curr, temp, state) > 0));
+
+                _do_copy(next, temp, 1);
+            }
+            i++;
+        }
+        
+        if (temp) {
+            _do_destroy(temp, 1);
+            free(temp);
+        }
+    }
+    return NO_ERROR;
+}
+
+void VectorImpl::pop()
+{
+    if (size())
+        removeItemsAt(size()-1, 1);
+}
+
+void VectorImpl::push()
+{
+    push(0);
+}
+
+void VectorImpl::push(const void* item)
+{
+    insertAt(item, size());
+}
+
+ssize_t VectorImpl::add()
+{
+    return add(0);
+}
+
+ssize_t VectorImpl::add(const void* item)
+{
+    return insertAt(item, size());
+}
+
+ssize_t VectorImpl::replaceAt(size_t index)
+{
+    return replaceAt(0, index);
+}
+
+ssize_t VectorImpl::replaceAt(const void* prototype, size_t index)
+{
+    LOG_ASSERT(index<size(),
+        "[%p] replace: index=%d, size=%d", this, (int)index, (int)size());
+
+    void* item = editItemLocation(index);
+    if (item == 0)
+        return NO_MEMORY;
+    _do_destroy(item, 1);
+    if (prototype == 0) {
+        _do_construct(item, 1);
+    } else {
+        _do_copy(item, prototype, 1);
+    }
+    return ssize_t(index);
+}
+
+ssize_t VectorImpl::removeItemsAt(size_t index, size_t count)
+{
+    LOG_ASSERT((index+count)<=size(),
+        "[%p] remove: index=%d, count=%d, size=%d",
+               this, (int)index, (int)count, (int)size());
+
+    if ((index+count) > size())
+        return BAD_VALUE;
+   _shrink(index, count);
+   return index;
+}
+
+void VectorImpl::finish_vector()
+{
+    release_storage();
+    mStorage = 0;
+    mCount = 0;
+}
+
+void VectorImpl::clear()
+{
+    _shrink(0, mCount);
+}
+
+void* VectorImpl::editItemLocation(size_t index)
+{
+    LOG_ASSERT(index<capacity(),
+        "[%p] itemLocation: index=%d, capacity=%d, count=%d",
+        this, (int)index, (int)capacity(), (int)mCount);
+            
+    void* buffer = editArrayImpl();
+    if (buffer)
+        return reinterpret_cast<char*>(buffer) + index*mItemSize;
+    return 0;
+}
+
+const void* VectorImpl::itemLocation(size_t index) const
+{
+    LOG_ASSERT(index<capacity(),
+        "[%p] editItemLocation: index=%d, capacity=%d, count=%d",
+        this, (int)index, (int)capacity(), (int)mCount);
+
+    const  void* buffer = arrayImpl();
+    if (buffer)
+        return reinterpret_cast<const char*>(buffer) + index*mItemSize;
+    return 0;
+}
+
+ssize_t VectorImpl::setCapacity(size_t new_capacity)
+{
+    size_t current_capacity = capacity();
+    ssize_t amount = new_capacity - size();
+    if (amount <= 0) {
+        // we can't reduce the capacity
+        return current_capacity;
+    } 
+    SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
+    if (sb) {
+        void* array = sb->data();
+        _do_copy(array, mStorage, size());
+        release_storage();
+        mStorage = const_cast<void*>(array);
+    } else {
+        return NO_MEMORY;
+    }
+    return new_capacity;
+}
+
+void VectorImpl::release_storage()
+{
+    if (mStorage) {
+        const SharedBuffer* sb = SharedBuffer::sharedBuffer(mStorage);
+        if (sb->release(SharedBuffer::eKeepStorage) == 1) {
+            _do_destroy(mStorage, mCount);
+            SharedBuffer::dealloc(sb);
+        } 
+    }
+}
+
+void* VectorImpl::_grow(size_t where, size_t amount)
+{
+//    LOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
+//        this, (int)where, (int)amount, (int)mCount, (int)capacity());
+
+    if (where > mCount)
+        where = mCount;
+      
+    const size_t new_size = mCount + amount;
+    if (capacity() < new_size) {
+        const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2);
+//        LOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity);
+        if ((mStorage) &&
+            (mCount==where) &&
+            (mFlags & HAS_TRIVIAL_COPY) &&
+            (mFlags & HAS_TRIVIAL_DTOR))
+        {
+            const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage);
+            SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
+            mStorage = sb->data();
+        } else {
+            SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
+            if (sb) {
+                void* array = sb->data();
+                if (where>0) {
+                    _do_copy(array, mStorage, where);
+                }
+                if (mCount>where) {
+                    const void* from = reinterpret_cast<const uint8_t *>(mStorage) + where*mItemSize;
+                    void* dest = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
+                    _do_copy(dest, from, mCount-where);
+                }
+                release_storage();
+                mStorage = const_cast<void*>(array);
+            }
+        }
+    } else {
+        ssize_t s = mCount-where;
+        if (s>0) {
+            void* array = editArrayImpl();    
+            void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
+            const void* from = reinterpret_cast<const uint8_t *>(array) + where*mItemSize;
+            _do_move_forward(to, from, s);
+        }
+    }
+    mCount += amount;
+    void* free_space = const_cast<void*>(itemLocation(where));
+    return free_space;
+}
+
+void VectorImpl::_shrink(size_t where, size_t amount)
+{
+    if (!mStorage)
+        return;
+
+//    LOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
+//        this, (int)where, (int)amount, (int)mCount, (int)capacity());
+
+    if (where >= mCount)
+        where = mCount - amount;
+
+    const size_t new_size = mCount - amount;
+    if (new_size*3 < capacity()) {
+        const size_t new_capacity = max(kMinVectorCapacity, new_size*2);
+//        LOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity);
+        if ((where == mCount-amount) &&
+            (mFlags & HAS_TRIVIAL_COPY) &&
+            (mFlags & HAS_TRIVIAL_DTOR))
+        {
+            const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage);
+            SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
+            mStorage = sb->data();
+        } else {
+            SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
+            if (sb) {
+                void* array = sb->data();
+                if (where>0) {
+                    _do_copy(array, mStorage, where);
+                }
+                if (mCount > where+amount) {
+                    const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize;
+                    void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
+                    _do_copy(dest, from, mCount-(where+amount));
+                }
+                release_storage();
+                mStorage = const_cast<void*>(array);
+            }
+        }
+    } else {
+        void* array = editArrayImpl();    
+        void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
+        _do_destroy(to, amount);
+        ssize_t s = mCount-(where+amount);
+        if (s>0) {
+            const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
+            _do_move_backward(to, from, s);
+        }
+    }
+
+    // adjust the number of items...
+    mCount -= amount;
+}
+
+size_t VectorImpl::itemSize() const {
+    return mItemSize;
+}
+
+void VectorImpl::_do_construct(void* storage, size_t num) const
+{
+    if (!(mFlags & HAS_TRIVIAL_CTOR)) {
+        do_construct(storage, num);
+    }
+}
+
+void VectorImpl::_do_destroy(void* storage, size_t num) const
+{
+    if (!(mFlags & HAS_TRIVIAL_DTOR)) {
+        do_destroy(storage, num);
+    }
+}
+
+void VectorImpl::_do_copy(void* dest, const void* from, size_t num) const
+{
+    if (!(mFlags & HAS_TRIVIAL_COPY)) {
+        do_copy(dest, from, num);
+    } else {
+        memcpy(dest, from, num*itemSize());
+    }
+}
+
+void VectorImpl::_do_splat(void* dest, const void* item, size_t num) const {
+    do_splat(dest, item, num);
+}
+
+void VectorImpl::_do_move_forward(void* dest, const void* from, size_t num) const {
+    do_move_forward(dest, from, num);
+}
+
+void VectorImpl::_do_move_backward(void* dest, const void* from, size_t num) const {
+    do_move_backward(dest, from, num);
+}
+
+void VectorImpl::reservedVectorImpl1() { }
+void VectorImpl::reservedVectorImpl2() { }
+void VectorImpl::reservedVectorImpl3() { }
+void VectorImpl::reservedVectorImpl4() { }
+void VectorImpl::reservedVectorImpl5() { }
+void VectorImpl::reservedVectorImpl6() { }
+void VectorImpl::reservedVectorImpl7() { }
+void VectorImpl::reservedVectorImpl8() { }
+
+/*****************************************************************************/
+
+SortedVectorImpl::SortedVectorImpl(size_t itemSize, uint32_t flags)
+    : VectorImpl(itemSize, flags)
+{
+}
+
+SortedVectorImpl::SortedVectorImpl(const VectorImpl& rhs)
+: VectorImpl(rhs)
+{
+}
+
+SortedVectorImpl::~SortedVectorImpl()
+{
+}
+
+SortedVectorImpl& SortedVectorImpl::operator = (const SortedVectorImpl& rhs)
+{
+    return static_cast<SortedVectorImpl&>( VectorImpl::operator = (static_cast<const VectorImpl&>(rhs)) );
+}
+
+ssize_t SortedVectorImpl::indexOf(const void* item) const
+{
+    return _indexOrderOf(item);
+}
+
+size_t SortedVectorImpl::orderOf(const void* item) const
+{
+    size_t o;
+    _indexOrderOf(item, &o);
+    return o;
+}
+
+ssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const
+{
+    // binary search
+    ssize_t err = NAME_NOT_FOUND;
+    ssize_t l = 0;
+    ssize_t h = size()-1;
+    ssize_t mid;
+    const void* a = arrayImpl();
+    const size_t s = itemSize();
+    while (l <= h) {
+        mid = l + (h - l)/2;
+        const void* const curr = reinterpret_cast<const char *>(a) + (mid*s);
+        const int c = do_compare(curr, item);
+        if (c == 0) {
+            err = l = mid;
+            break;
+        } else if (c < 0) {
+            l = mid + 1;
+        } else {
+            h = mid - 1;
+        }
+    }
+    if (order) *order = l;
+    return err;
+}
+
+ssize_t SortedVectorImpl::add(const void* item)
+{
+    size_t order;
+    ssize_t index = _indexOrderOf(item, &order);
+    if (index < 0) {
+        index = VectorImpl::insertAt(item, order, 1);
+    } else {
+        index = VectorImpl::replaceAt(item, index);
+    }
+    return index;
+}
+
+ssize_t SortedVectorImpl::merge(const VectorImpl& vector)
+{
+    // naive merge...
+    if (!vector.isEmpty()) {
+        const void* buffer = vector.arrayImpl();
+        const size_t is = itemSize();
+        size_t s = vector.size();
+        for (size_t i=0 ; i<s ; i++) {
+            ssize_t err = add( reinterpret_cast<const char*>(buffer) + i*is );
+            if (err<0) {
+                return err;
+            }
+        }
+    }
+    return NO_ERROR;
+}
+
+ssize_t SortedVectorImpl::merge(const SortedVectorImpl& vector)
+{
+    // we've merging a sorted vector... nice!
+    ssize_t err = NO_ERROR;
+    if (!vector.isEmpty()) {
+        // first take care of the case where the vectors are sorted together
+        if (do_compare(vector.itemLocation(vector.size()-1), arrayImpl()) <= 0) {
+            err = VectorImpl::insertVectorAt(static_cast<const VectorImpl&>(vector), 0);
+        } else if (do_compare(vector.arrayImpl(), itemLocation(size()-1)) >= 0) {
+            err = VectorImpl::appendVector(static_cast<const VectorImpl&>(vector));
+        } else {
+            // this could be made a little better
+            err = merge(static_cast<const VectorImpl&>(vector));
+        }
+    }
+    return err;
+}
+
+ssize_t SortedVectorImpl::remove(const void* item)
+{
+    ssize_t i = indexOf(item);
+    if (i>=0) {
+        VectorImpl::removeItemsAt(i, 1);
+    }
+    return i;
+}
+
+void SortedVectorImpl::reservedSortedVectorImpl1() { };
+void SortedVectorImpl::reservedSortedVectorImpl2() { };
+void SortedVectorImpl::reservedSortedVectorImpl3() { };
+void SortedVectorImpl::reservedSortedVectorImpl4() { };
+void SortedVectorImpl::reservedSortedVectorImpl5() { };
+void SortedVectorImpl::reservedSortedVectorImpl6() { };
+void SortedVectorImpl::reservedSortedVectorImpl7() { };
+void SortedVectorImpl::reservedSortedVectorImpl8() { };
+
+
+/*****************************************************************************/
+
+}; // namespace android
+
diff --git a/libs/utils/ZipEntry.cpp b/libs/utils/ZipEntry.cpp
new file mode 100644
index 0000000..fbc9e67
--- /dev/null
+++ b/libs/utils/ZipEntry.cpp
@@ -0,0 +1,696 @@
+/*
+ * Copyright (C) 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.
+ */
+
+//
+// Access to entries in a Zip archive.
+//
+
+#define LOG_TAG "zip"
+
+#include "utils/ZipEntry.h"
+#include "utils/Log.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+using namespace android;
+
+/*
+ * Initialize a new ZipEntry structure from a FILE* positioned at a
+ * CentralDirectoryEntry.
+ *
+ * On exit, the file pointer will be at the start of the next CDE or
+ * at the EOCD.
+ */
+status_t ZipEntry::initFromCDE(FILE* fp)
+{
+    status_t result;
+    long posn;
+    bool hasDD;
+
+    //LOGV("initFromCDE ---\n");
+
+    /* read the CDE */
+    result = mCDE.read(fp);
+    if (result != NO_ERROR) {
+        LOGD("mCDE.read failed\n");
+        return result;
+    }
+
+    //mCDE.dump();
+
+    /* using the info in the CDE, go load up the LFH */
+    posn = ftell(fp);
+    if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
+        LOGD("local header seek failed (%ld)\n",
+            mCDE.mLocalHeaderRelOffset);
+        return UNKNOWN_ERROR;
+    }
+
+    result = mLFH.read(fp);
+    if (result != NO_ERROR) {
+        LOGD("mLFH.read failed\n");
+        return result;
+    }
+
+    if (fseek(fp, posn, SEEK_SET) != 0)
+        return UNKNOWN_ERROR;
+
+    //mLFH.dump();
+
+    /*
+     * We *might* need to read the Data Descriptor at this point and
+     * integrate it into the LFH.  If this bit is set, the CRC-32,
+     * compressed size, and uncompressed size will be zero.  In practice
+     * these seem to be rare.
+     */
+    hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;
+    if (hasDD) {
+        // do something clever
+        //LOGD("+++ has data descriptor\n");
+    }
+
+    /*
+     * Sanity-check the LFH.  Note that this will fail if the "kUsesDataDescr"
+     * flag is set, because the LFH is incomplete.  (Not a problem, since we
+     * prefer the CDE values.)
+     */
+    if (!hasDD && !compareHeaders()) {
+        LOGW("WARNING: header mismatch\n");
+        // keep going?
+    }
+
+    /*
+     * If the mVersionToExtract is greater than 20, we may have an
+     * issue unpacking the record -- could be encrypted, compressed
+     * with something we don't support, or use Zip64 extensions.  We
+     * can defer worrying about that to when we're extracting data.
+     */
+
+    return NO_ERROR;
+}
+
+/*
+ * Initialize a new entry.  Pass in the file name and an optional comment.
+ *
+ * Initializes the CDE and the LFH.
+ */
+void ZipEntry::initNew(const char* fileName, const char* comment)
+{
+    assert(fileName != NULL && *fileName != '\0');  // name required
+
+    /* most fields are properly initialized by constructor */
+    mCDE.mVersionMadeBy = kDefaultMadeBy;
+    mCDE.mVersionToExtract = kDefaultVersion;
+    mCDE.mCompressionMethod = kCompressStored;
+    mCDE.mFileNameLength = strlen(fileName);
+    if (comment != NULL)
+        mCDE.mFileCommentLength = strlen(comment);
+    mCDE.mExternalAttrs = 0x81b60020;   // matches what WinZip does
+
+    if (mCDE.mFileNameLength > 0) {
+        mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
+        strcpy((char*) mCDE.mFileName, fileName);
+    }
+    if (mCDE.mFileCommentLength > 0) {
+        /* TODO: stop assuming null-terminated ASCII here? */
+        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
+        strcpy((char*) mCDE.mFileComment, comment);
+    }
+
+    copyCDEtoLFH();
+}
+
+/*
+ * Initialize a new entry, starting with the ZipEntry from a different
+ * archive.
+ *
+ * Initializes the CDE and the LFH.
+ */
+status_t ZipEntry::initFromExternal(const ZipFile* pZipFile,
+    const ZipEntry* pEntry)
+{
+    /*
+     * Copy everything in the CDE over, then fix up the hairy bits.
+     */
+    memcpy(&mCDE, &pEntry->mCDE, sizeof(mCDE));
+
+    if (mCDE.mFileNameLength > 0) {
+        mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
+        if (mCDE.mFileName == NULL)
+            return NO_MEMORY;
+        strcpy((char*) mCDE.mFileName, (char*)pEntry->mCDE.mFileName);
+    }
+    if (mCDE.mFileCommentLength > 0) {
+        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
+        if (mCDE.mFileComment == NULL)
+            return NO_MEMORY;
+        strcpy((char*) mCDE.mFileComment, (char*)pEntry->mCDE.mFileComment);
+    }
+    if (mCDE.mExtraFieldLength > 0) {
+        /* we null-terminate this, though it may not be a string */
+        mCDE.mExtraField = new unsigned char[mCDE.mExtraFieldLength+1];
+        if (mCDE.mExtraField == NULL)
+            return NO_MEMORY;
+        memcpy(mCDE.mExtraField, pEntry->mCDE.mExtraField,
+            mCDE.mExtraFieldLength+1);
+    }
+
+    /* construct the LFH from the CDE */
+    copyCDEtoLFH();
+
+    /*
+     * The LFH "extra" field is independent of the CDE "extra", so we
+     * handle it here.
+     */
+    assert(mLFH.mExtraField == NULL);
+    mLFH.mExtraFieldLength = pEntry->mLFH.mExtraFieldLength;
+    if (mLFH.mExtraFieldLength > 0) {
+        mLFH.mExtraField = new unsigned char[mLFH.mExtraFieldLength+1];
+        if (mLFH.mExtraField == NULL)
+            return NO_MEMORY;
+        memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField,
+            mLFH.mExtraFieldLength+1);
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Insert pad bytes in the LFH by tweaking the "extra" field.  This will
+ * potentially confuse something that put "extra" data in here earlier,
+ * but I can't find an actual problem.
+ */
+status_t ZipEntry::addPadding(int padding)
+{
+    if (padding <= 0)
+        return INVALID_OPERATION;
+
+    //LOGI("HEY: adding %d pad bytes to existing %d in %s\n",
+    //    padding, mLFH.mExtraFieldLength, mCDE.mFileName);
+
+    if (mLFH.mExtraFieldLength > 0) {
+        /* extend existing field */
+        unsigned char* newExtra;
+
+        newExtra = new unsigned char[mLFH.mExtraFieldLength + padding];
+        if (newExtra == NULL)
+            return NO_MEMORY;
+        memset(newExtra + mLFH.mExtraFieldLength, 0, padding);
+        memcpy(newExtra, mLFH.mExtraField, mLFH.mExtraFieldLength);
+
+        delete[] mLFH.mExtraField;
+        mLFH.mExtraField = newExtra;
+        mLFH.mExtraFieldLength += padding;
+    } else {
+        /* create new field */
+        mLFH.mExtraField = new unsigned char[padding];
+        memset(mLFH.mExtraField, 0, padding);
+        mLFH.mExtraFieldLength = padding;
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Set the fields in the LFH equal to the corresponding fields in the CDE.
+ *
+ * This does not touch the LFH "extra" field.
+ */
+void ZipEntry::copyCDEtoLFH(void)
+{
+    mLFH.mVersionToExtract  = mCDE.mVersionToExtract;
+    mLFH.mGPBitFlag         = mCDE.mGPBitFlag;
+    mLFH.mCompressionMethod = mCDE.mCompressionMethod;
+    mLFH.mLastModFileTime   = mCDE.mLastModFileTime;
+    mLFH.mLastModFileDate   = mCDE.mLastModFileDate;
+    mLFH.mCRC32             = mCDE.mCRC32;
+    mLFH.mCompressedSize    = mCDE.mCompressedSize;
+    mLFH.mUncompressedSize  = mCDE.mUncompressedSize;
+    mLFH.mFileNameLength    = mCDE.mFileNameLength;
+    // the "extra field" is independent
+
+    delete[] mLFH.mFileName;
+    if (mLFH.mFileNameLength > 0) {
+        mLFH.mFileName = new unsigned char[mLFH.mFileNameLength+1];
+        strcpy((char*) mLFH.mFileName, (const char*) mCDE.mFileName);
+    } else {
+        mLFH.mFileName = NULL;
+    }
+}
+
+/*
+ * Set some information about a file after we add it.
+ */
+void ZipEntry::setDataInfo(long uncompLen, long compLen, unsigned long crc32,
+    int compressionMethod)
+{
+    mCDE.mCompressionMethod = compressionMethod;
+    mCDE.mCRC32 = crc32;
+    mCDE.mCompressedSize = compLen;
+    mCDE.mUncompressedSize = uncompLen;
+    mCDE.mCompressionMethod = compressionMethod;
+    if (compressionMethod == kCompressDeflated) {
+        mCDE.mGPBitFlag |= 0x0002;      // indicates maximum compression used
+    }
+    copyCDEtoLFH();
+}
+
+/*
+ * See if the data in mCDE and mLFH match up.  This is mostly useful for
+ * debugging these classes, but it can be used to identify damaged
+ * archives.
+ *
+ * Returns "false" if they differ.
+ */
+bool ZipEntry::compareHeaders(void) const
+{
+    if (mCDE.mVersionToExtract != mLFH.mVersionToExtract) {
+        LOGV("cmp: VersionToExtract\n");
+        return false;
+    }
+    if (mCDE.mGPBitFlag != mLFH.mGPBitFlag) {
+        LOGV("cmp: GPBitFlag\n");
+        return false;
+    }
+    if (mCDE.mCompressionMethod != mLFH.mCompressionMethod) {
+        LOGV("cmp: CompressionMethod\n");
+        return false;
+    }
+    if (mCDE.mLastModFileTime != mLFH.mLastModFileTime) {
+        LOGV("cmp: LastModFileTime\n");
+        return false;
+    }
+    if (mCDE.mLastModFileDate != mLFH.mLastModFileDate) {
+        LOGV("cmp: LastModFileDate\n");
+        return false;
+    }
+    if (mCDE.mCRC32 != mLFH.mCRC32) {
+        LOGV("cmp: CRC32\n");
+        return false;
+    }
+    if (mCDE.mCompressedSize != mLFH.mCompressedSize) {
+        LOGV("cmp: CompressedSize\n");
+        return false;
+    }
+    if (mCDE.mUncompressedSize != mLFH.mUncompressedSize) {
+        LOGV("cmp: UncompressedSize\n");
+        return false;
+    }
+    if (mCDE.mFileNameLength != mLFH.mFileNameLength) {
+        LOGV("cmp: FileNameLength\n");
+        return false;
+    }
+#if 0       // this seems to be used for padding, not real data
+    if (mCDE.mExtraFieldLength != mLFH.mExtraFieldLength) {
+        LOGV("cmp: ExtraFieldLength\n");
+        return false;
+    }
+#endif
+    if (mCDE.mFileName != NULL) {
+        if (strcmp((char*) mCDE.mFileName, (char*) mLFH.mFileName) != 0) {
+            LOGV("cmp: FileName\n");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+
+/*
+ * Convert the DOS date/time stamp into a UNIX time stamp.
+ */
+time_t ZipEntry::getModWhen(void) const
+{
+    struct tm parts;
+
+    parts.tm_sec = (mCDE.mLastModFileTime & 0x001f) << 1;
+    parts.tm_min = (mCDE.mLastModFileTime & 0x07e0) >> 5;
+    parts.tm_hour = (mCDE.mLastModFileTime & 0xf800) >> 11;
+    parts.tm_mday = (mCDE.mLastModFileDate & 0x001f);
+    parts.tm_mon = ((mCDE.mLastModFileDate & 0x01e0) >> 5) -1;
+    parts.tm_year = ((mCDE.mLastModFileDate & 0xfe00) >> 9) + 80;
+    parts.tm_wday = parts.tm_yday = 0;
+    parts.tm_isdst = -1;        // DST info "not available"
+
+    return mktime(&parts);
+}
+
+/*
+ * Set the CDE/LFH timestamp from UNIX time.
+ */
+void ZipEntry::setModWhen(time_t when)
+{
+#ifdef HAVE_LOCALTIME_R
+    struct tm tmResult;
+#endif
+    time_t even;
+    unsigned short zdate, ztime;
+
+    struct tm* ptm;
+
+    /* round up to an even number of seconds */
+    even = (time_t)(((unsigned long)(when) + 1) & (~1));
+
+    /* expand */
+#ifdef HAVE_LOCALTIME_R
+    ptm = localtime_r(&even, &tmResult);
+#else
+    ptm = localtime(&even);
+#endif
+
+    int year;
+    year = ptm->tm_year;
+    if (year < 80)
+        year = 80;
+
+    zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday;
+    ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;
+
+    mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime;
+    mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate;
+}
+
+
+/*
+ * ===========================================================================
+ *      ZipEntry::LocalFileHeader
+ * ===========================================================================
+ */
+
+/*
+ * Read a local file header.
+ *
+ * On entry, "fp" points to the signature at the start of the header.
+ * On exit, "fp" points to the start of data.
+ */
+status_t ZipEntry::LocalFileHeader::read(FILE* fp)
+{
+    status_t result = NO_ERROR;
+    unsigned char buf[kLFHLen];
+
+    assert(mFileName == NULL);
+    assert(mExtraField == NULL);
+
+    if (fread(buf, 1, kLFHLen, fp) != kLFHLen) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
+        LOGD("whoops: didn't find expected signature\n");
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    mVersionToExtract = ZipEntry::getShortLE(&buf[0x04]);
+    mGPBitFlag = ZipEntry::getShortLE(&buf[0x06]);
+    mCompressionMethod = ZipEntry::getShortLE(&buf[0x08]);
+    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0a]);
+    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0c]);
+    mCRC32 = ZipEntry::getLongLE(&buf[0x0e]);
+    mCompressedSize = ZipEntry::getLongLE(&buf[0x12]);
+    mUncompressedSize = ZipEntry::getLongLE(&buf[0x16]);
+    mFileNameLength = ZipEntry::getShortLE(&buf[0x1a]);
+    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1c]);
+
+    // TODO: validate sizes
+
+    /* grab filename */
+    if (mFileNameLength != 0) {
+        mFileName = new unsigned char[mFileNameLength+1];
+        if (mFileName == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mFileName[mFileNameLength] = '\0';
+    }
+
+    /* grab extra field */
+    if (mExtraFieldLength != 0) {
+        mExtraField = new unsigned char[mExtraFieldLength+1];
+        if (mExtraField == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mExtraField[mExtraFieldLength] = '\0';
+    }
+
+bail:
+    return result;
+}
+
+/*
+ * Write a local file header.
+ */
+status_t ZipEntry::LocalFileHeader::write(FILE* fp)
+{
+    unsigned char buf[kLFHLen];
+
+    ZipEntry::putLongLE(&buf[0x00], kSignature);
+    ZipEntry::putShortLE(&buf[0x04], mVersionToExtract);
+    ZipEntry::putShortLE(&buf[0x06], mGPBitFlag);
+    ZipEntry::putShortLE(&buf[0x08], mCompressionMethod);
+    ZipEntry::putShortLE(&buf[0x0a], mLastModFileTime);
+    ZipEntry::putShortLE(&buf[0x0c], mLastModFileDate);
+    ZipEntry::putLongLE(&buf[0x0e], mCRC32);
+    ZipEntry::putLongLE(&buf[0x12], mCompressedSize);
+    ZipEntry::putLongLE(&buf[0x16], mUncompressedSize);
+    ZipEntry::putShortLE(&buf[0x1a], mFileNameLength);
+    ZipEntry::putShortLE(&buf[0x1c], mExtraFieldLength);
+
+    if (fwrite(buf, 1, kLFHLen, fp) != kLFHLen)
+        return UNKNOWN_ERROR;
+
+    /* write filename */
+    if (mFileNameLength != 0) {
+        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
+            return UNKNOWN_ERROR;
+    }
+
+    /* write "extra field" */
+    if (mExtraFieldLength != 0) {
+        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
+            return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+
+/*
+ * Dump the contents of a LocalFileHeader object.
+ */
+void ZipEntry::LocalFileHeader::dump(void) const
+{
+    LOGD(" LocalFileHeader contents:\n");
+    LOGD("  versToExt=%u gpBits=0x%04x compression=%u\n",
+        mVersionToExtract, mGPBitFlag, mCompressionMethod);
+    LOGD("  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
+        mLastModFileTime, mLastModFileDate, mCRC32);
+    LOGD("  compressedSize=%lu uncompressedSize=%lu\n",
+        mCompressedSize, mUncompressedSize);
+    LOGD("  filenameLen=%u extraLen=%u\n",
+        mFileNameLength, mExtraFieldLength);
+    if (mFileName != NULL)
+        LOGD("  filename: '%s'\n", mFileName);
+}
+
+
+/*
+ * ===========================================================================
+ *      ZipEntry::CentralDirEntry
+ * ===========================================================================
+ */
+
+/*
+ * Read the central dir entry that appears next in the file.
+ *
+ * On entry, "fp" should be positioned on the signature bytes for the
+ * entry.  On exit, "fp" will point at the signature word for the next
+ * entry or for the EOCD.
+ */
+status_t ZipEntry::CentralDirEntry::read(FILE* fp)
+{
+    status_t result = NO_ERROR;
+    unsigned char buf[kCDELen];
+
+    /* no re-use */
+    assert(mFileName == NULL);
+    assert(mExtraField == NULL);
+    assert(mFileComment == NULL);
+
+    if (fread(buf, 1, kCDELen, fp) != kCDELen) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
+        LOGD("Whoops: didn't find expected signature\n");
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    mVersionMadeBy = ZipEntry::getShortLE(&buf[0x04]);
+    mVersionToExtract = ZipEntry::getShortLE(&buf[0x06]);
+    mGPBitFlag = ZipEntry::getShortLE(&buf[0x08]);
+    mCompressionMethod = ZipEntry::getShortLE(&buf[0x0a]);
+    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0c]);
+    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0e]);
+    mCRC32 = ZipEntry::getLongLE(&buf[0x10]);
+    mCompressedSize = ZipEntry::getLongLE(&buf[0x14]);
+    mUncompressedSize = ZipEntry::getLongLE(&buf[0x18]);
+    mFileNameLength = ZipEntry::getShortLE(&buf[0x1c]);
+    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1e]);
+    mFileCommentLength = ZipEntry::getShortLE(&buf[0x20]);
+    mDiskNumberStart = ZipEntry::getShortLE(&buf[0x22]);
+    mInternalAttrs = ZipEntry::getShortLE(&buf[0x24]);
+    mExternalAttrs = ZipEntry::getLongLE(&buf[0x26]);
+    mLocalHeaderRelOffset = ZipEntry::getLongLE(&buf[0x2a]);
+
+    // TODO: validate sizes and offsets
+
+    /* grab filename */
+    if (mFileNameLength != 0) {
+        mFileName = new unsigned char[mFileNameLength+1];
+        if (mFileName == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mFileName[mFileNameLength] = '\0';
+    }
+
+    /* read "extra field" */
+    if (mExtraFieldLength != 0) {
+        mExtraField = new unsigned char[mExtraFieldLength+1];
+        if (mExtraField == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mExtraField[mExtraFieldLength] = '\0';
+    }
+
+
+    /* grab comment, if any */
+    if (mFileCommentLength != 0) {
+        mFileComment = new unsigned char[mFileCommentLength+1];
+        if (mFileComment == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
+        {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mFileComment[mFileCommentLength] = '\0';
+    }
+
+bail:
+    return result;
+}
+
+/*
+ * Write a central dir entry.
+ */
+status_t ZipEntry::CentralDirEntry::write(FILE* fp)
+{
+    unsigned char buf[kCDELen];
+
+    ZipEntry::putLongLE(&buf[0x00], kSignature);
+    ZipEntry::putShortLE(&buf[0x04], mVersionMadeBy);
+    ZipEntry::putShortLE(&buf[0x06], mVersionToExtract);
+    ZipEntry::putShortLE(&buf[0x08], mGPBitFlag);
+    ZipEntry::putShortLE(&buf[0x0a], mCompressionMethod);
+    ZipEntry::putShortLE(&buf[0x0c], mLastModFileTime);
+    ZipEntry::putShortLE(&buf[0x0e], mLastModFileDate);
+    ZipEntry::putLongLE(&buf[0x10], mCRC32);
+    ZipEntry::putLongLE(&buf[0x14], mCompressedSize);
+    ZipEntry::putLongLE(&buf[0x18], mUncompressedSize);
+    ZipEntry::putShortLE(&buf[0x1c], mFileNameLength);
+    ZipEntry::putShortLE(&buf[0x1e], mExtraFieldLength);
+    ZipEntry::putShortLE(&buf[0x20], mFileCommentLength);
+    ZipEntry::putShortLE(&buf[0x22], mDiskNumberStart);
+    ZipEntry::putShortLE(&buf[0x24], mInternalAttrs);
+    ZipEntry::putLongLE(&buf[0x26], mExternalAttrs);
+    ZipEntry::putLongLE(&buf[0x2a], mLocalHeaderRelOffset);
+
+    if (fwrite(buf, 1, kCDELen, fp) != kCDELen)
+        return UNKNOWN_ERROR;
+
+    /* write filename */
+    if (mFileNameLength != 0) {
+        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
+            return UNKNOWN_ERROR;
+    }
+
+    /* write "extra field" */
+    if (mExtraFieldLength != 0) {
+        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
+            return UNKNOWN_ERROR;
+    }
+
+    /* write comment */
+    if (mFileCommentLength != 0) {
+        if (fwrite(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
+            return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Dump the contents of a CentralDirEntry object.
+ */
+void ZipEntry::CentralDirEntry::dump(void) const
+{
+    LOGD(" CentralDirEntry contents:\n");
+    LOGD("  versMadeBy=%u versToExt=%u gpBits=0x%04x compression=%u\n",
+        mVersionMadeBy, mVersionToExtract, mGPBitFlag, mCompressionMethod);
+    LOGD("  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
+        mLastModFileTime, mLastModFileDate, mCRC32);
+    LOGD("  compressedSize=%lu uncompressedSize=%lu\n",
+        mCompressedSize, mUncompressedSize);
+    LOGD("  filenameLen=%u extraLen=%u commentLen=%u\n",
+        mFileNameLength, mExtraFieldLength, mFileCommentLength);
+    LOGD("  diskNumStart=%u intAttr=0x%04x extAttr=0x%08lx relOffset=%lu\n",
+        mDiskNumberStart, mInternalAttrs, mExternalAttrs,
+        mLocalHeaderRelOffset);
+
+    if (mFileName != NULL)
+        LOGD("  filename: '%s'\n", mFileName);
+    if (mFileComment != NULL)
+        LOGD("  comment: '%s'\n", mFileComment);
+}
+
diff --git a/libs/utils/ZipFile.cpp b/libs/utils/ZipFile.cpp
new file mode 100644
index 0000000..89aa874
--- /dev/null
+++ b/libs/utils/ZipFile.cpp
@@ -0,0 +1,1296 @@
+/*
+ * Copyright (C) 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.
+ */
+
+//
+// Access to Zip archives.
+//
+
+#define LOG_TAG "zip"
+
+#include "utils/ZipFile.h"
+#include "utils/ZipUtils.h"
+#include "utils/Log.h"
+
+#include <zlib.h>
+#define DEF_MEM_LEVEL 8                // normally in zutil.h?
+
+#include <memory.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+/*
+ * Some environments require the "b", some choke on it.
+ */
+#define FILE_OPEN_RO        "rb"
+#define FILE_OPEN_RW        "r+b"
+#define FILE_OPEN_RW_CREATE "w+b"
+
+/* should live somewhere else? */
+static status_t errnoToStatus(int err)
+{
+    if (err == ENOENT)
+        return NAME_NOT_FOUND;
+    else if (err == EACCES)
+        return PERMISSION_DENIED;
+    else
+        return UNKNOWN_ERROR;
+}
+
+/*
+ * Open a file and parse its guts.
+ */
+status_t ZipFile::open(const char* zipFileName, int flags)
+{
+    bool newArchive = false;
+
+    assert(mZipFp == NULL);     // no reopen
+
+    if ((flags & kOpenTruncate))
+        flags |= kOpenCreate;           // trunc implies create
+
+    if ((flags & kOpenReadOnly) && (flags & kOpenReadWrite))
+        return INVALID_OPERATION;       // not both
+    if (!((flags & kOpenReadOnly) || (flags & kOpenReadWrite)))
+        return INVALID_OPERATION;       // not neither
+    if ((flags & kOpenCreate) && !(flags & kOpenReadWrite))
+        return INVALID_OPERATION;       // create requires write
+
+    if (flags & kOpenTruncate) {
+        newArchive = true;
+    } else {
+        newArchive = (access(zipFileName, F_OK) != 0);
+        if (!(flags & kOpenCreate) && newArchive) {
+            /* not creating, must already exist */
+            LOGD("File %s does not exist", zipFileName);
+            return NAME_NOT_FOUND;
+        }
+    }
+
+    /* open the file */
+    const char* openflags;
+    if (flags & kOpenReadWrite) {
+        if (newArchive)
+            openflags = FILE_OPEN_RW_CREATE;
+        else
+            openflags = FILE_OPEN_RW;
+    } else {
+        openflags = FILE_OPEN_RO;
+    }
+    mZipFp = fopen(zipFileName, openflags);
+    if (mZipFp == NULL) {
+		int err = errno;
+		LOGD("fopen failed: %d\n", err);
+        return errnoToStatus(err);
+	}
+
+    status_t result;
+    if (!newArchive) {
+        /*
+         * Load the central directory.  If that fails, then this probably
+         * isn't a Zip archive.
+         */
+        result = readCentralDir();
+    } else {
+        /*
+         * Newly-created.  The EndOfCentralDir constructor actually
+         * sets everything to be the way we want it (all zeroes).  We
+         * set mNeedCDRewrite so that we create *something* if the
+         * caller doesn't add any files.  (We could also just unlink
+         * the file if it's brand new and nothing was added, but that's
+         * probably doing more than we really should -- the user might
+         * have a need for empty zip files.)
+         */
+        mNeedCDRewrite = true;
+        result = NO_ERROR;
+    }
+
+    if (flags & kOpenReadOnly)
+        mReadOnly = true;
+    else
+        assert(!mReadOnly);
+
+    return result;
+}
+
+/*
+ * Return the Nth entry in the archive.
+ */
+ZipEntry* ZipFile::getEntryByIndex(int idx) const
+{
+    if (idx < 0 || idx >= (int) mEntries.size())
+        return NULL;
+
+    return mEntries[idx];
+}
+
+/*
+ * Find an entry by name.
+ */
+ZipEntry* ZipFile::getEntryByName(const char* fileName) const
+{
+    /*
+     * Do a stupid linear string-compare search.
+     *
+     * There are various ways to speed this up, especially since it's rare
+     * to intermingle changes to the archive with "get by name" calls.  We
+     * don't want to sort the mEntries vector itself, however, because
+     * it's used to recreate the Central Directory.
+     *
+     * (Hash table works, parallel list of pointers in sorted order is good.)
+     */
+    int idx;
+
+    for (idx = mEntries.size()-1; idx >= 0; idx--) {
+        ZipEntry* pEntry = mEntries[idx];
+        if (!pEntry->getDeleted() &&
+            strcmp(fileName, pEntry->getFileName()) == 0)
+        {
+            return pEntry;
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Empty the mEntries vector.
+ */
+void ZipFile::discardEntries(void)
+{
+    int count = mEntries.size();
+
+    while (--count >= 0)
+        delete mEntries[count];
+
+    mEntries.clear();
+}
+
+
+/*
+ * Find the central directory and read the contents.
+ *
+ * The fun thing about ZIP archives is that they may or may not be
+ * readable from start to end.  In some cases, notably for archives
+ * that were written to stdout, the only length information is in the
+ * central directory at the end of the file.
+ *
+ * Of course, the central directory can be followed by a variable-length
+ * comment field, so we have to scan through it backwards.  The comment
+ * is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff
+ * itself, plus apparently sometimes people throw random junk on the end
+ * just for the fun of it.
+ *
+ * This is all a little wobbly.  If the wrong value ends up in the EOCD
+ * area, we're hosed.  This appears to be the way that everbody handles
+ * it though, so we're in pretty good company if this fails.
+ */
+status_t ZipFile::readCentralDir(void)
+{
+    status_t result = NO_ERROR;
+    unsigned char* buf = NULL;
+    off_t fileLength, seekStart;
+    long readAmount;
+    int i;
+
+    fseek(mZipFp, 0, SEEK_END);
+    fileLength = ftell(mZipFp);
+    rewind(mZipFp);
+
+    /* too small to be a ZIP archive? */
+    if (fileLength < EndOfCentralDir::kEOCDLen) {
+        LOGD("Length is %ld -- too small\n", (long)fileLength);
+        result = INVALID_OPERATION;
+        goto bail;
+    }
+
+    buf = new unsigned char[EndOfCentralDir::kMaxEOCDSearch];
+    if (buf == NULL) {
+		LOGD("Failure allocating %d bytes for EOCD search",
+			 EndOfCentralDir::kMaxEOCDSearch);
+        result = NO_MEMORY;
+        goto bail;
+    }
+
+    if (fileLength > EndOfCentralDir::kMaxEOCDSearch) {
+        seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch;
+        readAmount = EndOfCentralDir::kMaxEOCDSearch;
+    } else {
+        seekStart = 0;
+        readAmount = (long) fileLength;
+    }
+    if (fseek(mZipFp, seekStart, SEEK_SET) != 0) {
+		LOGD("Failure seeking to end of zip at %ld", (long) seekStart);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /* read the last part of the file into the buffer */
+    if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) {
+        LOGD("short file? wanted %ld\n", readAmount);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /* find the end-of-central-dir magic */
+    for (i = readAmount - 4; i >= 0; i--) {
+        if (buf[i] == 0x50 &&
+            ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature)
+        {
+            LOGV("+++ Found EOCD at buf+%d\n", i);
+            break;
+        }
+    }
+    if (i < 0) {
+        LOGD("EOCD not found, not Zip\n");
+        result = INVALID_OPERATION;
+        goto bail;
+    }
+
+    /* extract eocd values */
+    result = mEOCD.readBuf(buf + i, readAmount - i);
+    if (result != NO_ERROR) {
+		LOGD("Failure reading %ld bytes of EOCD values", readAmount - i);
+        goto bail;
+	}
+    //mEOCD.dump();
+
+    if (mEOCD.mDiskNumber != 0 || mEOCD.mDiskWithCentralDir != 0 ||
+        mEOCD.mNumEntries != mEOCD.mTotalNumEntries)
+    {
+        LOGD("Archive spanning not supported\n");
+        result = INVALID_OPERATION;
+        goto bail;
+    }
+
+    /*
+     * So far so good.  "mCentralDirSize" is the size in bytes of the
+     * central directory, so we can just seek back that far to find it.
+     * We can also seek forward mCentralDirOffset bytes from the
+     * start of the file.
+     *
+     * We're not guaranteed to have the rest of the central dir in the
+     * buffer, nor are we guaranteed that the central dir will have any
+     * sort of convenient size.  We need to skip to the start of it and
+     * read the header, then the other goodies.
+     *
+     * The only thing we really need right now is the file comment, which
+     * we're hoping to preserve.
+     */
+    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+		LOGD("Failure seeking to central dir offset %ld\n",
+			 mEOCD.mCentralDirOffset);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /*
+     * Loop through and read the central dir entries.
+     */
+    LOGV("Scanning %d entries...\n", mEOCD.mTotalNumEntries);
+    int entry;
+    for (entry = 0; entry < mEOCD.mTotalNumEntries; entry++) {
+        ZipEntry* pEntry = new ZipEntry;
+
+        result = pEntry->initFromCDE(mZipFp);
+        if (result != NO_ERROR) {
+            LOGD("initFromCDE failed\n");
+            delete pEntry;
+            goto bail;
+        }
+
+        mEntries.add(pEntry);
+    }
+
+
+    /*
+     * If all went well, we should now be back at the EOCD.
+     */
+    {
+        unsigned char checkBuf[4];
+        if (fread(checkBuf, 1, 4, mZipFp) != 4) {
+            LOGD("EOCD check read failed\n");
+            result = INVALID_OPERATION;
+            goto bail;
+        }
+        if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) {
+            LOGD("EOCD read check failed\n");
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        LOGV("+++ EOCD read check passed\n");
+    }
+
+bail:
+    delete[] buf;
+    return result;
+}
+
+
+/*
+ * Add a new file to the archive.
+ *
+ * This requires creating and populating a ZipEntry structure, and copying
+ * the data into the file at the appropriate position.  The "appropriate
+ * position" is the current location of the central directory, which we
+ * casually overwrite (we can put it back later).
+ *
+ * If we were concerned about safety, we would want to make all changes
+ * in a temp file and then overwrite the original after everything was
+ * safely written.  Not really a concern for us.
+ */
+status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size,
+    const char* storageName, int sourceType, int compressionMethod,
+    ZipEntry** ppEntry)
+{
+    ZipEntry* pEntry = NULL;
+    status_t result = NO_ERROR;
+    long lfhPosn, startPosn, endPosn, uncompressedLen;
+    FILE* inputFp = NULL;
+    unsigned long crc;
+    time_t modWhen;
+
+    if (mReadOnly)
+        return INVALID_OPERATION;
+
+    assert(compressionMethod == ZipEntry::kCompressDeflated ||
+           compressionMethod == ZipEntry::kCompressStored);
+
+    /* make sure we're in a reasonable state */
+    assert(mZipFp != NULL);
+    assert(mEntries.size() == mEOCD.mTotalNumEntries);
+
+    /* make sure it doesn't already exist */
+    if (getEntryByName(storageName) != NULL)
+        return ALREADY_EXISTS;
+
+    if (!data) {
+        inputFp = fopen(fileName, FILE_OPEN_RO);
+        if (inputFp == NULL)
+            return errnoToStatus(errno);
+    }
+
+    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    pEntry = new ZipEntry;
+    pEntry->initNew(storageName, NULL);
+
+    /*
+     * From here on out, failures are more interesting.
+     */
+    mNeedCDRewrite = true;
+
+    /*
+     * Write the LFH, even though it's still mostly blank.  We need it
+     * as a place-holder.  In theory the LFH isn't necessary, but in
+     * practice some utilities demand it.
+     */
+    lfhPosn = ftell(mZipFp);
+    pEntry->mLFH.write(mZipFp);
+    startPosn = ftell(mZipFp);
+
+    /*
+     * Copy the data in, possibly compressing it as we go.
+     */
+    if (sourceType == ZipEntry::kCompressStored) {
+        if (compressionMethod == ZipEntry::kCompressDeflated) {
+            bool failed = false;
+            result = compressFpToFp(mZipFp, inputFp, data, size, &crc);
+            if (result != NO_ERROR) {
+                LOGD("compression failed, storing\n");
+                failed = true;
+            } else {
+                /*
+                 * Make sure it has compressed "enough".  This probably ought
+                 * to be set through an API call, but I don't expect our
+                 * criteria to change over time.
+                 */
+                long src = inputFp ? ftell(inputFp) : size;
+                long dst = ftell(mZipFp) - startPosn;
+                if (dst + (dst / 10) > src) {
+                    LOGD("insufficient compression (src=%ld dst=%ld), storing\n",
+                        src, dst);
+                    failed = true;
+                }
+            }
+
+            if (failed) {
+                compressionMethod = ZipEntry::kCompressStored;
+                if (inputFp) rewind(inputFp);
+                fseek(mZipFp, startPosn, SEEK_SET);
+                /* fall through to kCompressStored case */
+            }
+        }
+        /* handle "no compression" request, or failed compression from above */
+        if (compressionMethod == ZipEntry::kCompressStored) {
+            if (inputFp) {
+                result = copyFpToFp(mZipFp, inputFp, &crc);
+            } else {
+                result = copyDataToFp(mZipFp, data, size, &crc);
+            }
+            if (result != NO_ERROR) {
+                // don't need to truncate; happens in CDE rewrite
+                LOGD("failed copying data in\n");
+                goto bail;
+            }
+        }
+
+        // currently seeked to end of file
+        uncompressedLen = inputFp ? ftell(inputFp) : size;
+    } else if (sourceType == ZipEntry::kCompressDeflated) {
+        /* we should support uncompressed-from-compressed, but it's not
+         * important right now */
+        assert(compressionMethod == ZipEntry::kCompressDeflated);
+
+        bool scanResult;
+        int method;
+        long compressedLen;
+
+        scanResult = ZipUtils::examineGzip(inputFp, &method, &uncompressedLen,
+                        &compressedLen, &crc);
+        if (!scanResult || method != ZipEntry::kCompressDeflated) {
+            LOGD("this isn't a deflated gzip file?");
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+
+        result = copyPartialFpToFp(mZipFp, inputFp, compressedLen, NULL);
+        if (result != NO_ERROR) {
+            LOGD("failed copying gzip data in\n");
+            goto bail;
+        }
+    } else {
+        assert(false);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /*
+     * We could write the "Data Descriptor", but there doesn't seem to
+     * be any point since we're going to go back and write the LFH.
+     *
+     * Update file offsets.
+     */
+    endPosn = ftell(mZipFp);            // seeked to end of compressed data
+
+    /*
+     * Success!  Fill out new values.
+     */
+    pEntry->setDataInfo(uncompressedLen, endPosn - startPosn, crc,
+        compressionMethod);
+    modWhen = getModTime(inputFp ? fileno(inputFp) : fileno(mZipFp));
+    pEntry->setModWhen(modWhen);
+    pEntry->setLFHOffset(lfhPosn);
+    mEOCD.mNumEntries++;
+    mEOCD.mTotalNumEntries++;
+    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
+    mEOCD.mCentralDirOffset = endPosn;
+
+    /*
+     * Go back and write the LFH.
+     */
+    if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+    pEntry->mLFH.write(mZipFp);
+
+    /*
+     * Add pEntry to the list.
+     */
+    mEntries.add(pEntry);
+    if (ppEntry != NULL)
+        *ppEntry = pEntry;
+    pEntry = NULL;
+
+bail:
+    if (inputFp != NULL)
+        fclose(inputFp);
+    delete pEntry;
+    return result;
+}
+
+/*
+ * Add an entry by copying it from another zip file.  If "padding" is
+ * nonzero, the specified number of bytes will be added to the "extra"
+ * field in the header.
+ *
+ * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+ */
+status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
+    int padding, ZipEntry** ppEntry)
+{
+    ZipEntry* pEntry = NULL;
+    status_t result;
+    long lfhPosn, endPosn;
+
+    if (mReadOnly)
+        return INVALID_OPERATION;
+
+    /* make sure we're in a reasonable state */
+    assert(mZipFp != NULL);
+    assert(mEntries.size() == mEOCD.mTotalNumEntries);
+
+    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    pEntry = new ZipEntry;
+    if (pEntry == NULL) {
+        result = NO_MEMORY;
+        goto bail;
+    }
+
+    result = pEntry->initFromExternal(pSourceZip, pSourceEntry);
+    if (result != NO_ERROR)
+        goto bail;
+    if (padding != 0) {
+        result = pEntry->addPadding(padding);
+        if (result != NO_ERROR)
+            goto bail;
+    }
+
+    /*
+     * From here on out, failures are more interesting.
+     */
+    mNeedCDRewrite = true;
+
+    /*
+     * Write the LFH.  Since we're not recompressing the data, we already
+     * have all of the fields filled out.
+     */
+    lfhPosn = ftell(mZipFp);
+    pEntry->mLFH.write(mZipFp);
+
+    /*
+     * Copy the data over.
+     *
+     * If the "has data descriptor" flag is set, we want to copy the DD
+     * fields as well.  This is a fixed-size area immediately following
+     * the data.
+     */
+    if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0)
+    {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    off_t copyLen;
+    copyLen = pSourceEntry->getCompressedLen();
+    if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0)
+        copyLen += ZipEntry::kDataDescriptorLen;
+
+    if (copyPartialFpToFp(mZipFp, pSourceZip->mZipFp, copyLen, NULL)
+        != NO_ERROR)
+    {
+        LOGW("copy of '%s' failed\n", pEntry->mCDE.mFileName);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /*
+     * Update file offsets.
+     */
+    endPosn = ftell(mZipFp);
+
+    /*
+     * Success!  Fill out new values.
+     */
+    pEntry->setLFHOffset(lfhPosn);      // sets mCDE.mLocalHeaderRelOffset
+    mEOCD.mNumEntries++;
+    mEOCD.mTotalNumEntries++;
+    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
+    mEOCD.mCentralDirOffset = endPosn;
+
+    /*
+     * Add pEntry to the list.
+     */
+    mEntries.add(pEntry);
+    if (ppEntry != NULL)
+        *ppEntry = pEntry;
+    pEntry = NULL;
+
+    result = NO_ERROR;
+
+bail:
+    delete pEntry;
+    return result;
+}
+
+/*
+ * Copy all of the bytes in "src" to "dst".
+ *
+ * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
+ * will be seeked immediately past the data.
+ */
+status_t ZipFile::copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32)
+{
+    unsigned char tmpBuf[32768];
+    size_t count;
+
+    *pCRC32 = crc32(0L, Z_NULL, 0);
+
+    while (1) {
+        count = fread(tmpBuf, 1, sizeof(tmpBuf), srcFp);
+        if (ferror(srcFp) || ferror(dstFp))
+            return errnoToStatus(errno);
+        if (count == 0)
+            break;
+
+        *pCRC32 = crc32(*pCRC32, tmpBuf, count);
+
+        if (fwrite(tmpBuf, 1, count, dstFp) != count) {
+            LOGD("fwrite %d bytes failed\n", (int) count);
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Copy all of the bytes in "src" to "dst".
+ *
+ * On exit, "dstFp" will be seeked immediately past the data.
+ */
+status_t ZipFile::copyDataToFp(FILE* dstFp,
+    const void* data, size_t size, unsigned long* pCRC32)
+{
+    size_t count;
+
+    *pCRC32 = crc32(0L, Z_NULL, 0);
+    if (size > 0) {
+        *pCRC32 = crc32(*pCRC32, (const unsigned char*)data, size);
+        if (fwrite(data, 1, size, dstFp) != size) {
+            LOGD("fwrite %d bytes failed\n", (int) size);
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Copy some of the bytes in "src" to "dst".
+ *
+ * If "pCRC32" is NULL, the CRC will not be computed.
+ *
+ * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
+ * will be seeked immediately past the data just written.
+ */
+status_t ZipFile::copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,
+    unsigned long* pCRC32)
+{
+    unsigned char tmpBuf[32768];
+    size_t count;
+
+    if (pCRC32 != NULL)
+        *pCRC32 = crc32(0L, Z_NULL, 0);
+
+    while (length) {
+        long readSize;
+        
+        readSize = sizeof(tmpBuf);
+        if (readSize > length)
+            readSize = length;
+
+        count = fread(tmpBuf, 1, readSize, srcFp);
+        if ((long) count != readSize) {     // error or unexpected EOF
+            LOGD("fread %d bytes failed\n", (int) readSize);
+            return UNKNOWN_ERROR;
+        }
+
+        if (pCRC32 != NULL)
+            *pCRC32 = crc32(*pCRC32, tmpBuf, count);
+
+        if (fwrite(tmpBuf, 1, count, dstFp) != count) {
+            LOGD("fwrite %d bytes failed\n", (int) count);
+            return UNKNOWN_ERROR;
+        }
+
+        length -= readSize;
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Compress all of the data in "srcFp" and write it to "dstFp".
+ *
+ * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
+ * will be seeked immediately past the compressed data.
+ */
+status_t ZipFile::compressFpToFp(FILE* dstFp, FILE* srcFp,
+    const void* data, size_t size, unsigned long* pCRC32)
+{
+    status_t result = NO_ERROR;
+	const size_t kBufSize = 32768;
+	unsigned char* inBuf = NULL;
+	unsigned char* outBuf = NULL;
+	z_stream zstream;
+    bool atEof = false;     // no feof() aviailable yet
+	unsigned long crc;
+	int zerr;
+
+	/*
+	 * Create an input buffer and an output buffer.
+	 */
+	inBuf = new unsigned char[kBufSize];
+	outBuf = new unsigned char[kBufSize];
+	if (inBuf == NULL || outBuf == NULL) {
+		result = NO_MEMORY;
+		goto bail;
+	}
+
+	/*
+	 * Initialize the zlib stream.
+	 */
+	memset(&zstream, 0, sizeof(zstream));
+	zstream.zalloc = Z_NULL;
+	zstream.zfree = Z_NULL;
+	zstream.opaque = Z_NULL;
+	zstream.next_in = NULL;
+	zstream.avail_in = 0;
+	zstream.next_out = outBuf;
+	zstream.avail_out = kBufSize;
+	zstream.data_type = Z_UNKNOWN;
+
+	zerr = deflateInit2(&zstream, Z_BEST_COMPRESSION,
+		Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
+	if (zerr != Z_OK) {
+		result = UNKNOWN_ERROR;
+		if (zerr == Z_VERSION_ERROR) {
+			LOGE("Installed zlib is not compatible with linked version (%s)\n",
+				ZLIB_VERSION);
+		} else {
+			LOGD("Call to deflateInit2 failed (zerr=%d)\n", zerr);
+		}
+		goto bail;
+	}
+
+ 	crc = crc32(0L, Z_NULL, 0);
+
+	/*
+	 * Loop while we have data.
+	 */
+	do {
+		size_t getSize;
+		int flush;
+
+		/* only read if the input buffer is empty */
+		if (zstream.avail_in == 0 && !atEof) {
+            LOGV("+++ reading %d bytes\n", (int)kBufSize);
+            if (data) {
+                getSize = size > kBufSize ? kBufSize : size;
+                memcpy(inBuf, data, getSize);
+                data = ((const char*)data) + getSize;
+                size -= getSize;
+            } else {
+                getSize = fread(inBuf, 1, kBufSize, srcFp);
+                if (ferror(srcFp)) {
+                    LOGD("deflate read failed (errno=%d)\n", errno);
+                    goto z_bail;
+                }
+            }
+            if (getSize < kBufSize) {
+                LOGV("+++  got %d bytes, EOF reached\n",
+                    (int)getSize);
+                atEof = true;
+            }
+
+			crc = crc32(crc, inBuf, getSize);
+
+			zstream.next_in = inBuf;
+			zstream.avail_in = getSize;
+		}
+
+		if (atEof)
+			flush = Z_FINISH;       /* tell zlib that we're done */
+		else
+			flush = Z_NO_FLUSH;     /* more to come! */
+
+		zerr = deflate(&zstream, flush);
+		if (zerr != Z_OK && zerr != Z_STREAM_END) {
+			LOGD("zlib deflate call failed (zerr=%d)\n", zerr);
+			result = UNKNOWN_ERROR;
+			goto z_bail;
+		}
+
+		/* write when we're full or when we're done */
+		if (zstream.avail_out == 0 ||
+			(zerr == Z_STREAM_END && zstream.avail_out != (uInt) kBufSize))
+		{
+			LOGV("+++ writing %d bytes\n", (int) (zstream.next_out - outBuf));
+            if (fwrite(outBuf, 1, zstream.next_out - outBuf, dstFp) !=
+                (size_t)(zstream.next_out - outBuf))
+            {
+				LOGD("write %d failed in deflate\n",
+                    (int) (zstream.next_out - outBuf));
+				goto z_bail;
+			}
+
+			zstream.next_out = outBuf;
+			zstream.avail_out = kBufSize;
+		}
+	} while (zerr == Z_OK);
+
+	assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+
+	*pCRC32 = crc;
+
+z_bail:
+	deflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+	delete[] inBuf;
+	delete[] outBuf;
+
+	return result;
+}
+
+/*
+ * Mark an entry as deleted.
+ *
+ * We will eventually need to crunch the file down, but if several files
+ * are being removed (perhaps as part of an "update" process) we can make
+ * things considerably faster by deferring the removal to "flush" time.
+ */
+status_t ZipFile::remove(ZipEntry* pEntry)
+{
+    /*
+     * Should verify that pEntry is actually part of this archive, and
+     * not some stray ZipEntry from a different file.
+     */
+
+    /* mark entry as deleted, and mark archive as dirty */
+    pEntry->setDeleted();
+    mNeedCDRewrite = true;
+    return NO_ERROR;
+}
+
+/*
+ * Flush any pending writes.
+ *
+ * In particular, this will crunch out deleted entries, and write the
+ * Central Directory and EOCD if we have stomped on them.
+ */
+status_t ZipFile::flush(void)
+{
+    status_t result = NO_ERROR;
+    long eocdPosn;
+    int i, count;
+
+    if (mReadOnly)
+        return INVALID_OPERATION;
+    if (!mNeedCDRewrite)
+        return NO_ERROR;
+
+    assert(mZipFp != NULL);
+
+    result = crunchArchive();
+    if (result != NO_ERROR)
+        return result;
+
+    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0)
+        return UNKNOWN_ERROR;
+
+    count = mEntries.size();
+    for (i = 0; i < count; i++) {
+        ZipEntry* pEntry = mEntries[i];
+        pEntry->mCDE.write(mZipFp);
+    }
+
+    eocdPosn = ftell(mZipFp);
+    mEOCD.mCentralDirSize = eocdPosn - mEOCD.mCentralDirOffset;
+
+    mEOCD.write(mZipFp);
+
+    /*
+     * If we had some stuff bloat up during compression and get replaced
+     * with plain files, or if we deleted some entries, there's a lot
+     * of wasted space at the end of the file.  Remove it now.
+     */
+    if (ftruncate(fileno(mZipFp), ftell(mZipFp)) != 0) {
+        LOGW("ftruncate failed %ld: %s\n", ftell(mZipFp), strerror(errno));
+        // not fatal
+    }
+
+    /* should we clear the "newly added" flag in all entries now? */
+
+    mNeedCDRewrite = false;
+    return NO_ERROR;
+}
+
+/*
+ * Crunch deleted files out of an archive by shifting the later files down.
+ *
+ * Because we're not using a temp file, we do the operation inside the
+ * current file.
+ */
+status_t ZipFile::crunchArchive(void)
+{
+    status_t result = NO_ERROR;
+    int i, count;
+    long delCount, adjust;
+
+#if 0
+    printf("CONTENTS:\n");
+    for (i = 0; i < (int) mEntries.size(); i++) {
+        printf(" %d: lfhOff=%ld del=%d\n",
+            i, mEntries[i]->getLFHOffset(), mEntries[i]->getDeleted());
+    }
+    printf("  END is %ld\n", (long) mEOCD.mCentralDirOffset);
+#endif
+
+    /*
+     * Roll through the set of files, shifting them as appropriate.  We
+     * could probably get a slight performance improvement by sliding
+     * multiple files down at once (because we could use larger reads
+     * when operating on batches of small files), but it's not that useful.
+     */
+    count = mEntries.size();
+    delCount = adjust = 0;
+    for (i = 0; i < count; i++) {
+        ZipEntry* pEntry = mEntries[i];
+        long span;
+
+        if (pEntry->getLFHOffset() != 0) {
+            long nextOffset;
+
+            /* Get the length of this entry by finding the offset
+             * of the next entry.  Directory entries don't have
+             * file offsets, so we need to find the next non-directory
+             * entry.
+             */
+            nextOffset = 0;
+            for (int ii = i+1; nextOffset == 0 && ii < count; ii++)
+                nextOffset = mEntries[ii]->getLFHOffset();
+            if (nextOffset == 0)
+                nextOffset = mEOCD.mCentralDirOffset;
+            span = nextOffset - pEntry->getLFHOffset();
+
+            assert(span >= ZipEntry::LocalFileHeader::kLFHLen);
+        } else {
+            /* This is a directory entry.  It doesn't have
+             * any actual file contents, so there's no need to
+             * move anything.
+             */
+            span = 0;
+        }
+
+        //printf("+++ %d: off=%ld span=%ld del=%d [count=%d]\n",
+        //    i, pEntry->getLFHOffset(), span, pEntry->getDeleted(), count);
+
+        if (pEntry->getDeleted()) {
+            adjust += span;
+            delCount++;
+
+            delete pEntry;
+            mEntries.removeAt(i);
+
+            /* adjust loop control */
+            count--;
+            i--;
+        } else if (span != 0 && adjust > 0) {
+            /* shuffle this entry back */
+            //printf("+++ Shuffling '%s' back %ld\n",
+            //    pEntry->getFileName(), adjust);
+            result = filemove(mZipFp, pEntry->getLFHOffset() - adjust,
+                        pEntry->getLFHOffset(), span);
+            if (result != NO_ERROR) {
+                /* this is why you use a temp file */
+                LOGE("error during crunch - archive is toast\n");
+                return result;
+            }
+
+            pEntry->setLFHOffset(pEntry->getLFHOffset() - adjust);
+        }
+    }
+
+    /*
+     * Fix EOCD info.  We have to wait until the end to do some of this
+     * because we use mCentralDirOffset to determine "span" for the
+     * last entry.
+     */
+    mEOCD.mCentralDirOffset -= adjust;
+    mEOCD.mNumEntries -= delCount;
+    mEOCD.mTotalNumEntries -= delCount;
+    mEOCD.mCentralDirSize = 0;  // mark invalid; set by flush()
+
+    assert(mEOCD.mNumEntries == mEOCD.mTotalNumEntries);
+    assert(mEOCD.mNumEntries == count);
+
+    return result;
+}
+
+/*
+ * Works like memmove(), but on pieces of a file.
+ */
+status_t ZipFile::filemove(FILE* fp, off_t dst, off_t src, size_t n)
+{
+    if (dst == src || n <= 0)
+        return NO_ERROR;
+
+    unsigned char readBuf[32768];
+
+    if (dst < src) {
+        /* shift stuff toward start of file; must read from start */
+        while (n != 0) {
+            size_t getSize = sizeof(readBuf);
+            if (getSize > n)
+                getSize = n;
+
+            if (fseek(fp, (long) src, SEEK_SET) != 0) {
+                LOGD("filemove src seek %ld failed\n", (long) src);
+                return UNKNOWN_ERROR;
+            }
+
+            if (fread(readBuf, 1, getSize, fp) != getSize) {
+                LOGD("filemove read %ld off=%ld failed\n",
+                    (long) getSize, (long) src);
+                return UNKNOWN_ERROR;
+            }
+
+            if (fseek(fp, (long) dst, SEEK_SET) != 0) {
+                LOGD("filemove dst seek %ld failed\n", (long) dst);
+                return UNKNOWN_ERROR;
+            }
+
+            if (fwrite(readBuf, 1, getSize, fp) != getSize) {
+                LOGD("filemove write %ld off=%ld failed\n",
+                    (long) getSize, (long) dst);
+                return UNKNOWN_ERROR;
+            }
+
+            src += getSize;
+            dst += getSize;
+            n -= getSize;
+        }
+    } else {
+        /* shift stuff toward end of file; must read from end */
+        assert(false);      // write this someday, maybe
+        return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+
+/*
+ * Get the modification time from a file descriptor.
+ */
+time_t ZipFile::getModTime(int fd)
+{
+    struct stat sb;
+
+    if (fstat(fd, &sb) < 0) {
+        LOGD("HEY: fstat on fd %d failed\n", fd);
+        return (time_t) -1;
+    }
+
+    return sb.st_mtime;
+}
+
+
+#if 0       /* this is a bad idea */
+/*
+ * Get a copy of the Zip file descriptor.
+ *
+ * We don't allow this if the file was opened read-write because we tend
+ * to leave the file contents in an uncertain state between calls to
+ * flush().  The duplicated file descriptor should only be valid for reads.
+ */
+int ZipFile::getZipFd(void) const
+{
+    if (!mReadOnly)
+        return INVALID_OPERATION;
+    assert(mZipFp != NULL);
+
+    int fd;
+    fd = dup(fileno(mZipFp));
+    if (fd < 0) {
+        LOGD("didn't work, errno=%d\n", errno);
+    }
+
+    return fd;
+}
+#endif
+
+
+#if 0
+/*
+ * Expand data.
+ */
+bool ZipFile::uncompress(const ZipEntry* pEntry, void* buf) const
+{
+    return false;
+}
+#endif
+
+// free the memory when you're done
+void* ZipFile::uncompress(const ZipEntry* entry)
+{
+    size_t unlen = entry->getUncompressedLen();
+    size_t clen = entry->getCompressedLen();
+
+    void* buf = malloc(unlen);
+    if (buf == NULL) {
+        return NULL;
+    }
+
+    fseek(mZipFp, 0, SEEK_SET);
+
+    off_t offset = entry->getFileOffset();
+    if (fseek(mZipFp, offset, SEEK_SET) != 0) {
+        goto bail;
+    }
+
+    switch (entry->getCompressionMethod())
+    {
+        case ZipEntry::kCompressStored: {
+            ssize_t amt = fread(buf, 1, unlen, mZipFp);
+            if (amt != (ssize_t)unlen) {
+                goto bail;
+            }
+#if 0
+            printf("data...\n");
+            const unsigned char* p = (unsigned char*)buf;
+            const unsigned char* end = p+unlen;
+            for (int i=0; i<32 && p < end; i++) {
+                printf("0x%08x ", (int)(offset+(i*0x10)));
+                for (int j=0; j<0x10 && p < end; j++) {
+                    printf(" %02x", *p);
+                    p++;
+                }
+                printf("\n");
+            }
+#endif
+
+            }
+            break;
+        case ZipEntry::kCompressDeflated: {
+            if (!ZipUtils::inflateToBuffer(mZipFp, buf, unlen, clen)) {
+                goto bail;
+            }
+            }
+            break;
+        default:
+            goto bail;
+    }
+    return buf;
+
+bail:
+    free(buf);
+    return NULL;
+}
+
+
+/*
+ * ===========================================================================
+ *		ZipFile::EndOfCentralDir
+ * ===========================================================================
+ */
+
+/*
+ * Read the end-of-central-dir fields.
+ *
+ * "buf" should be positioned at the EOCD signature, and should contain
+ * the entire EOCD area including the comment.
+ */
+status_t ZipFile::EndOfCentralDir::readBuf(const unsigned char* buf, int len)
+{
+    /* don't allow re-use */
+    assert(mComment == NULL);
+
+    if (len < kEOCDLen) {
+        /* looks like ZIP file got truncated */
+        LOGD(" Zip EOCD: expected >= %d bytes, found %d\n",
+            kEOCDLen, len);
+        return INVALID_OPERATION;
+    }
+
+    /* this should probably be an assert() */
+    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature)
+        return UNKNOWN_ERROR;
+
+    mDiskNumber = ZipEntry::getShortLE(&buf[0x04]);
+    mDiskWithCentralDir = ZipEntry::getShortLE(&buf[0x06]);
+    mNumEntries = ZipEntry::getShortLE(&buf[0x08]);
+    mTotalNumEntries = ZipEntry::getShortLE(&buf[0x0a]);
+    mCentralDirSize = ZipEntry::getLongLE(&buf[0x0c]);
+    mCentralDirOffset = ZipEntry::getLongLE(&buf[0x10]);
+    mCommentLen = ZipEntry::getShortLE(&buf[0x14]);
+
+    // TODO: validate mCentralDirOffset
+
+    if (mCommentLen > 0) {
+        if (kEOCDLen + mCommentLen > len) {
+            LOGD("EOCD(%d) + comment(%d) exceeds len (%d)\n",
+                kEOCDLen, mCommentLen, len);
+            return UNKNOWN_ERROR;
+        }
+        mComment = new unsigned char[mCommentLen];
+        memcpy(mComment, buf + kEOCDLen, mCommentLen);
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Write an end-of-central-directory section.
+ */
+status_t ZipFile::EndOfCentralDir::write(FILE* fp)
+{
+    unsigned char buf[kEOCDLen];
+
+    ZipEntry::putLongLE(&buf[0x00], kSignature);
+    ZipEntry::putShortLE(&buf[0x04], mDiskNumber);
+    ZipEntry::putShortLE(&buf[0x06], mDiskWithCentralDir);
+    ZipEntry::putShortLE(&buf[0x08], mNumEntries);
+    ZipEntry::putShortLE(&buf[0x0a], mTotalNumEntries);
+    ZipEntry::putLongLE(&buf[0x0c], mCentralDirSize);
+    ZipEntry::putLongLE(&buf[0x10], mCentralDirOffset);
+    ZipEntry::putShortLE(&buf[0x14], mCommentLen);
+
+    if (fwrite(buf, 1, kEOCDLen, fp) != kEOCDLen)
+        return UNKNOWN_ERROR;
+    if (mCommentLen > 0) {
+        assert(mComment != NULL);
+        if (fwrite(mComment, mCommentLen, 1, fp) != mCommentLen)
+            return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Dump the contents of an EndOfCentralDir object.
+ */
+void ZipFile::EndOfCentralDir::dump(void) const
+{
+    LOGD(" EndOfCentralDir contents:\n");
+    LOGD("  diskNum=%u diskWCD=%u numEnt=%u totalNumEnt=%u\n",
+        mDiskNumber, mDiskWithCentralDir, mNumEntries, mTotalNumEntries);
+    LOGD("  centDirSize=%lu centDirOff=%lu commentLen=%u\n",
+        mCentralDirSize, mCentralDirOffset, mCommentLen);
+}
+
diff --git a/libs/utils/ZipFileCRO.cpp b/libs/utils/ZipFileCRO.cpp
new file mode 100644
index 0000000..d312daf
--- /dev/null
+++ b/libs/utils/ZipFileCRO.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#include "utils/ZipFileCRO.h"
+#include "utils/ZipFileRO.h"
+
+using namespace android;
+
+ZipFileCRO ZipFileXRO_open(const char* path) {
+    ZipFileRO* zip = new ZipFileRO();
+    if (zip->open(path) == NO_ERROR) {
+        return (ZipFileCRO)zip;
+    }
+    return NULL;
+}
+
+void ZipFileCRO_destroy(ZipFileCRO zipToken) {
+    ZipFileRO* zip = (ZipFileRO*)zipToken;
+    delete zip;
+}
+
+ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zipToken,
+        const char* fileName) {
+    ZipFileRO* zip = (ZipFileRO*)zipToken;
+    return (ZipEntryCRO)zip->findEntryByName(fileName);
+}
+
+bool ZipFileCRO_getEntryInfo(ZipFileCRO zipToken, ZipEntryRO entryToken,
+        int* pMethod, long* pUncompLen,
+        long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) {
+    ZipFileRO* zip = (ZipFileRO*)zipToken;
+    ZipEntryRO entry = (ZipEntryRO)entryToken;
+    return zip->getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset,
+            pModWhen, pCrc32);
+}
+
+bool ZipFileCRO_uncompressEntry(ZipFileCRO zipToken, ZipEntryRO entryToken, int fd) {
+    ZipFileRO* zip = (ZipFileRO*)zipToken;
+    ZipEntryRO entry = (ZipEntryRO)entryToken;
+    return zip->uncompressEntry(entry, fd);
+}
diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp
new file mode 100644
index 0000000..ae8c719
--- /dev/null
+++ b/libs/utils/ZipFileRO.cpp
@@ -0,0 +1,724 @@
+/*
+ * 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.
+ */
+
+//
+// Read-only access to Zip archives, with minimal heap allocation.
+//
+#define LOG_TAG "zipro"
+//#define LOG_NDEBUG 0
+#include "utils/ZipFileRO.h"
+#include "utils/Log.h"
+#include "utils/misc.h"
+
+#include <zlib.h>
+
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+/*
+ * Zip file constants.
+ */
+#define kEOCDSignature      0x06054b50
+#define kEOCDLen            22
+#define kEOCDNumEntries     8               // offset to #of entries in file
+#define kEOCDFileOffset     16              // offset to central directory
+
+#define kMaxCommentLen      65535           // longest possible in ushort
+#define kMaxEOCDSearch      (kMaxCommentLen + kEOCDLen)
+
+#define kLFHSignature       0x04034b50
+#define kLFHLen             30              // excluding variable-len fields
+#define kLFHNameLen         26              // offset to filename length
+#define kLFHExtraLen        28              // offset to extra length
+
+#define kCDESignature       0x02014b50
+#define kCDELen             46              // excluding variable-len fields
+#define kCDEMethod          10              // offset to compression method
+#define kCDEModWhen         12              // offset to modification timestamp
+#define kCDECRC             16              // offset to entry CRC
+#define kCDECompLen         20              // offset to compressed length
+#define kCDEUncompLen       24              // offset to uncompressed length
+#define kCDENameLen         28              // offset to filename length
+#define kCDEExtraLen        30              // offset to extra length
+#define kCDECommentLen      32              // offset to comment length
+#define kCDELocalOffset     42              // offset to local hdr
+
+/*
+ * The values we return for ZipEntryRO use 0 as an invalid value, so we
+ * want to adjust the hash table index by a fixed amount.  Using a large
+ * value helps insure that people don't mix & match arguments, e.g. to
+ * findEntryByIndex().
+ */
+#define kZipEntryAdj        10000
+
+/*
+ * Convert a ZipEntryRO to a hash table index, verifying that it's in a
+ * valid range.
+ */
+int ZipFileRO::entryToIndex(const ZipEntryRO entry) const
+{
+    long ent = ((long) entry) - kZipEntryAdj;
+    if (ent < 0 || ent >= mHashTableSize || mHashTable[ent].name == NULL) {
+        LOGW("Invalid ZipEntryRO %p (%ld)\n", entry, ent);
+        return -1;
+    }
+    return ent;
+}
+
+
+/*
+ * Open the specified file read-only.  We memory-map the entire thing and
+ * close the file before returning.
+ */
+status_t ZipFileRO::open(const char* zipFileName)
+{
+    int fd = -1;
+    off_t length;
+
+    assert(mFileMap == NULL);
+
+    /*
+     * Open and map the specified file.
+     */
+    fd = ::open(zipFileName, O_RDONLY);
+    if (fd < 0) {
+        LOGW("Unable to open zip '%s': %s\n", zipFileName, strerror(errno));
+        return NAME_NOT_FOUND;
+    }
+
+    length = lseek(fd, 0, SEEK_END);
+    if (length < 0) {
+        close(fd);
+        return UNKNOWN_ERROR;
+    }
+
+    mFileMap = new FileMap();
+    if (mFileMap == NULL) {
+        close(fd);
+        return NO_MEMORY;
+    }
+    if (!mFileMap->create(zipFileName, fd, 0, length, true)) {
+        LOGW("Unable to map '%s': %s\n", zipFileName, strerror(errno));
+        close(fd);
+        return UNKNOWN_ERROR;
+    }
+
+    mFd = fd;
+
+    /*
+     * Got it mapped, verify it and create data structures for fast access.
+     */
+    if (!parseZipArchive()) {
+        mFileMap->release();
+        mFileMap = NULL;
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+/*
+ * Parse the Zip archive, verifying its contents and initializing internal
+ * data structures.
+ */
+bool ZipFileRO::parseZipArchive(void)
+{
+#define CHECK_OFFSET(_off) {                                                \
+        if ((unsigned int) (_off) >= maxOffset) {                           \
+            LOGE("ERROR: bad offset %u (max %d): %s\n",                     \
+                (unsigned int) (_off), maxOffset, #_off);                   \
+            goto bail;                                                      \
+        }                                                                   \
+    }
+    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
+    const unsigned char* ptr;
+    size_t length = mFileMap->getDataLength();
+    bool result = false;
+    unsigned int i, numEntries, cdOffset;
+    unsigned int val;
+
+    /*
+     * The first 4 bytes of the file will either be the local header
+     * signature for the first file (kLFHSignature) or, if the archive doesn't
+     * have any files in it, the end-of-central-directory signature
+     * (kEOCDSignature).
+     */
+    val = get4LE(basePtr);
+    if (val == kEOCDSignature) {
+        LOGI("Found Zip archive, but it looks empty\n");
+        goto bail;
+    } else if (val != kLFHSignature) {
+        LOGV("Not a Zip archive (found 0x%08x)\n", val);
+        goto bail;
+    }
+
+    /*
+     * Find the EOCD.  We'll find it immediately unless they have a file
+     * comment.
+     */
+    ptr = basePtr + length - kEOCDLen;
+
+    while (ptr >= basePtr) {
+        if (*ptr == (kEOCDSignature & 0xff) && get4LE(ptr) == kEOCDSignature)
+            break;
+        ptr--;
+    }
+    if (ptr < basePtr) {
+        LOGI("Could not find end-of-central-directory in Zip\n");
+        goto bail;
+    }
+
+    /*
+     * There are two interesting items in the EOCD block: the number of
+     * entries in the file, and the file offset of the start of the
+     * central directory.
+     *
+     * (There's actually a count of the #of entries in this file, and for
+     * all files which comprise a spanned archive, but for our purposes
+     * we're only interested in the current file.  Besides, we expect the
+     * two to be equivalent for our stuff.)
+     */
+    numEntries = get2LE(ptr + kEOCDNumEntries);
+    cdOffset = get4LE(ptr + kEOCDFileOffset);
+
+    /* valid offsets are [0,EOCD] */
+    unsigned int maxOffset;
+    maxOffset = (ptr - basePtr) +1;
+
+    LOGV("+++ numEntries=%d cdOffset=%d\n", numEntries, cdOffset);
+    if (numEntries == 0 || cdOffset >= length) {
+        LOGW("Invalid entries=%d offset=%d (len=%zd)\n",
+            numEntries, cdOffset, length);
+        goto bail;
+    }
+
+    /*
+     * Create hash table.  We have a minimum 75% load factor, possibly as
+     * low as 50% after we round off to a power of 2.
+     */
+    mNumEntries = numEntries;
+    mHashTableSize = roundUpPower2(1 + ((numEntries * 4) / 3));
+    mHashTable = (HashEntry*) calloc(1, sizeof(HashEntry) * mHashTableSize);
+
+    /*
+     * Walk through the central directory, adding entries to the hash
+     * table.
+     */
+    ptr = basePtr + cdOffset;
+    for (i = 0; i < numEntries; i++) {
+        unsigned int fileNameLen, extraLen, commentLen, localHdrOffset;
+        const unsigned char* localHdr;
+        unsigned int hash;
+
+        if (get4LE(ptr) != kCDESignature) {
+            LOGW("Missed a central dir sig (at %d)\n", i);
+            goto bail;
+        }
+        if (ptr + kCDELen > basePtr + length) {
+            LOGW("Ran off the end (at %d)\n", i);
+            goto bail;
+        }
+
+        localHdrOffset = get4LE(ptr + kCDELocalOffset);
+        CHECK_OFFSET(localHdrOffset);
+        fileNameLen = get2LE(ptr + kCDENameLen);
+        extraLen = get2LE(ptr + kCDEExtraLen);
+        commentLen = get2LE(ptr + kCDECommentLen);
+
+        //LOGV("+++ %d: localHdr=%d fnl=%d el=%d cl=%d\n",
+        //    i, localHdrOffset, fileNameLen, extraLen, commentLen);
+        //LOGV(" '%.*s'\n", fileNameLen, ptr + kCDELen);
+
+        /* add the CDE filename to the hash table */
+        hash = computeHash((const char*)ptr + kCDELen, fileNameLen);
+        addToHash((const char*)ptr + kCDELen, fileNameLen, hash);
+
+        localHdr = basePtr + localHdrOffset;
+        if (get4LE(localHdr) != kLFHSignature) {
+            LOGW("Bad offset to local header: %d (at %d)\n",
+                localHdrOffset, i);
+            goto bail;
+        }
+
+        ptr += kCDELen + fileNameLen + extraLen + commentLen;
+        CHECK_OFFSET(ptr - basePtr);
+    }
+
+    result = true;
+
+bail:
+    return result;
+#undef CHECK_OFFSET
+}
+
+
+/*
+ * Simple string hash function for non-null-terminated strings.
+ */
+/*static*/ unsigned int ZipFileRO::computeHash(const char* str, int len)
+{
+    unsigned int hash = 0;
+
+    while (len--)
+        hash = hash * 31 + *str++;
+
+    return hash;
+}
+
+/*
+ * Add a new entry to the hash table.
+ */
+void ZipFileRO::addToHash(const char* str, int strLen, unsigned int hash)
+{
+    int ent = hash & (mHashTableSize-1);
+
+    /*
+     * We over-allocate the table, so we're guaranteed to find an empty slot.
+     */
+    while (mHashTable[ent].name != NULL)
+        ent = (ent + 1) & (mHashTableSize-1);
+
+    mHashTable[ent].name = str;
+    mHashTable[ent].nameLen = strLen;
+}
+
+/*
+ * Find a matching entry.
+ *
+ * Returns 0 if not found.
+ */
+ZipEntryRO ZipFileRO::findEntryByName(const char* fileName) const
+{
+    int nameLen = strlen(fileName);
+    unsigned int hash = computeHash(fileName, nameLen);
+    int ent = hash & (mHashTableSize-1);
+
+    while (mHashTable[ent].name != NULL) {
+        if (mHashTable[ent].nameLen == nameLen &&
+            memcmp(mHashTable[ent].name, fileName, nameLen) == 0)
+        {
+            /* match */
+            return (ZipEntryRO) (ent + kZipEntryAdj);
+        }
+
+        ent = (ent + 1) & (mHashTableSize-1);
+    }
+
+    return NULL;
+}
+
+/*
+ * Find the Nth entry.
+ *
+ * This currently involves walking through the sparse hash table, counting
+ * non-empty entries.  If we need to speed this up we can either allocate
+ * a parallel lookup table or (perhaps better) provide an iterator interface.
+ */
+ZipEntryRO ZipFileRO::findEntryByIndex(int idx) const
+{
+    if (idx < 0 || idx >= mNumEntries) {
+        LOGW("Invalid index %d\n", idx);
+        return NULL;
+    }
+
+    for (int ent = 0; ent < mHashTableSize; ent++) {
+        if (mHashTable[ent].name != NULL) {
+            if (idx-- == 0)
+                return (ZipEntryRO) (ent + kZipEntryAdj);
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Get the useful fields from the zip entry.
+ *
+ * Returns "false" if the offsets to the fields or the contents of the fields
+ * appear to be bogus.
+ */
+bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, long* pUncompLen,
+    long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const
+{
+    int ent = entryToIndex(entry);
+    if (ent < 0)
+        return false;
+
+    /*
+     * Recover the start of the central directory entry from the filename
+     * pointer.
+     */
+    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
+    const unsigned char* ptr = (const unsigned char*) mHashTable[ent].name;
+    size_t zipLength = mFileMap->getDataLength();
+
+    ptr -= kCDELen;
+
+    int method = get2LE(ptr + kCDEMethod);
+    if (pMethod != NULL)
+        *pMethod = method;
+
+    if (pModWhen != NULL)
+        *pModWhen = get4LE(ptr + kCDEModWhen);
+    if (pCrc32 != NULL)
+        *pCrc32 = get4LE(ptr + kCDECRC);
+
+    /*
+     * We need to make sure that the lengths are not so large that somebody
+     * trying to map the compressed or uncompressed data runs off the end
+     * of the mapped region.
+     */
+    unsigned long localHdrOffset = get4LE(ptr + kCDELocalOffset);
+    if (localHdrOffset + kLFHLen >= zipLength) {
+        LOGE("ERROR: bad local hdr offset in zip\n");
+        return false;
+    }
+    const unsigned char* localHdr = basePtr + localHdrOffset;
+    off_t dataOffset = localHdrOffset + kLFHLen
+        + get2LE(localHdr + kLFHNameLen) + get2LE(localHdr + kLFHExtraLen);
+    if ((unsigned long) dataOffset >= zipLength) {
+        LOGE("ERROR: bad data offset in zip\n");
+        return false;
+    }
+
+    if (pCompLen != NULL) {
+        *pCompLen = get4LE(ptr + kCDECompLen);
+        if (*pCompLen < 0 || (size_t)(dataOffset + *pCompLen) >= zipLength) {
+            LOGE("ERROR: bad compressed length in zip\n");
+            return false;
+        }
+    }
+    if (pUncompLen != NULL) {
+        *pUncompLen = get4LE(ptr + kCDEUncompLen);
+        if (*pUncompLen < 0) {
+            LOGE("ERROR: negative uncompressed length in zip\n");
+            return false;
+        }
+        if (method == kCompressStored &&
+            (size_t)(dataOffset + *pUncompLen) >= zipLength)
+        {
+            LOGE("ERROR: bad uncompressed length in zip\n");
+            return false;
+        }
+    }
+
+    if (pOffset != NULL) {
+        *pOffset = dataOffset;
+    }
+    return true;
+}
+
+/*
+ * Copy the entry's filename to the buffer.
+ */
+int ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen)
+    const
+{
+    int ent = entryToIndex(entry);
+    if (ent < 0)
+        return -1;
+
+    int nameLen = mHashTable[ent].nameLen;
+    if (bufLen < nameLen+1)
+        return nameLen+1;
+
+    memcpy(buffer, mHashTable[ent].name, nameLen);
+    buffer[nameLen] = '\0';
+    return 0;
+}
+
+/*
+ * Create a new FileMap object that spans the data in "entry".
+ */
+FileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const
+{
+    /*
+     * TODO: the efficient way to do this is to modify FileMap to allow
+     * sub-regions of a file to be mapped.  A reference-counting scheme
+     * can manage the base memory mapping.  For now, we just create a brand
+     * new mapping off of the Zip archive file descriptor.
+     */
+
+    FileMap* newMap;
+    long compLen;
+    off_t offset;
+
+    if (!getEntryInfo(entry, NULL, NULL, &compLen, &offset, NULL, NULL))
+        return NULL;
+
+    newMap = new FileMap();
+    if (!newMap->create(mFileMap->getFileName(), mFd, offset, compLen, true)) {
+        newMap->release();
+        return NULL;
+    }
+
+    return newMap;
+}
+
+/*
+ * Uncompress an entry, in its entirety, into the provided output buffer.
+ *
+ * This doesn't verify the data's CRC, which might be useful for
+ * uncompressed data.  The caller should be able to manage it.
+ */
+bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
+{
+    const int kSequentialMin = 32768;
+    bool result = false;
+    int ent = entryToIndex(entry);
+    if (ent < 0)
+        return -1;
+
+    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
+    int method;
+    long uncompLen, compLen;
+    off_t offset;
+
+    getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
+
+    /*
+     * Experiment with madvise hint.  When we want to uncompress a file,
+     * we pull some stuff out of the central dir entry and then hit a
+     * bunch of compressed or uncompressed data sequentially.  The CDE
+     * visit will cause a limited amount of read-ahead because it's at
+     * the end of the file.  We could end up doing lots of extra disk
+     * access if the file we're prying open is small.  Bottom line is we
+     * probably don't want to turn MADV_SEQUENTIAL on and leave it on.
+     *
+     * So, if the compressed size of the file is above a certain minimum
+     * size, temporarily boost the read-ahead in the hope that the extra
+     * pair of system calls are negated by a reduction in page faults.
+     */
+    if (compLen > kSequentialMin)
+        mFileMap->advise(FileMap::SEQUENTIAL);
+
+    if (method == kCompressStored) {
+        memcpy(buffer, basePtr + offset, uncompLen);
+    } else {
+        if (!inflateBuffer(buffer, basePtr + offset, uncompLen, compLen))
+            goto bail;
+    }
+
+    if (compLen > kSequentialMin)
+        mFileMap->advise(FileMap::NORMAL);
+
+    result = true;
+
+bail:
+    return result;
+}
+
+/*
+ * Uncompress an entry, in its entirety, to an open file descriptor.
+ *
+ * This doesn't verify the data's CRC, but probably should.
+ */
+bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
+{
+    bool result = false;
+    int ent = entryToIndex(entry);
+    if (ent < 0)
+        return -1;
+
+    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
+    int method;
+    long uncompLen, compLen;
+    off_t offset;
+
+    getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
+
+    if (method == kCompressStored) {
+        ssize_t actual;
+
+        actual = write(fd, basePtr + offset, uncompLen);
+        if (actual < 0) {
+            LOGE("Write failed: %s\n", strerror(errno));
+            goto bail;
+        } else if (actual != uncompLen) {
+            LOGE("Partial write during uncompress (%d of %ld)\n",
+                (int)actual, uncompLen);
+            goto bail;
+        } else {
+            LOGI("+++ successful write\n");
+        }
+    } else {
+        if (!inflateBuffer(fd, basePtr+offset, uncompLen, compLen))
+            goto bail;
+    }
+
+    result = true;
+
+bail:
+    return result;
+}
+
+/*
+ * Uncompress "deflate" data from one buffer to another.
+ */
+/*static*/ bool ZipFileRO::inflateBuffer(void* outBuf, const void* inBuf,
+    long uncompLen, long compLen)
+{
+    bool result = false;
+    z_stream zstream;
+    int zerr;
+
+    /*
+     * Initialize the zlib stream struct.
+     */
+	memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = (Bytef*)inBuf;
+    zstream.avail_in = compLen;
+    zstream.next_out = (Bytef*) outBuf;
+    zstream.avail_out = uncompLen;
+    zstream.data_type = Z_UNKNOWN;
+
+	/*
+	 * Use the undocumented "negative window bits" feature to tell zlib
+	 * that there's no zlib header waiting for it.
+	 */
+    zerr = inflateInit2(&zstream, -MAX_WBITS);
+    if (zerr != Z_OK) {
+        if (zerr == Z_VERSION_ERROR) {
+            LOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
+        }
+        goto bail;
+    }
+
+    /*
+     * Expand data.
+     */
+    zerr = inflate(&zstream, Z_FINISH);
+    if (zerr != Z_STREAM_END) {
+        LOGW("Zip inflate failed, zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
+            zerr, zstream.next_in, zstream.avail_in,
+            zstream.next_out, zstream.avail_out);
+        goto z_bail;
+    }
+
+    /* paranoia */
+    if ((long) zstream.total_out != uncompLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+            zstream.total_out, uncompLen);
+        goto z_bail;
+    }
+
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+    return result;
+}
+
+/*
+ * Uncompress "deflate" data from one buffer to an open file descriptor.
+ */
+/*static*/ bool ZipFileRO::inflateBuffer(int fd, const void* inBuf,
+    long uncompLen, long compLen)
+{
+    bool result = false;
+    const int kWriteBufSize = 32768;
+    unsigned char writeBuf[kWriteBufSize];
+    z_stream zstream;
+    int zerr;
+
+    /*
+     * Initialize the zlib stream struct.
+     */
+	memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = (Bytef*)inBuf;
+    zstream.avail_in = compLen;
+    zstream.next_out = (Bytef*) writeBuf;
+    zstream.avail_out = sizeof(writeBuf);
+    zstream.data_type = Z_UNKNOWN;
+
+	/*
+	 * Use the undocumented "negative window bits" feature to tell zlib
+	 * that there's no zlib header waiting for it.
+	 */
+    zerr = inflateInit2(&zstream, -MAX_WBITS);
+    if (zerr != Z_OK) {
+        if (zerr == Z_VERSION_ERROR) {
+            LOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
+        }
+        goto bail;
+    }
+
+    /*
+     * Loop while we have more to do.
+     */
+    do {
+        /*
+         * Expand data.
+         */
+        zerr = inflate(&zstream, Z_NO_FLUSH);
+        if (zerr != Z_OK && zerr != Z_STREAM_END) {
+            LOGW("zlib inflate: zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
+                zerr, zstream.next_in, zstream.avail_in,
+                zstream.next_out, zstream.avail_out);
+            goto z_bail;
+        }
+
+        /* write when we're full or when we're done */
+        if (zstream.avail_out == 0 ||
+            (zerr == Z_STREAM_END && zstream.avail_out != sizeof(writeBuf)))
+        {
+            long writeSize = zstream.next_out - writeBuf;
+            int cc = write(fd, writeBuf, writeSize);
+            if (cc != (int) writeSize) {
+                LOGW("write failed in inflate (%d vs %ld)\n", cc, writeSize);
+                goto z_bail;
+            }
+
+            zstream.next_out = writeBuf;
+            zstream.avail_out = sizeof(writeBuf);
+        }
+    } while (zerr == Z_OK);
+
+    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+
+    /* paranoia */
+    if ((long) zstream.total_out != uncompLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+            zstream.total_out, uncompLen);
+        goto z_bail;
+    }
+
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+    return result;
+}
diff --git a/libs/utils/ZipUtils.cpp b/libs/utils/ZipUtils.cpp
new file mode 100644
index 0000000..bfbacfe
--- /dev/null
+++ b/libs/utils/ZipUtils.cpp
@@ -0,0 +1,344 @@
+/*
+ * 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.
+ */
+
+//
+// Misc zip/gzip utility functions.
+//
+
+#define LOG_TAG "ziputil"
+
+#include "utils/ZipUtils.h"
+#include "utils/ZipFileRO.h"
+#include "utils/Log.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <zlib.h>
+
+using namespace android;
+
+/*
+ * Utility function that expands zip/gzip "deflate" compressed data
+ * into a buffer.
+ *
+ * "fd" is an open file positioned at the start of the "deflate" data
+ * "buf" must hold at least "uncompressedLen" bytes.
+ */
+/*static*/ bool ZipUtils::inflateToBuffer(int fd, void* buf,
+    long uncompressedLen, long compressedLen)
+{
+    bool result = false;
+	const unsigned long kReadBufSize = 32768;
+	unsigned char* readBuf = NULL;
+    z_stream zstream;
+    int zerr;
+    unsigned long compRemaining;
+
+    assert(uncompressedLen >= 0);
+    assert(compressedLen >= 0);
+
+	readBuf = new unsigned char[kReadBufSize];
+	if (readBuf == NULL)
+        goto bail;
+    compRemaining = compressedLen;
+
+    /*
+     * Initialize the zlib stream.
+     */
+	memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = NULL;
+    zstream.avail_in = 0;
+    zstream.next_out = (Bytef*) buf;
+    zstream.avail_out = uncompressedLen;
+    zstream.data_type = Z_UNKNOWN;
+
+	/*
+	 * Use the undocumented "negative window bits" feature to tell zlib
+	 * that there's no zlib header waiting for it.
+	 */
+    zerr = inflateInit2(&zstream, -MAX_WBITS);
+    if (zerr != Z_OK) {
+        if (zerr == Z_VERSION_ERROR) {
+            LOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
+        }
+        goto bail;
+    }
+
+    /*
+     * Loop while we have data.
+     */
+    do {
+        unsigned long getSize;
+
+        /* read as much as we can */
+        if (zstream.avail_in == 0) {
+            getSize = (compRemaining > kReadBufSize) ?
+                        kReadBufSize : compRemaining;
+            LOGV("+++ reading %ld bytes (%ld left)\n",
+                getSize, compRemaining);
+
+            int cc = read(fd, readBuf, getSize);
+            if (cc != (int) getSize) {
+                LOGD("inflate read failed (%d vs %ld)\n",
+                    cc, getSize);
+                goto z_bail;
+            }
+
+            compRemaining -= getSize;
+
+            zstream.next_in = readBuf;
+            zstream.avail_in = getSize;
+        }
+
+        /* uncompress the data */
+        zerr = inflate(&zstream, Z_NO_FLUSH);
+        if (zerr != Z_OK && zerr != Z_STREAM_END) {
+            LOGD("zlib inflate call failed (zerr=%d)\n", zerr);
+            goto z_bail;
+        }
+
+		/* output buffer holds all, so no need to write the output */
+    } while (zerr == Z_OK);
+
+    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+
+    if ((long) zstream.total_out != uncompressedLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+            zstream.total_out, uncompressedLen);
+        goto z_bail;
+    }
+
+    // success!
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+	delete[] readBuf;
+    return result;
+}
+
+/*
+ * Utility function that expands zip/gzip "deflate" compressed data
+ * into a buffer.
+ *
+ * (This is a clone of the previous function, but it takes a FILE* instead
+ * of an fd.  We could pass fileno(fd) to the above, but we can run into
+ * trouble when "fp" has a different notion of what fd's file position is.)
+ *
+ * "fp" is an open file positioned at the start of the "deflate" data
+ * "buf" must hold at least "uncompressedLen" bytes.
+ */
+/*static*/ bool ZipUtils::inflateToBuffer(FILE* fp, void* buf,
+    long uncompressedLen, long compressedLen)
+{
+    bool result = false;
+	const unsigned long kReadBufSize = 32768;
+	unsigned char* readBuf = NULL;
+    z_stream zstream;
+    int zerr;
+    unsigned long compRemaining;
+
+    assert(uncompressedLen >= 0);
+    assert(compressedLen >= 0);
+
+	readBuf = new unsigned char[kReadBufSize];
+	if (readBuf == NULL)
+        goto bail;
+    compRemaining = compressedLen;
+
+    /*
+     * Initialize the zlib stream.
+     */
+	memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = NULL;
+    zstream.avail_in = 0;
+    zstream.next_out = (Bytef*) buf;
+    zstream.avail_out = uncompressedLen;
+    zstream.data_type = Z_UNKNOWN;
+
+	/*
+	 * Use the undocumented "negative window bits" feature to tell zlib
+	 * that there's no zlib header waiting for it.
+	 */
+    zerr = inflateInit2(&zstream, -MAX_WBITS);
+    if (zerr != Z_OK) {
+        if (zerr == Z_VERSION_ERROR) {
+            LOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
+        }
+        goto bail;
+    }
+
+    /*
+     * Loop while we have data.
+     */
+    do {
+        unsigned long getSize;
+
+        /* read as much as we can */
+        if (zstream.avail_in == 0) {
+            getSize = (compRemaining > kReadBufSize) ?
+                        kReadBufSize : compRemaining;
+            LOGV("+++ reading %ld bytes (%ld left)\n",
+                getSize, compRemaining);
+
+            int cc = fread(readBuf, getSize, 1, fp);
+            if (cc != (int) getSize) {
+                LOGD("inflate read failed (%d vs %ld)\n",
+                    cc, getSize);
+                goto z_bail;
+            }
+
+            compRemaining -= getSize;
+
+            zstream.next_in = readBuf;
+            zstream.avail_in = getSize;
+        }
+
+        /* uncompress the data */
+        zerr = inflate(&zstream, Z_NO_FLUSH);
+        if (zerr != Z_OK && zerr != Z_STREAM_END) {
+            LOGD("zlib inflate call failed (zerr=%d)\n", zerr);
+            goto z_bail;
+        }
+
+		/* output buffer holds all, so no need to write the output */
+    } while (zerr == Z_OK);
+
+    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+
+    if ((long) zstream.total_out != uncompressedLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+            zstream.total_out, uncompressedLen);
+        goto z_bail;
+    }
+
+    // success!
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+	delete[] readBuf;
+    return result;
+}
+
+/*
+ * Look at the contents of a gzip archive.  We want to know where the
+ * data starts, and how long it will be after it is uncompressed.
+ *
+ * We expect to find the CRC and length as the last 8 bytes on the file.
+ * This is a pretty reasonable thing to expect for locally-compressed
+ * files, but there's a small chance that some extra padding got thrown
+ * on (the man page talks about compressed data written to tape).  We
+ * don't currently deal with that here.  If "gzip -l" whines, we're going
+ * to fail too.
+ *
+ * On exit, "fp" is pointing at the start of the compressed data.
+ */
+/*static*/ bool ZipUtils::examineGzip(FILE* fp, int* pCompressionMethod,
+    long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32)
+{
+    enum {  // flags
+        FTEXT       = 0x01,
+        FHCRC       = 0x02,
+        FEXTRA      = 0x04,
+        FNAME       = 0x08,
+        FCOMMENT    = 0x10,
+    };
+    int ic;
+    int method, flags;
+    int i;
+
+    ic = getc(fp);
+    if (ic != 0x1f || getc(fp) != 0x8b)
+        return false;       // not gzip
+    method = getc(fp);
+    flags = getc(fp);
+
+    /* quick sanity checks */
+    if (method == EOF || flags == EOF)
+        return false;
+    if (method != ZipFileRO::kCompressDeflated)
+        return false;
+
+    /* skip over 4 bytes of mod time, 1 byte XFL, 1 byte OS */
+    for (i = 0; i < 6; i++)
+        (void) getc(fp);
+    /* consume "extra" field, if present */
+    if ((flags & FEXTRA) != 0) {
+        int len;
+
+        len = getc(fp);
+        len |= getc(fp) << 8;
+        while (len-- && getc(fp) != EOF)
+            ;
+    }
+    /* consume filename, if present */
+    if ((flags & FNAME) != 0) {
+        do {
+            ic = getc(fp);
+        } while (ic != 0 && ic != EOF);
+    }
+    /* consume comment, if present */
+    if ((flags & FCOMMENT) != 0) {
+        do {
+            ic = getc(fp);
+        } while (ic != 0 && ic != EOF);
+    }
+    /* consume 16-bit header CRC, if present */
+    if ((flags & FHCRC) != 0) {
+        (void) getc(fp);
+        (void) getc(fp);
+    }
+
+    if (feof(fp) || ferror(fp))
+        return false;
+
+    /* seek to the end; CRC and length are in the last 8 bytes */
+    long curPosn = ftell(fp);
+    unsigned char buf[8];
+    fseek(fp, -8, SEEK_END);
+    *pCompressedLen = ftell(fp) - curPosn;
+
+    if (fread(buf, 1, 8, fp) != 8)
+        return false;
+    /* seek back to start of compressed data */
+    fseek(fp, curPosn, SEEK_SET);
+
+    *pCompressionMethod = method;
+    *pCRC32 = ZipFileRO::get4LE(&buf[0]);
+    *pUncompressedLen = ZipFileRO::get4LE(&buf[4]);
+
+    return true;
+}
+
diff --git a/libs/utils/characterData.h b/libs/utils/characterData.h
new file mode 100644
index 0000000..e931d99
--- /dev/null
+++ b/libs/utils/characterData.h
@@ -0,0 +1,730 @@
+/*
+ * 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.
+ */
+
+// Automatically generated on 07-11-2006 by make-CharacterDataC
+// DO NOT EDIT DIRECTLY
+namespace CharacterData {
+
+    // Structure containing an array of ranges
+    struct Range {
+        int length;
+        const uint32_t* array;
+    };
+
+    // For Latin1 characters just index into this array to get the index and decomposition
+    static const uint16_t LATIN1_DATA[] = {
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x0001, 0x0002, 0x0003, 0x0002, 0x0004, 0x0003, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0003, 0x0003, 0x0002, 
+        0x0005, 0x0006, 0x0006, 0x0007, 0x0008, 0x0007, 0x0006, 0x0006, 
+        0x0009, 0x000A, 0x0006, 0x000B, 0x000C, 0x000D, 0x000C, 0x000C, 
+        0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 
+        0x0016, 0x0017, 0x000C, 0x0006, 0x0018, 0x0019, 0x001A, 0x0006, 
+        0x0006, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 
+        0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 
+        0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 
+        0x0032, 0x0033, 0x0034, 0x0035, 0x0006, 0x0036, 0x0037, 0x0038, 
+        0x0037, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 
+        0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 
+        0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 
+        0x0050, 0x0051, 0x0052, 0x0035, 0x0019, 0x0036, 0x0019, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x5853, 0x0006, 0x0008, 0x0008, 0x0008, 0x0008, 0x0054, 0x0054, 
+        0x1037, 0x0054, 0x7855, 0x0056, 0x0019, 0x0057, 0x0054, 0x1037, 
+        0x0058, 0x0059, 0x785A, 0x785B, 0x1037, 0x105C, 0x0054, 0x0006, 
+        0x1037, 0x785D, 0x7855, 0x005E, 0x305F, 0x305F, 0x305F, 0x0006, 
+        0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0060, 0x0860, 
+        0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 
+        0x0060, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0019, 
+        0x0060, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0060, 0x0055, 
+        0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0061, 0x0861, 
+        0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 
+        0x0061, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0019, 
+        0x0061, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0061, 0x0862
+    };
+
+    // Each of these arrays is stripped into ranges. In order to build the arrays, each
+    // codepoint was bit-shifted so that even and odd characters were separated into different
+    // arrays. The identifier of each array is the top byte after bit-shifting.
+    // The numbers stored in the array are the bit-shifted codepoint, the decomposition, and an
+    // index into another array of all possible packed data values. The top 16 bits are the
+    // codepoint and the bottom 16 are the decomposition and index. The top 5 bits for the decomposition
+    // and the rest for the index.
+    static const uint32_t a0[] = {
+        0x00800863, 0x00880063, 0x00890863, 0x00930063, 0x00940863, 0x00980864, 0x00991063, 0x009A0863, 
+        0x009C0055, 0x009D0865, 0x00A01065, 0x00A10065, 0x00A20865, 0x00A50063, 0x00A60863, 0x00A90063, 
+        0x00AA0863, 0x00B30063, 0x00B40863, 0x00BC0866, 0x00BD0865, 0x00C00055, 0x00C10063, 0x00C30067, 
+        0x00C40065, 0x00C50068, 0x00C60065, 0x00C70069, 0x00C8006A, 0x00C90065, 0x00CA006B, 0x00CB006C, 
+        0x00CC0063, 0x00CD006D, 0x00CE006C, 0x00CF006E, 0x00D00863, 0x00D10063, 0x00D3006F, 0x00D40065, 
+        0x00D50055, 0x00D60063, 0x00D7006F, 0x00D80865, 0x00D90070, 0x00DA0065, 0x00DC0063, 0x00DD0055, 
+        0x00DE0063, 0x00DF0055, 0x00E00071, 0x00E21072, 0x00E31073, 0x00E41074, 0x00E51072, 0x00E61073, 
+        0x00E70865, 0x00EF0863, 0x00F20063, 0x00F30863, 0x00F80855, 0x00F91074, 0x00FA0863, 0x00FB0075, 
+        0x00FC0863, 0x010E0063, 0x010F0863, 0x01100076, 0x01110063, 0x01130863, 0x011A0055, 0x011D0077, 
+        0x011E0065, 0x011F0077, 0x01200055, 0x01210078, 0x01280055, 0x012A0079, 0x012B007A, 0x012C0055, 
+        0x0130007A, 0x01310055, 0x0134007B, 0x01350055, 0x0139007C, 0x013A0055, 0x0140007D, 0x01410055, 
+        0x0144007D, 0x0145007E, 0x01460055, 0x0149007F, 0x014A0080, 0x014B0055, 0x01587881, 0x015D0082, 
+        0x015E0081, 0x01610037, 0x01630082, 0x01680081, 0x01690037, 0x016C1037, 0x016F0037, 0x01707881, 
+        0x01730037, 0x01770081, 0x01780037, 0x01800083, 0x01A00883, 0x01A10083, 0x01A20883, 0x01A30083, 
+        0x01B80078, 0x01BA0837, 0x01BB0078, 0x01BD1081, 0x01BE0078, 0x01BF0806, 0x01C00078, 0x01C21037, 
+        0x01C30884, 0x01C40885, 0x01C60886, 0x01C70887, 0x01C80855, 0x01C90060, 0x01D10078, 0x01D20060, 
+        0x01D50860, 0x01D60888, 0x01D70889, 0x01D80855, 0x01D90061, 0x01E1008A, 0x01E20061, 0x01E50861, 
+        0x01E6088B, 0x01E7088C, 0x01E8108D, 0x01E91077, 0x01EA0877, 0x01EB108E, 0x01EC0063, 0x01F8108F, 
+        0x01F91090, 0x01FA1091, 0x01FB0019, 0x01FC0065, 0x01FD0063, 0x01FE0055, 0x01FF0077, 0x02000892, 
+        0x02010092, 0x02060892, 0x02080060, 0x02180061, 0x02280893, 0x02290093, 0x022E0893, 0x02300063, 
+        0x023B0863, 0x023C0063, 0x02410094, 0x02420083, 0x02440095, 0x02450063, 0x02600077, 0x02610865, 
+        0x02620065, 0x02680863, 0x026A0063, 0x026B0863, 0x026C0063, 0x026D0863, 0x02700063, 0x02710863, 
+        0x02740063, 0x02750863, 0x027B0063, 0x027C0863, 0x027D0078, 0x02800063, 0x02880078, 0x02990096, 
+        0x02AC0078, 0x02AD0097, 0x02B00078, 0x02B10098, 0x02C40078, 0x02C50099, 0x02C60078, 0x02C90083, 
+        0x02DD0078, 0x02DE0083, 0x02DF009A, 0x02E10083, 0x02E3009A, 0x02E40078, 0x02E8009B, 0x02F60078, 
+        0x02F8009B, 0x02FA009A, 0x02FB0078, 0x0300009C, 0x03020078, 0x0306000C, 0x03070054, 0x03080083, 
+        0x030B0078, 0x030F009D, 0x03100078, 0x0311089E, 0x0314009E, 0x031E0078, 0x0320009F, 0x0321009E, 
+        0x03260083, 0x033000A0, 0x033100A1, 0x033200A2, 0x033300A3, 0x033400A4, 0x03350007, 0x033600A5, 
+        0x0337009E, 0x03380083, 0x0339009E, 0x033B109E, 0x033D009E, 0x0360089E, 0x0362009E, 0x036A009D, 
+        0x036B0083, 0x036F0095, 0x03700083, 0x0373009F, 0x03740083, 0x0377009E, 0x0378000E, 0x03790010, 
+        0x037A0012, 0x037B0014, 0x037C0016, 0x037D009E, 0x037F00A6, 0x0380009D, 0x03870078, 0x0388009E, 
+        0x03980083, 0x03A60078, 0x03A7009E, 0x03B70078, 0x03C0009E, 0x03D30083, 0x03D90078, 0x04810083, 
+        0x04820071, 0x049A0871, 0x049B0071, 0x049D0078, 0x049E0083, 0x049F00A7, 0x04A10083, 0x04A500A7, 
+        0x04A70078, 0x04A80071, 0x04A90083, 0x04AB0078, 0x04AC0871, 0x04B00071, 0x04B10083, 0x04B20097, 
+        0x04B300A8, 0x04B400A9, 0x04B500AA, 0x04B600AB, 0x04B700AC, 0x04B80097, 0x04B90078, 0x04C100A7, 
+        0x04C20078, 0x04C30071, 0x04C70078, 0x04C80071, 0x04C90078, 0x04CA0071, 0x04DA0078, 0x04DB0071, 
+        0x04DD0078, 0x04DE0083, 0x04DF00A7, 0x04E10083, 0x04E30078, 0x04E400A7, 0x04E50078, 0x04E608A7, 
+        0x04E70071, 0x04E80078, 0x04EE0871, 0x04EF0078, 0x04F00071, 0x04F10083, 0x04F20078, 0x04F300A8, 
+        0x04F400A9, 0x04F500AA, 0x04F600AB, 0x04F700AC, 0x04F80071, 0x04F90008, 0x04FA00AD, 0x04FB00AE, 
+        0x04FC00AF, 0x04FD0094, 0x04FE0078, 0x05010083, 0x05020078, 0x05030071, 0x05060078, 0x05080071, 
+        0x05090078, 0x050A0071, 0x051A0078, 0x051B0871, 0x051C0071, 0x051D0078, 0x051E0083, 0x051F00A7, 
+        0x05210083, 0x05220078, 0x05240083, 0x05250078, 0x05260083, 0x05270078, 0x052D0871, 0x052E0071, 
+        0x052F0871, 0x05300078, 0x053300A8, 0x053400A9, 0x053500AA, 0x053600AB, 0x053700AC, 0x05380083, 
+        0x05390071, 0x053B0078, 0x05410083, 0x05420078, 0x05430071, 0x05470078, 0x05480071, 0x05490078, 
+        0x054A0071, 0x055A0078, 0x055B0071, 0x055D0078, 0x055E0083, 0x055F00A7, 0x05610083, 0x05630078, 
+        0x05640083, 0x05650078, 0x056600A7, 0x05670078, 0x05680071, 0x05690078, 0x05700071, 0x05710083, 
+        0x05720078, 0x057300A8, 0x057400A9, 0x057500AA, 0x057600AB, 0x057700AC, 0x05780078, 0x058100A7, 
+        0x05820078, 0x05830071, 0x05870078, 0x05880071, 0x05890078, 0x058A0071, 0x059A0078, 0x059B0071, 
+        0x059D0078, 0x059E0083, 0x059F00A7, 0x05A10083, 0x05A20078, 0x05A408A7, 0x05A50078, 0x05A608A7, 
+        0x05A70078, 0x05AB0083, 0x05AC0078, 0x05AE0871, 0x05AF0078, 0x05B00071, 0x05B10078, 0x05B300A8, 
+        0x05B400A9, 0x05B500AA, 0x05B600AB, 0x05B700AC, 0x05B80094, 0x05B90078, 0x05C10083, 0x05C20078, 
+        0x05C30071, 0x05C60078, 0x05C70071, 0x05CA0871, 0x05CB0078, 0x05CD0071, 0x05D00078, 0x05D20071, 
+        0x05D30078, 0x05D40071, 0x05D60078, 0x05D70071, 0x05DD0078, 0x05DF00A7, 0x05E00083, 0x05E100A7, 
+        0x05E20078, 0x05E300A7, 0x05E508A7, 0x05E70078, 0x05F300A8, 0x05F400A9, 0x05F500AA, 0x05F600AB, 
+        0x05F700AC, 0x05F800B0, 0x05F900B1, 0x05FA0054, 0x05FE0078, 0x060100A7, 0x06020078, 0x06030071, 
+        0x061A0078, 0x061B0071, 0x061D0078, 0x061F0083, 0x062100A7, 0x06230083, 0x06240883, 0x06250083, 
+        0x06270078, 0x062B0083, 0x062C0078, 0x06300071, 0x06310078, 0x063300A8, 0x063400A9, 0x063500AA, 
+        0x063600AB, 0x063700AC, 0x06380078, 0x064100A7, 0x06420078, 0x06430071, 0x065A0078, 0x065B0071, 
+        0x065D0078, 0x065E0083, 0x065F00A7, 0x066008A7, 0x066100A7, 0x066300B2, 0x066408A7, 0x06660083, 
+        0x06670078, 0x066B00A7, 0x066C0078, 0x066F0071, 0x06710078, 0x067300A8, 0x067400A9, 0x067500AA, 
+        0x067600AB, 0x067700AC, 0x06780078, 0x068100A7, 0x06820078, 0x06830071, 0x069D0078, 0x069F00A7, 
+        0x06A10083, 0x06A20078, 0x06A300A7, 0x06A508A7, 0x06A70078, 0x06B00071, 0x06B10078, 0x06B300A8, 
+        0x06B400A9, 0x06B500AA, 0x06B600AB, 0x06B700AC, 0x06B80078, 0x06C100A7, 0x06C20078, 0x06C30071, 
+        0x06CC0078, 0x06CD0071, 0x06D90078, 0x06DA0071, 0x06DE0078, 0x06E00071, 0x06E40078, 0x06E50083, 
+        0x06E60078, 0x06E800A7, 0x06E90083, 0x06EC00A7, 0x06ED08A7, 0x06F00078, 0x06F900A7, 0x06FA0097, 
+        0x06FB0078, 0x07010071, 0x071A0083, 0x071E0078, 0x07200071, 0x07230081, 0x07240083, 0x072800A8, 
+        0x072900A9, 0x072A00AA, 0x072B00AB, 0x072C00AC, 0x072D0097, 0x072E0078, 0x07410071, 0x07430078, 
+        0x07440071, 0x07460078, 0x074A0071, 0x074C0078, 0x074D0071, 0x07500078, 0x07510071, 0x07520078, 
+        0x07550071, 0x07560078, 0x07570071, 0x075A0083, 0x075D0078, 0x075E0083, 0x075F0078, 0x07600071, 
+        0x07630081, 0x07640083, 0x07670078, 0x076800A8, 0x076900A9, 0x076A00AA, 0x076B00AB, 0x076C00AC, 
+        0x076D0078, 0x076E1071, 0x076F0078, 0x07800071, 0x07810094, 0x07820097, 0x07865897, 0x07870097, 
+        0x078A0094, 0x078C0083, 0x078D0094, 0x079000A8, 0x079100A9, 0x079200AA, 0x079300AB, 0x079400AC, 
+        0x079500B3, 0x079A0094, 0x079D00B4, 0x079F00A7, 0x07A00071, 0x07A40078, 0x07A50071, 0x07A90871, 
+        0x07AA0071, 0x07AE0871, 0x07AF0071, 0x07B60078, 0x07B90083, 0x07BB0883, 0x07BD0083, 0x07C40071, 
+        0x07C60078, 0x07C80083, 0x07CC0078, 0x07CD0083, 0x07D10883, 0x07D20083, 0x07D60883, 0x07D70083, 
+        0x07DF0094, 0x07E30083, 0x07E40094, 0x07E70078, 0x07E80097, 0x07E90078, 0x08000071, 0x08110078, 
+        0x08120071, 0x08130871, 0x08140078, 0x08150071, 0x081600A7, 0x08170083, 0x081A0078, 0x081B0083, 
+        0x081C00A7, 0x081D0078, 0x082000A8, 0x082100A9, 0x082200AA, 0x082300AB, 0x082400AC, 0x08250097, 
+        0x08280071, 0x082B00A7, 0x082C0083, 0x082D0078, 0x085000B5, 0x08630078, 0x08680071, 0x087E7881, 
+        0x087F0078, 0x08800071, 0x08AD0078, 0x08B00071, 0x08D20078, 0x08D40071, 0x08FD0078, 0x09000071, 
+        0x09270078, 0x09280071, 0x092F0078, 0x09300071, 0x09470078, 0x09480071, 0x095B0078, 0x095C0071, 
+        0x09630078, 0x09640071, 0x098B0078, 0x098C0071, 0x09AE0078, 0x09B00094, 0x09B10097, 0x09B500B6, 
+        0x09B600B7, 0x09B700B8, 0x09B800B9, 0x09B900B0, 0x09BA00BA, 0x09BB00BB, 0x09BC00BC, 0x09BD00BD, 
+        0x09BE00BE, 0x09BF0078, 0x09C00071, 0x09C80054, 0x09CD0078, 0x09D00071, 0x09FB0078, 0x0A010071, 
+        0x0B370097, 0x0B380071, 0x0B3C0078, 0x0B400005, 0x0B410071, 0x0B4E00BF, 0x0B4F0078, 0x0B500071, 
+        0x0B760097, 0x0B7700C0, 0x0B7800C1, 0x0B790078, 0x0B800071, 0x0B890083, 0x0B8B0078, 0x0B900071, 
+        0x0B990083, 0x0B9B0097, 0x0B9C0078, 0x0BA00071, 0x0BA90083, 0x0BAA0078, 0x0BB00071, 0x0BB90083, 
+        0x0BBA0078, 0x0BC00071, 0x0BDA00C2, 0x0BDB00A7, 0x0BDC0083, 0x0BDF00A7, 0x0BE30083, 0x0BE400A7, 
+        0x0BE50083, 0x0BEA0097, 0x0BEE0071, 0x0BEF0078, 0x0BF000A8, 0x0BF100A9, 0x0BF200AA, 0x0BF300AB, 
+        0x0BF400AC, 0x0BF50078, 0x0BF800C3, 0x0BF900C4, 0x0BFA00C5, 0x0BFB00C6, 0x0BFC00C7, 0x0BFD0078, 
+        0x0C000006, 0x0C030099, 0x0C040006, 0x0C060083, 0x0C070005, 0x0C0800A8, 0x0C0900A9, 0x0C0A00AA, 
+        0x0C0B00AB, 0x0C0C00AC, 0x0C0D0078, 0x0C100071, 0x0C3C0078, 0x0C400071, 0x0C550078, 0x0C800071, 
+        0x0C8F0078, 0x0C900083, 0x0C9200A7, 0x0C940083, 0x0C9500C8, 0x0C960078, 0x0C9800A7, 0x0C990083, 
+        0x0C9A00A7, 0x0C9D0083, 0x0C9E0078, 0x0CA00054, 0x0CA10078, 0x0CA20006, 0x0CA300A8, 0x0CA400A9, 
+        0x0CA500AA, 0x0CA600AB, 0x0CA700AC, 0x0CA80071, 0x0CB70078, 0x0CB80071, 0x0CBB0078, 0x0CC00071, 
+        0x0CD50078, 0x0CD800A7, 0x0CE10071, 0x0CE400A7, 0x0CE50078, 0x0CE800A8, 0x0CE900A9, 0x0CEA00AA, 
+        0x0CEB00AB, 0x0CEC00AC, 0x0CED0078, 0x0CEF0006, 0x0CF00054, 0x0D000071, 0x0D0C0083, 0x0D0D00A7, 
+        0x0D0E0078, 0x0D0F0097, 0x0D100078, 0x0E800055, 0x0E967881, 0x0EA70081, 0x0EA87881, 0x0EB17055, 
+        0x0EB60055, 0x0EBC7881, 0x0EBD0055, 0x0ECE7881, 0x0EE00083, 0x0EE20078, 0x0F000863, 0x0F4B0855, 
+        0x0F4D1055, 0x0F4E0078, 0x0F500863, 0x0F7D0078, 0x0F8008C9, 0x0F8408CA, 0x0F8808C9, 0x0F8B0078, 
+        0x0F8C08CA, 0x0F8F0078, 0x0F9008C9, 0x0F9408CA, 0x0F9808C9, 0x0F9C08CA, 0x0FA008C9, 0x0FA30078, 
+        0x0FA408CA, 0x0FA70078, 0x0FA80855, 0x0FAC0078, 0x0FB008C9, 0x0FB408CA, 0x0FB808CB, 0x0FB908CC, 
+        0x0FBB08CD, 0x0FBC08CE, 0x0FBD08CF, 0x0FBE08D0, 0x0FBF0078, 0x0FC008C9, 0x0FC408D1, 0x0FC808C9, 
+        0x0FCC08D1, 0x0FD008C9, 0x0FD408D1, 0x0FD808C9, 0x0FD90855, 0x0FDC08CA, 0x0FDD08D2, 0x0FDE08D3, 
+        0x0FDF08D4, 0x0FE01037, 0x0FE10855, 0x0FE408D5, 0x0FE608D3, 0x0FE70837, 0x0FE808C9, 0x0FE90855, 
+        0x0FEA0078, 0x0FEB0855, 0x0FEC08CA, 0x0FED08D6, 0x0FEE0078, 0x0FEF0837, 0x0FF008C9, 0x0FF10855, 
+        0x0FF408CA, 0x0FF508D7, 0x0FF608D8, 0x0FF70837, 0x0FF80078, 0x0FF90855, 0x0FFC08D9, 0x0FFD08DA, 
+        0x0FFE08D3, 0x0FFF1037, 0x10000805, 0x10011005, 0x10060057, 0x100700C2, 0x10080099, 0x100B0006, 
+        0x100C00DB, 0x100D00B4, 0x100E00DB, 0x100F00B4, 0x10100006, 0x10121006, 0x101400DC, 0x101500DD, 
+        0x101600DE, 0x101700DF, 0x10180007, 0x101A1007, 0x101B1006, 0x101C0006, 0x101D00E0, 0x101E1006, 
+        0x10200038, 0x10210006, 0x102200E1, 0x1023000A, 0x10241006, 0x10250006, 0x10290019, 0x102A0038, 
+        0x102B0006, 0x10300057, 0x10320078, 0x10350057, 0x103878E2, 0x10390078, 0x103A78E3, 0x103B78E4, 
+        0x103C78E5, 0x103D780B, 0x103E7819, 0x103F780A, 0x104070E2, 0x1041705A, 0x104270E3, 0x104370E4, 
+        0x104470E5, 0x1045700B, 0x10467019, 0x1047700A, 0x10487081, 0x104B0078, 0x10500008, 0x10541008, 
+        0x10550008, 0x105B0078, 0x10680083, 0x106F0095, 0x10730083, 0x10760078, 0x10801054, 0x10812877, 
+        0x10820054, 0x10831054, 0x10840054, 0x10852855, 0x10862877, 0x10872855, 0x10882877, 0x108A0054, 
+        0x108B1054, 0x108C0054, 0x108D2877, 0x108F0054, 0x10907854, 0x10922877, 0x109308E6, 0x10942877, 
+        0x109508E7, 0x10962877, 0x10970058, 0x10982877, 0x10990054, 0x109A2855, 0x109B1071, 0x109D0054, 
+        0x109E2855, 0x109F2877, 0x10A028E8, 0x10A10019, 0x10A32855, 0x10A50054, 0x10A70078, 0x10AA305F, 
+        0x10B010E9, 0x10B110EA, 0x10B210EB, 0x10B310EC, 0x10B410ED, 0x10B510EE, 0x10B610EF, 0x10B710F0, 
+        0x10B810F1, 0x10B910F2, 0x10BA10F3, 0x10BB10F4, 0x10BC10F5, 0x10BD10F6, 0x10BE10F7, 0x10BF10F8, 
+        0x10C000F9, 0x10C100FA, 0x10C20078, 0x10C80019, 0x10CB0054, 0x10CD0819, 0x10CE0054, 0x10D00019, 
+        0x10D10054, 0x10D30019, 0x10D40054, 0x10D70819, 0x10D80054, 0x10E70819, 0x10E80054, 0x10E90019, 
+        0x10EB0054, 0x10FA0019, 0x110100E8, 0x110208E8, 0x11030019, 0x110400FB, 0x110608FC, 0x11070019, 
+        0x1109000B, 0x110A0019, 0x110B00E8, 0x110C0019, 0x110D00E8, 0x110F0019, 0x111000E8, 0x111208E8, 
+        0x11140019, 0x111610E8, 0x111700E8, 0x111810E8, 0x111900E8, 0x111A0019, 0x111E00FD, 0x111F00E8, 
+        0x112208E8, 0x112300E8, 0x11270019, 0x112900FD, 0x112B0019, 0x113008E8, 0x113200FD, 0x11360019, 
+        0x113708FD, 0x113900FD, 0x113A08FD, 0x113B00FD, 0x113C08FD, 0x113D00FD, 0x114008FD, 0x114100FD, 
+        0x114208FD, 0x114300FD, 0x114408FD, 0x114500FD, 0x114600E8, 0x11470019, 0x114800FE, 0x114A0019, 
+        0x114C00FF, 0x114D0019, 0x115100FD, 0x11520019, 0x11530100, 0x11540101, 0x115500E8, 0x115608E8, 
+        0x115800FD, 0x115C00E8, 0x115D0019, 0x115F00E8, 0x11600019, 0x116500FE, 0x11670019, 0x116800FD, 
+        0x11690019, 0x116B00FD, 0x117008FD, 0x117200FD, 0x117508FD, 0x11770019, 0x117800FD, 0x11790102, 
+        0x117B0103, 0x117C00E8, 0x117D0104, 0x117F0105, 0x11800054, 0x118400FD, 0x11860054, 0x119000E8, 
+        0x11910054, 0x1195080A, 0x11960054, 0x119B0094, 0x11BE0019, 0x11BF0054, 0x11CE0019, 0x11DA00B4, 
+        0x11DB0006, 0x11DC0054, 0x11EE0078, 0x12000054, 0x12140078, 0x12200054, 0x12260078, 0x12301906, 
+        0x12311907, 0x12321908, 0x12331909, 0x1234190A, 0x1235190B, 0x1236190C, 0x1237190D, 0x1238190E, 
+        0x1239190F, 0x123A1106, 0x123B1107, 0x123C1108, 0x123D1109, 0x123E110A, 0x123F110B, 0x1240110C, 
+        0x1241110D, 0x1242110E, 0x1243110F, 0x1244105D, 0x1245105B, 0x12461110, 0x12471111, 0x12481112, 
+        0x12491113, 0x124A1114, 0x124B1115, 0x124C1116, 0x124D1117, 0x124E1094, 0x125B1918, 0x12681919, 
+        0x127518C3, 0x1276011A, 0x1277011B, 0x1278011C, 0x1279011D, 0x127A011E, 0x127B00C4, 0x127C00C5, 
+        0x127D00C6, 0x127E00C7, 0x127F011F, 0x12800054, 0x12FC0019, 0x13000054, 0x134F0078, 0x13500054, 
+        0x13560094, 0x13570054, 0x13590078, 0x13810054, 0x13850078, 0x13860054, 0x13940078, 0x13950054, 
+        0x13A60078, 0x13A80054, 0x13AA0078, 0x13AB0054, 0x13B00078, 0x13B10054, 0x13B40009, 0x13BB0106, 
+        0x13BC0107, 0x13BD0108, 0x13BE0109, 0x13BF010A, 0x13C00106, 0x13C10107, 0x13C20108, 0x13C30109, 
+        0x13C4010A, 0x13C50106, 0x13C60107, 0x13C70108, 0x13C80109, 0x13C9010A, 0x13CA0054, 0x13CB0078, 
+        0x13CC0054, 0x13D80078, 0x13D90054, 0x13E000E8, 0x13E10019, 0x13E200FE, 0x13E3000A, 0x13E40078, 
+        0x13E80019, 0x13EA00E8, 0x13EB00FE, 0x13EC0019, 0x13EE00E8, 0x13EF00FE, 0x13F00019, 0x13F100FD, 
+        0x13F30009, 0x13F60078, 0x13F80019, 0x14000094, 0x14800019, 0x14C2000A, 0x14C70120, 0x14C80121, 
+        0x14C9000A, 0x14CD0019, 0x14CE00E8, 0x14D80019, 0x14DC0122, 0x14DD0019, 0x14E000FD, 0x14E100E8, 
+        0x14E200FD, 0x14E30019, 0x14E700E8, 0x14E800FE, 0x14EA00FD, 0x14EB0019, 0x14EC0009, 0x14EE00E8, 
+        0x14EF0019, 0x14F200E8, 0x14F30019, 0x14F400E8, 0x14F50019, 0x14FA00E8, 0x14FC00FD, 0x14FD0019, 
+        0x14FE0009, 0x14FF0019, 0x150500E8, 0x150610E8, 0x150700E8, 0x15110019, 0x151200E8, 0x15140019, 
+        0x151600FE, 0x15180019, 0x151A00FD, 0x151B0019, 0x151E00FD, 0x151F00E8, 0x15200019, 0x152C00E8, 
+        0x152D0019, 0x153200FD, 0x15330019, 0x153500E8, 0x15370019, 0x153800E8, 0x15390019, 0x153A10E8, 
+        0x153B1019, 0x153C0019, 0x153D00FE, 0x153E00E8, 0x153F00FE, 0x154300E8, 0x154600FE, 0x154700E8, 
+        0x154900FE, 0x154F00E8, 0x155100FE, 0x15520019, 0x155300FD, 0x15570019, 0x155800FE, 0x155900E8, 
+        0x155A00FE, 0x155B00E8, 0x155E00FE, 0x156400E8, 0x156700FE, 0x156C0019, 0x156E08E8, 0x156F0123, 
+        0x15700019, 0x157100E8, 0x15720124, 0x157300E8, 0x15740019, 0x157600FD, 0x157700E8, 0x15780019, 
+        0x157C00FE, 0x157E0019, 0x15800054, 0x158A0078, 0x16000096, 0x16180098, 0x16300078, 0x16400063, 
+        0x16720055, 0x16730054, 0x16760078, 0x167D0006, 0x16800125, 0x16930078, 0x16980071, 0x16B30078, 
+        0x16C00071, 0x16CC0078, 0x16D00071, 0x16F00078, 0x17000006, 0x17010126, 0x17030006, 0x170500E0, 
+        0x17060126, 0x17070006, 0x170C0078, 0x170E0126, 0x170F0078, 0x17400054, 0x174D0078, 0x174E0054, 
+        0x177A0078, 0x17801054, 0x17EB0078, 0x17F80054, 0x17FE0078, 0x18008805, 0x18010006, 0x18020054, 
+        0x18030071, 0x18040009, 0x18090054, 0x180A0009, 0x180E0099, 0x180F00BF, 0x18100054, 0x18110127, 
+        0x18120128, 0x18130129, 0x1814012A, 0x18150083, 0x18180099, 0x18190081, 0x181B1054, 0x181C112B, 
+        0x181D112C, 0x181E0071, 0x181F0054, 0x18200078, 0x18210071, 0x18260871, 0x18320071, 0x18380871, 
+        0x18390071, 0x183A0871, 0x183C0071, 0x183D0871, 0x183F0071, 0x184A0871, 0x184B0071, 0x184C0078, 
+        0x184D0083, 0x184E1037, 0x184F0881, 0x18500099, 0x18510071, 0x18560871, 0x18620071, 0x18680871, 
+        0x18690071, 0x186A0871, 0x186C0071, 0x186D0871, 0x186F0071, 0x187A0871, 0x187B0071, 0x187C0871, 
+        0x187E0081, 0x187F0881, 0x18800078, 0x18830071, 0x18970078, 0x18991071, 0x18C80094, 0x18C978AD, 
+        0x18CA78AE, 0x18CB7894, 0x18D00071, 0x18DC0078, 0x18E00054, 0x18E80078, 0x18F80071, 0x19001094, 
+        0x190F1054, 0x191010AD, 0x191110AE, 0x1912112D, 0x1913112E, 0x1914112F, 0x19151094, 0x19220078, 
+        0x19286854, 0x19291930, 0x192A1931, 0x192B1932, 0x192C1933, 0x192D1934, 0x192E1935, 0x192F1936, 
+        0x19301894, 0x193E1854, 0x194018AD, 0x194118AE, 0x1942192D, 0x1943192E, 0x1944192F, 0x19451894, 
+        0x19591937, 0x195A1938, 0x195B1939, 0x195C193A, 0x195D193B, 0x195E193C, 0x195F193D, 0x19601094, 
+        0x19666854, 0x19681894, 0x19806894, 0x19AC1094, 0x19B96894, 0x19BC6854, 0x19BE6894, 0x19EF6854, 
+        0x19F01094, 0x1A000071, 0x26DB0078, 0x26E00054, 0x27000071, 0x4FDE0078, 0x50000071, 0x52470078, 
+        0x52480054, 0x52640078, 0x53800037, 0x538C0078, 0x54000071, 0x540100C8, 0x54020071, 0x54030083, 
+        0x54040071, 0x541200A7, 0x54130083, 0x54140054, 0x54160078, 0x56000071, 0x6BD20078, 0x6C00013E, 
+        0x7000013F, 0x7C800871, 0x7D070071, 0x7D080871, 0x7D0A0071, 0x7D0B0871, 0x7D120071, 0x7D130871, 
+        0x7D140071, 0x7D150871, 0x7D170078, 0x7D180871, 0x7D360078, 0x7D380871, 0x7D6D0078, 0x7D801055, 
+        0x7D840078, 0x7D8A1055, 0x7D8C0078, 0x7D8F0083, 0x7D90289B, 0x7D95089B, 0x7DA10078, 0x7DA2089B, 
+        0x7DA8409E, 0x7DAA389E, 0x7DAB409E, 0x7DAC389E, 0x7DAD409E, 0x7DAE389E, 0x7DAF409E, 0x7DB0389E, 
+        0x7DB1409E, 0x7DB2389E, 0x7DB3409E, 0x7DB4389E, 0x7DB5409E, 0x7DB6389E, 0x7DB7409E, 0x7DB8389E, 
+        0x7DB9409E, 0x7DBA389E, 0x7DBB409E, 0x7DBC389E, 0x7DBD409E, 0x7DBE389E, 0x7DBF409E, 0x7DC0389E, 
+        0x7DC1409E, 0x7DC8389E, 0x7DC9409E, 0x7DCA389E, 0x7DCB409E, 0x7DCC389E, 0x7DCD409E, 0x7DCE389E, 
+        0x7DCF409E, 0x7DD1389E, 0x7DD2409E, 0x7DD4389E, 0x7DD5409E, 0x7DD6389E, 0x7DD7409E, 0x7DD90078, 
+        0x7DEA209E, 0x7DEB489E, 0x7DEC209E, 0x7DEF409E, 0x7DF3389E, 0x7DF5409E, 0x7DFC389E, 0x7DFD209E, 
+        0x7DFE409E, 0x7DFF389E, 0x7E00409E, 0x7E32209E, 0x7E4C389E, 0x7E70489E, 0x7E7B409E, 0x7E89209E, 
+        0x7E97389E, 0x7E9A489E, 0x7E9E209E, 0x7E9F00B4, 0x7EA00078, 0x7EA8389E, 0x7EAC209E, 0x7EAE389E, 
+        0x7EAF209E, 0x7EB0389E, 0x7EB1209E, 0x7EB4389E, 0x7EB5209E, 0x7EB8389E, 0x7EBA209E, 0x7EC3389E, 
+        0x7EC80078, 0x7EC9389E, 0x7ECB209E, 0x7ECC389E, 0x7ECD209E, 0x7EDA389E, 0x7EDB209E, 0x7EDC389E, 
+        0x7EDE209E, 0x7EE2389E, 0x7EE3209E, 0x7EE40078, 0x7EF8409E, 0x7EFE4140, 0x7EFF0078, 0x7F000083, 
+        0x7F088006, 0x7F0C80BF, 0x7F0D0078, 0x7F100083, 0x7F120078, 0x7F188006, 0x7F198099, 0x7F1A8038, 
+        0x7F1B80BF, 0x7F230006, 0x7F2480BF, 0x7F251006, 0x7F271038, 0x7F28600C, 0x7F2A6006, 0x7F2C6099, 
+        0x7F2D60BF, 0x7F306006, 0x7F31600B, 0x7F326019, 0x7F346006, 0x7F356007, 0x7F360078, 0x7F38409E, 
+        0x7F41209E, 0x7F46489E, 0x7F47209E, 0x7F49489E, 0x7F4A209E, 0x7F4C489E, 0x7F4D209E, 0x7F4E489E, 
+        0x7F4F209E, 0x7F50489E, 0x7F51209E, 0x7F52489E, 0x7F53209E, 0x7F54489E, 0x7F55209E, 0x7F5A489E, 
+        0x7F5B209E, 0x7F5C489E, 0x7F5D209E, 0x7F5E489E, 0x7F5F209E, 0x7F60489E, 0x7F61209E, 0x7F62489E, 
+        0x7F63209E, 0x7F64489E, 0x7F65209E, 0x7F66489E, 0x7F67209E, 0x7F68489E, 0x7F69209E, 0x7F6A489E, 
+        0x7F6B209E, 0x7F6C489E, 0x7F6D209E, 0x7F6E489E, 0x7F6F209E, 0x7F70489E, 0x7F71209E, 0x7F72489E, 
+        0x7F73209E, 0x7F74489E, 0x7F75209E, 0x7F76489E, 0x7F77209E, 0x7F7A489E, 0x7F7B209E, 0x7F7F0078, 
+        0x7F818806, 0x7F828808, 0x7F838806, 0x7F848809, 0x7F858806, 0x7F86880C, 0x7F88880E, 0x7F898810, 
+        0x7F8A8812, 0x7F8B8814, 0x7F8C8816, 0x7F8D880C, 0x7F8E8818, 0x7F8F881A, 0x7F908806, 0x7F918860, 
+        0x7F9E8806, 0x7F9F8837, 0x7FA18861, 0x7FAE8819, 0x7FB0880A, 0x7FB15009, 0x7FB25006, 0x7FB35071, 
+        0x7FB85081, 0x7FB95071, 0x7FCF5081, 0x7FD05071, 0x7FE00078, 0x7FE15071, 0x7FE40078, 0x7FE55071, 
+        0x7FE80078, 0x7FE95071, 0x7FEC0078, 0x7FED5071, 0x7FEF0078, 0x7FF08808, 0x7FF18819, 0x7FF28854, 
+        0x7FF38808, 0x7FF45054, 0x7FF55019, 0x7FF75054, 0x7FF80078, 0x7FFD0141, 0x7FFE0054, 0x7FFF0078, 
+        0x80000071, 0x80060078, 0x80070071, 0x801F0078, 0x80200071, 0x80270078, 0x80280071, 0x802F0078, 
+        0x80400071, 0x807E0078, 0x80800097, 0x80810094, 0x80820078, 0x808400B6, 0x808500B7, 0x808600B8, 
+        0x808700B9, 0x808800B0, 0x808900BA, 0x808A00BB, 0x808B00BC, 0x808C00BD, 0x808D0142, 0x808E0143, 
+        0x808F0144, 0x80900145, 0x809100B1, 0x80920146, 0x80930147, 0x80940148, 0x80950149, 0x8096014A, 
+        0x8097014B, 0x8098014C, 0x8099014D, 0x809A0078, 0x809C0094, 0x80A0014E, 0x80A1014F, 0x80A20150, 
+        0x80A30151, 0x80A40152, 0x80A50150, 0x80A60153, 0x80A70151, 0x80A80154, 0x80A90155, 0x80AA0156, 
+        0x80AB0157, 0x80AC014F, 0x80AE0158, 0x80B00154, 0x80B30150, 0x80B50155, 0x80B60153, 0x80B90151, 
+        0x80BA0150, 0x80BB005F, 0x80BD0054, 0x80C500C3, 0x80C60078, 0x81800071, 0x819000AD, 0x819100B0, 
+        0x81920078, 0x81980071, 0x81A50159, 0x81A60078, 0x81C00071, 0x81CF0078, 0x81D00071, 0x81E20078, 
+        0x81E40071, 0x81E80094, 0x81E90158, 0x81EA015A, 0x81EB0078, 0x8200015B, 0x8214015C, 0x82280071, 
+        0x824F0078, 0x825000A8, 0x825100A9, 0x825200AA, 0x825300AB, 0x825400AC, 0x82550078, 0x8400009B, 
+        0x84030078, 0x8404009B, 0x841B0078, 0x841C009B, 0x841D0078, 0x841E009B, 0x841F0078, 0x8500009B, 
+        0x85010083, 0x85020078, 0x85030083, 0x85040078, 0x85060083, 0x8508009B, 0x850A0078, 0x850B009B, 
+        0x850C0078, 0x850D009B, 0x851A0078, 0x851C0083, 0x851E0078, 0x8520015D, 0x8521015E, 0x8522015F, 
+        0x85230160, 0x85240078, 0x8528009A, 0x852D0078, 0xE8000094, 0xE87B0078, 0xE8800094, 0xE8940078, 
+        0xE8950094, 0xE8AF0894, 0xE8B300A7, 0xE8B40083, 0xE8B50094, 0xE8B700A7, 0xE8BA0057, 0xE8BE0083, 
+        0xE8C20094, 0xE8C30083, 0xE8C60094, 0xE8D50083, 0xE8D70094, 0xE8DE0894, 0xE8E10094, 0xE8EF0078, 
+        0xE9000054, 0xE9210083, 0xE9230078, 0xE9800054, 0xE9AC0078, 0xEA002877, 0xEA0D2855, 0xEA1A2877, 
+        0xEA272855, 0xEA342877, 0xEA412855, 0xEA4E2877, 0xEA500078, 0xEA512877, 0xEA520078, 0xEA532877, 
+        0xEA540078, 0xEA552877, 0xEA5B2855, 0xEA5D0078, 0xEA5F2855, 0xEA620078, 0xEA632855, 0xEA682877, 
+        0xEA752855, 0xEA822877, 0xEA830078, 0xEA842877, 0xEA860078, 0xEA872877, 0xEA8F2855, 0xEA9C2877, 
+        0xEA9D0078, 0xEA9E2877, 0xEAA40078, 0xEAA52877, 0xEAA92855, 0xEAB62877, 0xEAC32855, 0xEAD02877, 
+        0xEADD2855, 0xEAEA2877, 0xEAF72855, 0xEB042877, 0xEB112855, 0xEB1E2877, 0xEB2B2855, 0xEB382877, 
+        0xEB452855, 0xEB530078, 0xEB542877, 0xEB612855, 0xEB712877, 0xEB7E2855, 0xEB8E2877, 0xEB9B2855, 
+        0xEBAB2877, 0xEBB82855, 0xEBC82877, 0xEBD52855, 0xEBE50078, 0xEBE7280E, 0xEBE82810, 0xEBE92812, 
+        0xEBEA2814, 0xEBEB2816, 0xEBEC280E, 0xEBED2810, 0xEBEE2812, 0xEBEF2814, 0xEBF02816, 0xEBF1280E, 
+        0xEBF22810, 0xEBF32812, 0xEBF42814, 0xEBF52816, 0xEBF6280E, 0xEBF72810, 0xEBF82812, 0xEBF92814, 
+        0xEBFA2816, 0xEBFB280E, 0xEBFC2810, 0xEBFD2812, 0xEBFE2814, 0xEBFF2816, 0xEC000078
+    };
+
+    static const uint32_t a1[] = {
+        0x00000071, 0x536C0078, 0x7C000871, 0x7D0F0078
+    };
+
+    static const uint32_t a7[] = {
+        0x00100057, 0x00400078, 0x00800083, 0x00F80078, 0x8000013F, 0xFFFF0078
+    };
+
+    static const uint32_t a8[] = {
+        0x0000013F, 0x7FFF0078
+    };
+
+    static const uint32_t a16[] = {
+        0x00800865, 0x00880065, 0x00890865, 0x00930065, 0x00940865, 0x00980161, 0x00991065, 0x009A0865, 
+        0x009C0863, 0x009F1063, 0x00A00063, 0x00A10863, 0x00A41055, 0x00A50065, 0x00A60865, 0x00A90065, 
+        0x00AA0865, 0x00B30065, 0x00B40865, 0x00BC0863, 0x00BF1162, 0x00C00163, 0x00C10065, 0x00C30063, 
+        0x00C40068, 0x00C50063, 0x00C60055, 0x00C70164, 0x00C80063, 0x00C90068, 0x00CA0165, 0x00CB0166, 
+        0x00CC0065, 0x00CD0055, 0x00CE0167, 0x00CF0168, 0x00D00865, 0x00D10065, 0x00D30063, 0x00D4006F, 
+        0x00D50055, 0x00D60065, 0x00D70863, 0x00D80070, 0x00D90063, 0x00DB0169, 0x00DC0065, 0x00DD0071, 
+        0x00DE0065, 0x00DF016A, 0x00E00071, 0x00E21074, 0x00E31072, 0x00E41073, 0x00E51074, 0x00E60863, 
+        0x00EE016B, 0x00EF0865, 0x00F20065, 0x00F30865, 0x00F81072, 0x00F91073, 0x00FA0865, 0x00FB016C, 
+        0x00FC0865, 0x010E0065, 0x010F0865, 0x01100055, 0x01110065, 0x01130865, 0x011A0055, 0x011D0063, 
+        0x011E016D, 0x011F0055, 0x0120016E, 0x01210078, 0x01280055, 0x0129016F, 0x012A0055, 0x012B007A, 
+        0x012C0170, 0x012D0171, 0x012E0055, 0x01310172, 0x01320055, 0x01340173, 0x01350055, 0x01370173, 
+        0x01380055, 0x013A0174, 0x013B0055, 0x0141007D, 0x01420055, 0x0145007E, 0x01460055, 0x01587881, 
+        0x015C0082, 0x015D0081, 0x01610037, 0x01630082, 0x01680081, 0x01690037, 0x016C1037, 0x016F0037, 
+        0x01707881, 0x01720037, 0x01800083, 0x01A00883, 0x01A20175, 0x01A30083, 0x01B80078, 0x01BA0037, 
+        0x01BB0078, 0x01C20837, 0x01C30806, 0x01C40885, 0x01C50078, 0x01C70887, 0x01C80060, 0x01D50860, 
+        0x01D60889, 0x01D80061, 0x01E50861, 0x01E6088C, 0x01E70078, 0x01E81176, 0x01E90877, 0x01EA1177, 
+        0x01EB0055, 0x01EC0065, 0x01F81093, 0x01F90055, 0x01FA1178, 0x01FB0063, 0x01FC10D8, 0x01FD0065, 
+        0x01FE0077, 0x02000892, 0x02020092, 0x02030892, 0x02040092, 0x02060892, 0x02070092, 0x02080060, 
+        0x020C0860, 0x020D0060, 0x02180061, 0x021C0861, 0x021D0061, 0x02280893, 0x022A0093, 0x022B0893, 
+        0x022C0093, 0x022E0893, 0x022F0093, 0x02300065, 0x023B0865, 0x023C0065, 0x02410083, 0x02430078, 
+        0x02440095, 0x02450065, 0x02600863, 0x02610063, 0x02670078, 0x02680865, 0x026A0065, 0x026B0865, 
+        0x026C0065, 0x026D0865, 0x02700065, 0x02710865, 0x02740065, 0x02750865, 0x027B0065, 0x027C0865, 
+        0x027D0078, 0x02800065, 0x02880078, 0x02980096, 0x02AB0078, 0x02AC0081, 0x02AD0097, 0x02B00098, 
+        0x02C31055, 0x02C40097, 0x02C50078, 0x02C80083, 0x02E1009A, 0x02E20083, 0x02E40078, 0x02E8009B, 
+        0x02F50078, 0x02F8009B, 0x02F9009A, 0x02FA0078, 0x0300009C, 0x03020078, 0x03050140, 0x0306009D, 
+        0x03070054, 0x03080083, 0x030B0078, 0x030D009D, 0x030E0078, 0x030F009D, 0x0310009E, 0x0311089E, 
+        0x0313009E, 0x031D0078, 0x0320009E, 0x03250083, 0x032F0078, 0x03300179, 0x0331017A, 0x0332017B, 
+        0x0333017C, 0x0334017D, 0x033500A5, 0x0336009D, 0x0337009E, 0x033A109E, 0x033C009E, 0x0369089E, 
+        0x036A009E, 0x036B0083, 0x036E009C, 0x036F0083, 0x0372009F, 0x03730083, 0x03740054, 0x03750083, 
+        0x0377009E, 0x0378000F, 0x03790011, 0x037A0013, 0x037B0015, 0x037C0017, 0x037D009E, 0x037E00A6, 
+        0x037F009E, 0x0380009D, 0x03870057, 0x03880083, 0x0389009E, 0x03980083, 0x03A50078, 0x03A6009E, 
+        0x03B70078, 0x03C0009E, 0x03D30083, 0x03D8009E, 0x03D90078, 0x04800083, 0x048100A7, 0x04820071, 
+        0x04940871, 0x04950071, 0x04980871, 0x04990071, 0x049D0078, 0x049E0071, 0x049F00A7, 0x04A00083, 
+        0x04A400A7, 0x04A60083, 0x04A70078, 0x04A80083, 0x04AA0078, 0x04AC0871, 0x04B00071, 0x04B10083, 
+        0x04B20097, 0x04B3017E, 0x04B4017F, 0x04B50180, 0x04B60181, 0x04B70182, 0x04B80078, 0x04BE0071, 
+        0x04BF0078, 0x04C00083, 0x04C100A7, 0x04C20071, 0x04C60078, 0x04C70071, 0x04C80078, 0x04C90071, 
+        0x04D40078, 0x04D50071, 0x04D80078, 0x04DB0071, 0x04DD0078, 0x04DE0071, 0x04DF00A7, 0x04E00083, 
+        0x04E20078, 0x04E300A7, 0x04E40078, 0x04E508A7, 0x04E60083, 0x04E70078, 0x04EB00A7, 0x04EC0078, 
+        0x04EE0871, 0x04F00071, 0x04F10083, 0x04F20078, 0x04F3017E, 0x04F4017F, 0x04F50180, 0x04F60181, 
+        0x04F70182, 0x04F80071, 0x04F90008, 0x04FA00B6, 0x04FB00B7, 0x04FC0183, 0x04FD0078, 0x05000083, 
+        0x050100A7, 0x05020071, 0x05050078, 0x05070071, 0x05080078, 0x05090071, 0x05140078, 0x05150071, 
+        0x05180078, 0x05190871, 0x051A0071, 0x051B0078, 0x051C0071, 0x051D0078, 0x051F00A7, 0x05200083, 
+        0x05210078, 0x05230083, 0x05240078, 0x05250083, 0x05270078, 0x052C0871, 0x052E0078, 0x0533017E, 
+        0x0534017F, 0x05350180, 0x05360181, 0x05370182, 0x05380083, 0x05390071, 0x053A0078, 0x05400083, 
+        0x054100A7, 0x05420071, 0x05540078, 0x05550071, 0x05580078, 0x05590071, 0x055D0078, 0x055E0071, 
+        0x055F00A7, 0x05600083, 0x056400A7, 0x05660083, 0x05670078, 0x05700071, 0x05710083, 0x05720078, 
+        0x0573017E, 0x0574017F, 0x05750180, 0x05760181, 0x05770182, 0x05780008, 0x05790078, 0x05800083, 
+        0x058100A7, 0x05820071, 0x05860078, 0x05870071, 0x05880078, 0x05890071, 0x05940078, 0x05950071, 
+        0x05980078, 0x05990071, 0x059D0078, 0x059E0071, 0x059F0083, 0x05A20078, 0x05A300A7, 0x05A40078, 
+        0x05A508A7, 0x05A60083, 0x05A70078, 0x05AB00A7, 0x05AC0078, 0x05AE0871, 0x05AF0071, 0x05B10078, 
+        0x05B3017E, 0x05B4017F, 0x05B50180, 0x05B60181, 0x05B70182, 0x05B80071, 0x05B90078, 0x05C10071, 
+        0x05C50078, 0x05C70071, 0x05C80078, 0x05C90071, 0x05CB0078, 0x05CC0071, 0x05CD0078, 0x05CF0071, 
+        0x05D00078, 0x05D10071, 0x05D20078, 0x05D40071, 0x05D50078, 0x05D70071, 0x05DD0078, 0x05DF00A7, 
+        0x05E10078, 0x05E300A7, 0x05E40078, 0x05E508A7, 0x05E60083, 0x05E70078, 0x05EB00A7, 0x05EC0078, 
+        0x05F3017E, 0x05F4017F, 0x05F50180, 0x05F60181, 0x05F70182, 0x05F80184, 0x05F90054, 0x05FC0008, 
+        0x05FD0078, 0x060000A7, 0x06020071, 0x06060078, 0x06070071, 0x06080078, 0x06090071, 0x06140078, 
+        0x06150071, 0x061D0078, 0x061F0083, 0x062000A7, 0x06220078, 0x06230083, 0x06240078, 0x06250083, 
+        0x06270078, 0x062A0083, 0x062B0078, 0x06300071, 0x06310078, 0x0633017E, 0x0634017F, 0x06350180, 
+        0x06360181, 0x06370182, 0x06380078, 0x064100A7, 0x06420071, 0x06460078, 0x06470071, 0x06480078, 
+        0x06490071, 0x06540078, 0x06550071, 0x065D0078, 0x065E0071, 0x065F00B2, 0x066000A7, 0x06620078, 
+        0x066308A7, 0x06640078, 0x066508A7, 0x06660083, 0x06670078, 0x066A00A7, 0x066B0078, 0x06700071, 
+        0x06710078, 0x0673017E, 0x0674017F, 0x06750180, 0x06760181, 0x06770182, 0x06780078, 0x068100A7, 
+        0x06820071, 0x06860078, 0x06870071, 0x06880078, 0x06890071, 0x06940078, 0x06950071, 0x069D0078, 
+        0x069F00A7, 0x06A00083, 0x06A20078, 0x06A300A7, 0x06A40078, 0x06A508A7, 0x06A60083, 0x06A70078, 
+        0x06AB00A7, 0x06AC0078, 0x06B00071, 0x06B10078, 0x06B3017E, 0x06B4017F, 0x06B50180, 0x06B60181, 
+        0x06B70182, 0x06B80078, 0x06C100A7, 0x06C20071, 0x06CB0078, 0x06CD0071, 0x06DF0078, 0x06E00071, 
+        0x06E30078, 0x06E700A7, 0x06E90083, 0x06EA0078, 0x06EC00A7, 0x06EE08A7, 0x06EF00A7, 0x06F00078, 
+        0x06F900A7, 0x06FA0078, 0x07000071, 0x07180083, 0x07191071, 0x071A0083, 0x071D0078, 0x071F0008, 
+        0x07200071, 0x07230083, 0x07270097, 0x0728017E, 0x0729017F, 0x072A0180, 0x072B0181, 0x072C0182, 
+        0x072D0097, 0x072E0078, 0x07400071, 0x07410078, 0x07430071, 0x07440078, 0x07460071, 0x07470078, 
+        0x074A0071, 0x07540078, 0x07550071, 0x07580083, 0x07591071, 0x075A0083, 0x075E0071, 0x075F0078, 
+        0x07600071, 0x07620078, 0x07640083, 0x07670078, 0x0768017E, 0x0769017F, 0x076A0180, 0x076B0181, 
+        0x076C0182, 0x076D0078, 0x076E1071, 0x076F0078, 0x07800094, 0x07820097, 0x07890094, 0x078C0083, 
+        0x078D0094, 0x0790017E, 0x0791017F, 0x07920180, 0x07930181, 0x07940182, 0x079500B3, 0x079A0083, 
+        0x079D00BF, 0x079F00A7, 0x07A00071, 0x07A10871, 0x07A20071, 0x07A60871, 0x07A70071, 0x07AB0871, 
+        0x07AC0071, 0x07B40871, 0x07B50078, 0x07B80083, 0x07B90883, 0x07BB1083, 0x07BD0083, 0x07BF00A7, 
+        0x07C00883, 0x07C10083, 0x07C20097, 0x07C30083, 0x07C40071, 0x07C60078, 0x07C80083, 0x07C90883, 
+        0x07CA0083, 0x07CE0883, 0x07CF0083, 0x07D30883, 0x07D40083, 0x07DC0883, 0x07DD0083, 0x07DE0078, 
+        0x07DF0094, 0x07E60078, 0x07E70094, 0x07E80097, 0x07E90078, 0x08000071, 0x08150078, 0x08160083, 
+        0x081800A7, 0x08190078, 0x081B0083, 0x081D0078, 0x0820017E, 0x0821017F, 0x08220180, 0x08230181, 
+        0x08240182, 0x08250097, 0x08280071, 0x082B00A7, 0x082C0083, 0x082D0078, 0x085000B5, 0x08630078, 
+        0x08680071, 0x087D0097, 0x087E0078, 0x08800071, 0x08AD0078, 0x08AF0071, 0x08D10078, 0x08D40071, 
+        0x08FD0078, 0x09000071, 0x09240078, 0x09250071, 0x09270078, 0x09280071, 0x092B0078, 0x092D0071, 
+        0x092F0078, 0x09300071, 0x09440078, 0x09450071, 0x09470078, 0x09480071, 0x09580078, 0x09590071, 
+        0x095B0078, 0x095C0071, 0x095F0078, 0x09610071, 0x09630078, 0x09640071, 0x096B0078, 0x096C0071, 
+        0x09880078, 0x09890071, 0x098B0078, 0x098C0071, 0x09AD0078, 0x09AF0083, 0x09B00097, 0x09B400AD, 
+        0x09B500AE, 0x09B6012D, 0x09B7012E, 0x09B8012F, 0x09B90185, 0x09BA0186, 0x09BB0187, 0x09BC0188, 
+        0x09BD0184, 0x09BE0078, 0x09C00071, 0x09C80054, 0x09CD0078, 0x09D00071, 0x09FA0078, 0x0A000071, 
+        0x0B360097, 0x0B370071, 0x0B3B0078, 0x0B400071, 0x0B4D00B4, 0x0B4E0078, 0x0B500071, 0x0B750097, 
+        0x0B770189, 0x0B780078, 0x0B800071, 0x0B860078, 0x0B870071, 0x0B890083, 0x0B8A0078, 0x0B900071, 
+        0x0B990083, 0x0B9A0097, 0x0B9B0078, 0x0BA00071, 0x0BA90083, 0x0BAA0078, 0x0BB00071, 0x0BB60078, 
+        0x0BB70071, 0x0BB80078, 0x0BB90083, 0x0BBA0078, 0x0BC00071, 0x0BDA00C2, 0x0BDB0083, 0x0BDF00A7, 
+        0x0BE40083, 0x0BEA0097, 0x0BEB0081, 0x0BEC0097, 0x0BED0008, 0x0BEE0083, 0x0BEF0078, 0x0BF0017E, 
+        0x0BF1017F, 0x0BF20180, 0x0BF30181, 0x0BF40182, 0x0BF50078, 0x0BF80106, 0x0BF90107, 0x0BFA0108, 
+        0x0BFB0109, 0x0BFC010A, 0x0BFD0078, 0x0C000006, 0x0C050083, 0x0C070078, 0x0C08017E, 0x0C09017F, 
+        0x0C0A0180, 0x0C0B0181, 0x0C0C0182, 0x0C0D0078, 0x0C100071, 0x0C210081, 0x0C220071, 0x0C3C0078, 
+        0x0C400071, 0x0C540083, 0x0C550078, 0x0C800071, 0x0C8E0078, 0x0C900083, 0x0C9100A7, 0x0C930083, 
+        0x0C9400C8, 0x0C960078, 0x0C9800A7, 0x0C9C0083, 0x0C9E0078, 0x0CA20006, 0x0CA3017E, 0x0CA4017F, 
+        0x0CA50180, 0x0CA60181, 0x0CA70182, 0x0CA80071, 0x0CB70078, 0x0CB80071, 0x0CBA0078, 0x0CC00071, 
+        0x0CD50078, 0x0CD800A7, 0x0CE00071, 0x0CE400A7, 0x0CE50078, 0x0CE8017E, 0x0CE9017F, 0x0CEA0180, 
+        0x0CEB0181, 0x0CEC0182, 0x0CED0078, 0x0CEF0006, 0x0CF00054, 0x0D000071, 0x0D0B0083, 0x0D0C00A7, 
+        0x0D0E0078, 0x0D0F0097, 0x0D100078, 0x0E800055, 0x0E967881, 0x0E970081, 0x0E987881, 0x0E9D0081, 
+        0x0E9E7881, 0x0EB17055, 0x0EB50055, 0x0ECD7881, 0x0EE00083, 0x0EE20078, 0x0F000865, 0x0F4B0855, 
+        0x0F4D098A, 0x0F4E0078, 0x0F500865, 0x0F7D0078, 0x0F8008C9, 0x0F8408CA, 0x0F8808C9, 0x0F8B0078, 
+        0x0F8C08CA, 0x0F8F0078, 0x0F9008C9, 0x0F9408CA, 0x0F9808C9, 0x0F9C08CA, 0x0FA008C9, 0x0FA30078, 
+        0x0FA408CA, 0x0FA70078, 0x0FA808C9, 0x0FAC08CA, 0x0FB008C9, 0x0FB408CA, 0x0FB808CB, 0x0FB908CC, 
+        0x0FBB08CD, 0x0FBC08CE, 0x0FBD08CF, 0x0FBE08D0, 0x0FBF0078, 0x0FC008C9, 0x0FC408D1, 0x0FC808C9, 
+        0x0FCC08D1, 0x0FD008C9, 0x0FD408D1, 0x0FD808C9, 0x0FD9098B, 0x0FDA0078, 0x0FDB0855, 0x0FDC08CA, 
+        0x0FDD08D2, 0x0FDE1037, 0x0FE00837, 0x0FE1098B, 0x0FE20078, 0x0FE30855, 0x0FE408D5, 0x0FE60837, 
+        0x0FE808C9, 0x0FE90855, 0x0FEA0078, 0x0FEB0855, 0x0FEC08CA, 0x0FED08D6, 0x0FEE0837, 0x0FF008C9, 
+        0x0FF10855, 0x0FF20890, 0x0FF30855, 0x0FF408CA, 0x0FF508D7, 0x0FF60837, 0x0FF80078, 0x0FF9098B, 
+        0x0FFA0078, 0x0FFB0855, 0x0FFC08D9, 0x0FFD08DA, 0x0FFE0837, 0x0FFF0078, 0x10000805, 0x10011005, 
+        0x10035805, 0x10041005, 0x10050057, 0x1007018C, 0x10085899, 0x10090099, 0x100B1006, 0x100C018D, 
+        0x100D00DB, 0x100E018D, 0x100F00DB, 0x10100006, 0x10121006, 0x10130006, 0x1014018E, 0x1015018F, 
+        0x10160190, 0x10175853, 0x10180007, 0x10191007, 0x101A0006, 0x101B1006, 0x101C0126, 0x101D0006, 
+        0x101F0038, 0x10200006, 0x10220009, 0x10231006, 0x10250006, 0x102B1006, 0x102C0006, 0x102F1005, 
+        0x10300057, 0x10320078, 0x10350057, 0x10387855, 0x10390078, 0x103A7910, 0x103B7911, 0x103C7912, 
+        0x103D780B, 0x103E7809, 0x103F7855, 0x1040705D, 0x1041705B, 0x10427110, 0x10437111, 0x10447112, 
+        0x1045700B, 0x10467009, 0x10470078, 0x10487081, 0x104A0078, 0x10500008, 0x105B0078, 0x10680083, 
+        0x106E0095, 0x10700083, 0x10710095, 0x10720083, 0x10760078, 0x10801054, 0x10831077, 0x10841054, 
+        0x10852877, 0x10872855, 0x10882877, 0x10892855, 0x108A2877, 0x108B0054, 0x108C2877, 0x108F0054, 
+        0x10901054, 0x10910054, 0x10950991, 0x10962877, 0x10972855, 0x10982877, 0x109A1071, 0x109C2855, 
+        0x109D1054, 0x109E2855, 0x109F2877, 0x10A00019, 0x10A22877, 0x10A32855, 0x10A50019, 0x10A60078, 
+        0x10A9305F, 0x10AF3106, 0x10B01192, 0x10B11193, 0x10B21194, 0x10B31195, 0x10B41196, 0x10B51197, 
+        0x10B61198, 0x10B71199, 0x10B8119A, 0x10B9119B, 0x10BA119C, 0x10BB119D, 0x10BC119E, 0x10BD119F, 
+        0x10BE11A0, 0x10BF11A1, 0x10C001A2, 0x10C101A3, 0x10C20078, 0x10C80019, 0x10CA0054, 0x10CD0819, 
+        0x10CE0054, 0x10D10019, 0x10D20054, 0x10E60854, 0x10E70819, 0x10E80054, 0x10FA0019, 0x110000E8, 
+        0x11020019, 0x110408FB, 0x110500FC, 0x11070019, 0x110800E8, 0x11090059, 0x110A01A4, 0x110B0019, 
+        0x110D00E8, 0x11110019, 0x111500E8, 0x111610E8, 0x111800E8, 0x111A0019, 0x111C00E8, 0x111E00FE, 
+        0x111F00E8, 0x112008E8, 0x112101A5, 0x112200E8, 0x112308E8, 0x112500E8, 0x11260019, 0x112900FE, 
+        0x112B0019, 0x112F00E8, 0x11300019, 0x113200FE, 0x11360819, 0x113708FE, 0x113900FE, 0x113A08FE, 
+        0x113B00FE, 0x113C08FE, 0x113D00FE, 0x114008FE, 0x114100FE, 0x114208FE, 0x114300FE, 0x114408FE, 
+        0x114500FE, 0x11460019, 0x114700FD, 0x11490019, 0x115100FE, 0x11520019, 0x115300E8, 0x115401A6, 
+        0x115608E8, 0x115800FE, 0x115C0019, 0x115F00E8, 0x11600019, 0x116400FD, 0x116601A7, 0x11670019, 
+        0x116800FE, 0x11690019, 0x116B00FE, 0x117008FE, 0x117200FE, 0x117508FE, 0x11770019, 0x117800FE, 
+        0x11790102, 0x117A00E8, 0x117B0103, 0x117C00E8, 0x117D0104, 0x117E0105, 0x117F00E8, 0x11800054, 
+        0x118400FE, 0x11860054, 0x119000E8, 0x11910054, 0x11940809, 0x11950054, 0x119B0094, 0x11BD0054, 
+        0x11CA0094, 0x11CB0054, 0x11CD0019, 0x11DA00BF, 0x11DB0054, 0x11EE0078, 0x12000054, 0x12130078, 
+        0x12200054, 0x12250078, 0x123018C4, 0x123118C5, 0x123218C6, 0x123318C7, 0x1234191F, 0x1235191A, 
+        0x1236191B, 0x1237191C, 0x1238191D, 0x1239191E, 0x123A10C4, 0x123B10C5, 0x123C10C6, 0x123D10C7, 
+        0x123E111F, 0x123F111A, 0x1240111B, 0x1241111C, 0x1242111D, 0x1243111E, 0x1244105A, 0x124510E3, 
+        0x124610E4, 0x124710E5, 0x124811A8, 0x124911A9, 0x124A11AA, 0x124B11AB, 0x124C11AC, 0x124D11AD, 
+        0x124E1094, 0x125B1918, 0x12681919, 0x1275010B, 0x1276010C, 0x1277010D, 0x1278010E, 0x1279010F, 
+        0x127A0106, 0x127B0107, 0x127C0108, 0x127D0109, 0x127E010A, 0x127F00C3, 0x12800054, 0x12DB0019, 
+        0x12DC0054, 0x12E00019, 0x12E10054, 0x12FC0019, 0x13000054, 0x13370019, 0x13380054, 0x134E0078, 
+        0x13500054, 0x13590078, 0x13800054, 0x13820078, 0x13830054, 0x13850078, 0x13860054, 0x13A90078, 
+        0x13AC0054, 0x13AF0078, 0x13B00054, 0x13B4000A, 0x13BB00C4, 0x13BC00C5, 0x13BD00C6, 0x13BE00C7, 
+        0x13BF011F, 0x13C000C4, 0x13C100C5, 0x13C200C6, 0x13C300C7, 0x13C4011F, 0x13C500C4, 0x13C600C5, 
+        0x13C700C6, 0x13C800C7, 0x13C9011F, 0x13CA0078, 0x13CC0054, 0x13DF0078, 0x13E00019, 0x13E100FD, 
+        0x13E20009, 0x13E30078, 0x13E80019, 0x13E900E8, 0x13EA00FD, 0x13EB0019, 0x13EE00FD, 0x13EF0019, 
+        0x13F100FE, 0x13F3000A, 0x13F60078, 0x13F80019, 0x14000094, 0x14800019, 0x14C10009, 0x14C601AE, 
+        0x14C701AF, 0x14C80009, 0x14CC0019, 0x14CD00E8, 0x14D80019, 0x14E000FE, 0x14E100E8, 0x14E200FE, 
+        0x14E30019, 0x14E400E8, 0x14E50019, 0x14E700FD, 0x14E90019, 0x14EA00FE, 0x14EB0019, 0x14EC000A, 
+        0x14EE0019, 0x14F000E8, 0x14F30019, 0x14F400E8, 0x14F50019, 0x14FA01B0, 0x14FB00E8, 0x14FC00FE, 
+        0x14FD0019, 0x14FE000A, 0x14FF0019, 0x150500E8, 0x150E0019, 0x150F00E8, 0x15110019, 0x151400E8, 
+        0x151500FD, 0x15170019, 0x151A00FE, 0x151B0019, 0x151E00FE, 0x151F0019, 0x152B00E8, 0x152C0019, 
+        0x153200FE, 0x15330019, 0x153500E8, 0x15380019, 0x153900E8, 0x153A1019, 0x153B0019, 0x153C00FD, 
+        0x153D00E8, 0x153E00FD, 0x154200E8, 0x154500FD, 0x154600E8, 0x154800FD, 0x154E00E8, 0x155000FD, 
+        0x155100E8, 0x15520019, 0x155300FE, 0x155700FD, 0x155800E8, 0x155900FD, 0x155A00E8, 0x155D00FD, 
+        0x156300E8, 0x156600FD, 0x156B0019, 0x157101B1, 0x15730019, 0x157600FE, 0x15770019, 0x157900E8, 
+        0x157A0019, 0x157B00FD, 0x157D00E8, 0x157F0019, 0x15800054, 0x158A0078, 0x16000096, 0x16170078, 
+        0x16180098, 0x162F0078, 0x16400065, 0x16720054, 0x16750078, 0x167C0006, 0x167E005F, 0x167F0006, 
+        0x16800125, 0x16930078, 0x16980071, 0x16B30078, 0x16B77881, 0x16B80078, 0x16C00071, 0x16CB0078, 
+        0x16D00071, 0x16D30078, 0x16D40071, 0x16D70078, 0x16D80071, 0x16DB0078, 0x16DC0071, 0x16DF0078, 
+        0x16E00071, 0x16E30078, 0x16E40071, 0x16E70078, 0x16E80071, 0x16EB0078, 0x16EC0071, 0x16EF0078, 
+        0x17000006, 0x170100E0, 0x17030006, 0x17040126, 0x17050006, 0x170600E0, 0x17070006, 0x170B0099, 
+        0x170C0078, 0x170E00E0, 0x170F0078, 0x17400054, 0x174F1054, 0x17500054, 0x17791054, 0x177A0078, 
+        0x17801054, 0x17EB0078, 0x17F80054, 0x17FE0078, 0x18000006, 0x18020081, 0x180301B2, 0x1804000A, 
+        0x18090054, 0x180A000A, 0x180E00B4, 0x180F00BF, 0x181001B3, 0x181101B4, 0x181201B5, 0x181301B6, 
+        0x181401B7, 0x18150083, 0x18180081, 0x181B0054, 0x181C11B8, 0x181D0081, 0x181E0006, 0x181F0054, 
+        0x18200071, 0x18320871, 0x18350071, 0x18380871, 0x183A0071, 0x183B0871, 0x183D0071, 0x183E0871, 
+        0x183F0071, 0x184B0078, 0x184C0083, 0x184D1037, 0x184E0081, 0x184F8071, 0x18500071, 0x18620871, 
+        0x18650071, 0x18680871, 0x186A0071, 0x186B0871, 0x186D0071, 0x186E0871, 0x186F0071, 0x187B0871, 
+        0x187D0006, 0x187E0081, 0x187F8071, 0x18800078, 0x18820071, 0x18960078, 0x18981071, 0x18C70078, 
+        0x18C80094, 0x18C978B6, 0x18CA78B7, 0x18CB7894, 0x18D00071, 0x18DC0078, 0x18E00054, 0x18E80078, 
+        0x18F80071, 0x19001094, 0x190E1054, 0x190F0078, 0x191010B6, 0x191110B7, 0x191210B8, 0x191310B9, 
+        0x191410B0, 0x19151094, 0x19220078, 0x192819B9, 0x192919BA, 0x192A19BB, 0x192B19BC, 0x192C19BD, 
+        0x192D19BE, 0x192E19BF, 0x192F19C0, 0x19301894, 0x193E1854, 0x193F0094, 0x194018B6, 0x194118B7, 
+        0x194218B8, 0x194318B9, 0x194418B0, 0x19451894, 0x195819C1, 0x195919C2, 0x195A19C3, 0x195B19C4, 
+        0x195C19C5, 0x195D19C6, 0x195E19C7, 0x195F19C8, 0x19601094, 0x19666854, 0x19681894, 0x197F0078, 
+        0x19806894, 0x19AC1094, 0x19B86894, 0x19BB6854, 0x19BD6894, 0x19EF6854, 0x19F01094, 0x19FF6854, 
+        0x1A000071, 0x26DB0078, 0x26E00054, 0x27000071, 0x4FDE0078, 0x50000071, 0x500A0081, 0x500B0071, 
+        0x52460078, 0x52480054, 0x52630078, 0x53800037, 0x538B0078, 0x54000071, 0x54050083, 0x54060071, 
+        0x541100A7, 0x54120083, 0x541300A7, 0x54140054, 0x54160078, 0x56000071, 0x6BD20078, 0x6C00013E, 
+        0x7000013F, 0x7C800871, 0x7D070071, 0x7D0A0871, 0x7D0F0071, 0x7D120871, 0x7D130071, 0x7D150871, 
+        0x7D170078, 0x7D180871, 0x7D350078, 0x7D380871, 0x7D6D0078, 0x7D801055, 0x7D830078, 0x7D891055, 
+        0x7D8C0078, 0x7D8E089B, 0x7D90289B, 0x7D94280B, 0x7D95089B, 0x7D9B0078, 0x7D9C089B, 0x7D9E0078, 
+        0x7DA0089B, 0x7DA20078, 0x7DA3089B, 0x7DA7109B, 0x7DA8209E, 0x7DAA489E, 0x7DAB209E, 0x7DAC489E, 
+        0x7DAD209E, 0x7DAE489E, 0x7DAF209E, 0x7DB0489E, 0x7DB1209E, 0x7DB2489E, 0x7DB3209E, 0x7DB4489E, 
+        0x7DB5209E, 0x7DB6489E, 0x7DB7209E, 0x7DB8489E, 0x7DB9209E, 0x7DBA489E, 0x7DBB209E, 0x7DBC489E, 
+        0x7DBD209E, 0x7DBE489E, 0x7DBF209E, 0x7DC0489E, 0x7DC1209E, 0x7DC8489E, 0x7DC9209E, 0x7DCA489E, 
+        0x7DCB209E, 0x7DCC489E, 0x7DCD209E, 0x7DCE489E, 0x7DCF209E, 0x7DD1489E, 0x7DD2209E, 0x7DD4489E, 
+        0x7DD5209E, 0x7DD6489E, 0x7DD7209E, 0x7DD90078, 0x7DE9409E, 0x7DEA389E, 0x7DEB409E, 0x7DEF209E, 
+        0x7DF3489E, 0x7DF5209E, 0x7DFC409E, 0x7DFD389E, 0x7DFE209E, 0x7DFF489E, 0x7E00409E, 0x7E32209E, 
+        0x7E4B389E, 0x7E6F489E, 0x7E7A409E, 0x7E88209E, 0x7E96389E, 0x7E9A489E, 0x7E9E409E, 0x7E9F00BF, 
+        0x7EA00078, 0x7EA8209E, 0x7EA9389E, 0x7EAD209E, 0x7EAE389E, 0x7EAF209E, 0x7EB0389E, 0x7EB3209E, 
+        0x7EB5389E, 0x7EB7209E, 0x7EB9389E, 0x7EBA209E, 0x7EBB389E, 0x7EBC209E, 0x7EBE389E, 0x7EBF209E, 
+        0x7EC1389E, 0x7EC2209E, 0x7EC4389E, 0x7EC5209E, 0x7EC6389E, 0x7EC80078, 0x7EC9389E, 0x7ECB209E, 
+        0x7ECE389E, 0x7ECF209E, 0x7EDA389E, 0x7EDB209E, 0x7EE1389E, 0x7EE3209E, 0x7EE40078, 0x7EF8409E, 
+        0x7EFE0054, 0x7EFF0078, 0x7F000083, 0x7F088006, 0x7F0B80B4, 0x7F0C8006, 0x7F0D0078, 0x7F100083, 
+        0x7F120078, 0x7F188099, 0x7F198038, 0x7F1A80B4, 0x7F220006, 0x7F2380B4, 0x7F241006, 0x7F261038, 
+        0x7F286006, 0x7F290078, 0x7F2A600C, 0x7F2B6006, 0x7F2C60B4, 0x7F2F6007, 0x7F306006, 0x7F31600D, 
+        0x7F326019, 0x7F330078, 0x7F346008, 0x7F356006, 0x7F360078, 0x7F38489E, 0x7F39009E, 0x7F3A0078, 
+        0x7F3B489E, 0x7F40409E, 0x7F45389E, 0x7F46409E, 0x7F48389E, 0x7F49409E, 0x7F4B389E, 0x7F4C409E, 
+        0x7F4D389E, 0x7F4E409E, 0x7F4F389E, 0x7F50409E, 0x7F51389E, 0x7F52409E, 0x7F53389E, 0x7F54409E, 
+        0x7F59389E, 0x7F5A409E, 0x7F5B389E, 0x7F5C409E, 0x7F5D389E, 0x7F5E409E, 0x7F5F389E, 0x7F60409E, 
+        0x7F61389E, 0x7F62409E, 0x7F63389E, 0x7F64409E, 0x7F65389E, 0x7F66409E, 0x7F67389E, 0x7F68409E, 
+        0x7F69389E, 0x7F6A409E, 0x7F6B389E, 0x7F6C409E, 0x7F6D389E, 0x7F6E409E, 0x7F6F389E, 0x7F70409E, 
+        0x7F71389E, 0x7F72409E, 0x7F73389E, 0x7F74409E, 0x7F75389E, 0x7F76409E, 0x7F79389E, 0x7F7A409E, 
+        0x7F7E0078, 0x7F7F0057, 0x7F808806, 0x7F818807, 0x7F838806, 0x7F84880A, 0x7F85880B, 0x7F86880D, 
+        0x7F87880C, 0x7F88880F, 0x7F898811, 0x7F8A8813, 0x7F8B8815, 0x7F8C8817, 0x7F8D8806, 0x7F8E8819, 
+        0x7F8F8806, 0x7F908860, 0x7F9D8835, 0x7F9E8836, 0x7F9F8838, 0x7FA08861, 0x7FAD8835, 0x7FAE8836, 
+        0x7FAF8809, 0x7FB05006, 0x7FB1500A, 0x7FB25006, 0x7FB35071, 0x7FCF5081, 0x7FD05071, 0x7FDF0078, 
+        0x7FE15071, 0x7FE40078, 0x7FE55071, 0x7FE80078, 0x7FE95071, 0x7FEC0078, 0x7FED5071, 0x7FEE0078, 
+        0x7FF08808, 0x7FF18837, 0x7FF28808, 0x7FF30078, 0x7FF45019, 0x7FF65054, 0x7FF70078, 0x7FFC0141, 
+        0x7FFE0054, 0x7FFF0078, 0x80000071, 0x80130078, 0x80140071, 0x801D0078, 0x801E0071, 0x80270078, 
+        0x80280071, 0x802F0078, 0x80400071, 0x807D0078, 0x80800006, 0x80810078, 0x808300AD, 0x808400AE, 
+        0x8085012D, 0x8086012E, 0x8087012F, 0x80880185, 0x80890186, 0x808A0187, 0x808B0188, 0x808C0184, 
+        0x808D01C9, 0x808E01CA, 0x808F01CB, 0x809001CC, 0x809101CD, 0x809201CE, 0x809301CF, 0x809401D0, 
+        0x809500BE, 0x809601D1, 0x809701D2, 0x809801D3, 0x809901D4, 0x809A0078, 0x809B0094, 0x80A0014E, 
+        0x80A10152, 0x80A20153, 0x80A30157, 0x80A40154, 0x80A50155, 0x80A60156, 0x80A70152, 0x80A80150, 
+        0x80A90153, 0x80AA01D5, 0x80AB0154, 0x80AC014F, 0x80AD0158, 0x80AF0152, 0x80B00154, 0x80B201D6, 
+        0x80B30150, 0x80B501D7, 0x80B60153, 0x80B80156, 0x80B90152, 0x80BA005F, 0x80BC0054, 0x80C50078, 
+        0x81800071, 0x818F0078, 0x8190012D, 0x819100BB, 0x81920078, 0x81980071, 0x81A50078, 0x81C00071, 
+        0x81CF0097, 0x81D00071, 0x81E20078, 0x81E40071, 0x81E8014F, 0x81E90154, 0x81EA0155, 0x81EB0078, 
+        0x8200015B, 0x8214015C, 0x82280071, 0x824F0078, 0x8250017E, 0x8251017F, 0x82520180, 0x82530181, 
+        0x82540182, 0x82550078, 0x8400009B, 0x84030078, 0x8405009B, 0x841C0078, 0x841F009B, 0x84200078, 
+        0x85000083, 0x85030078, 0x85060083, 0x8508009B, 0x851A0078, 0x851C0083, 0x851D0078, 0x851F0083, 
+        0x852001D8, 0x852101D9, 0x852201DA, 0x852301DB, 0x85240078, 0x8528009A, 0x852C0078, 0xE8000094, 
+        0xE87B0078, 0xE8800094, 0xE8930078, 0xE8950094, 0xE8AF0894, 0xE8B200A7, 0xE8B30083, 0xE8B50094, 
+        0xE8B600A7, 0xE8B90057, 0xE8BD0083, 0xE8C10094, 0xE8C20083, 0xE8C60094, 0xE8D50083, 0xE8D70094, 
+        0xE8DD0894, 0xE8E00094, 0xE8EF0078, 0xE9000054, 0xE9210083, 0xE9220054, 0xE9230078, 0xE9800054, 
+        0xE9AB0078, 0xEA002877, 0xEA0D2855, 0xEA1A2877, 0xEA272855, 0xEA2A0078, 0xEA2B2855, 0xEA342877, 
+        0xEA412855, 0xEA4E0078, 0xEA4F2877, 0xEA500078, 0xEA522877, 0xEA530078, 0xEA542877, 0xEA560078, 
+        0xEA572877, 0xEA5B2855, 0xEA682877, 0xEA752855, 0xEA822877, 0xEA850078, 0xEA862877, 0xEA8A0078, 
+        0xEA8B2877, 0xEA8E0078, 0xEA8F2855, 0xEA9C2877, 0xEA9F0078, 0xEAA02877, 0xEAA20078, 0xEAA52877, 
+        0xEAA80078, 0xEAA92855, 0xEAB62877, 0xEAC32855, 0xEAD02877, 0xEADD2855, 0xEAEA2877, 0xEAF72855, 
+        0xEB042877, 0xEB112855, 0xEB1E2877, 0xEB2B2855, 0xEB382877, 0xEB452855, 0xEB530078, 0xEB542877, 
+        0xEB6029DC, 0xEB612855, 0xEB6D29DC, 0xEB6E2855, 0xEB712877, 0xEB7D29DC, 0xEB7E2855, 0xEB8A29DC, 
+        0xEB8B2855, 0xEB8E2877, 0xEB9A29DC, 0xEB9B2855, 0xEBA729DC, 0xEBA82855, 0xEBAB2877, 0xEBB729DC, 
+        0xEBB82855, 0xEBC429DC, 0xEBC52855, 0xEBC82877, 0xEBD429DC, 0xEBD52855, 0xEBE129DC, 0xEBE22855, 
+        0xEBE50078, 0xEBE7280F, 0xEBE82811, 0xEBE92813, 0xEBEA2815, 0xEBEB2817, 0xEBEC280F, 0xEBED2811, 
+        0xEBEE2813, 0xEBEF2815, 0xEBF02817, 0xEBF1280F, 0xEBF22811, 0xEBF32813, 0xEBF42815, 0xEBF52817, 
+        0xEBF6280F, 0xEBF72811, 0xEBF82813, 0xEBF92815, 0xEBFA2817, 0xEBFB280F, 0xEBFC2811, 0xEBFD2813, 
+        0xEBFE2815, 0xEBFF2817, 0xEC000078
+    };
+
+    static const uint32_t a17[] = {
+        0x00000071, 0x536B0078, 0x7C000871, 0x7D0F0078
+    };
+
+    static const uint32_t a23[] = {
+        0x00000057, 0x00010078, 0x00100057, 0x00400078, 0x00800083, 0x00F80078, 0x8000013F, 0xFFFF0078
+    };
+
+    static const uint32_t a24[] = {
+        0x0000013F, 0x7FFF0078
+    };
+
+
+    // The full set of all arrays to be searched.
+    static const Range FULL_DATA[] = {
+        {sizeof(a0)/sizeof(uint32_t), a0},
+        {sizeof(a1)/sizeof(uint32_t), a1},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {sizeof(a7)/sizeof(uint32_t), a7},
+        {sizeof(a8)/sizeof(uint32_t), a8},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {sizeof(a16)/sizeof(uint32_t), a16},
+        {sizeof(a17)/sizeof(uint32_t), a17},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {sizeof(a23)/sizeof(uint32_t), a23},
+        {sizeof(a24)/sizeof(uint32_t), a24},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0}
+    };
+
+    // Array of uppercase differences
+    static const short UCDIFF[] = {
+            0,   -32,   743,   121,    -1,  -232,  -300,    97, 
+          163,   130,    56,    -2,   -79,  -210,  -206,  -205, 
+         -202,  -203,  -207,  -209,  -211,  -213,  -214,  -218, 
+         -217,  -219,   -83,    84,   -38,   -37,   -31,   -64, 
+          -63,   -62,   -57,   -47,   -54,   -86,   -80,     7, 
+          -96,   -48,   -59,     8,    74,    86,   100,   128, 
+          112,   126,     9, -7205,   -16,   -26, -7264,   -40
+    };
+
+    // Array of lowercase differences
+    static const short LCDIFF[] = {
+            0,    32,     1,  -199,  -121,   210,   206,   205, 
+           79,   202,   203,   207,   211,   209,   213,   214, 
+          218,   217,   219,     2,   -97,   -56,  -130,  -163, 
+           83,    38,    37,    64,    63,   -60,    -7,    80, 
+           48,  7264,    -8,   -74,    -9,   -86,  -100,  -112, 
+         -128,  -126, -7517, -8383, -8262,    16,    26,    40
+    };
+
+    // Array of titlecase differences
+    static const short TCDIFF[] = {
+            3,     1,     0,    -1
+    };
+
+    // Array of mirrored character differences
+    static const short MIRROR_DIFF[] = {
+            0,     1,    -1,     2,    -2,    16,   -16,     3, 
+           -3,  2016,   138,  1824,  2104,  2108,  2106,  -138, 
+            8,     7,    -8,    -7, -1824, -2016, -2104, -2106, 
+        -2108
+    };
+
+   // Array of all possible numeric values
+   static const int NUMERICS[] = {
+            -1,      0,      1,      2,      3,      4,      5,      6, 
+             7,      8,      9,     10,     11,     12,     13,     14, 
+            15,     16,     17,     18,     19,     20,     21,     22, 
+            23,     24,     25,     26,     27,     28,     29,     30, 
+            31,     32,     33,     34,     35,     -2,    100,   1000, 
+            40,     50,     60,     70,     80,     90,  10000,    500, 
+          5000,     36,     37,     38,     39,     41,     42,     43, 
+            44,     45,     46,     47,     48,     49,    200,    300, 
+           400,    600,    700,    800,    900,   2000,   3000,   4000, 
+          6000,   7000,   8000,   9000,  20000,  30000,  40000,  50000, 
+         60000,  70000,  80000,  90000
+    };
+
+    // All possible packed data values, no duplicates
+    static const uint32_t PACKED_DATA[] = {
+        0x00000000, 0x0000012F, 0x0000016F, 0x0000014F, 0x0000018F, 0x0000018C, 0x000001B8, 0x000000B8, 
+        0x000000BA, 0x020005B5, 0x040005B6, 0x00000099, 0x000000F8, 0x00000094, 0x02000069, 0x04000069, 
+        0x06000069, 0x08000069, 0x0A000069, 0x0C000069, 0x0E000069, 0x10000069, 0x12000069, 0x14000069, 
+        0x060005B9, 0x000001B9, 0x080005B9, 0x16020001, 0x18020001, 0x1A020001, 0x1C020001, 0x1E020001, 
+        0x20020001, 0x22020001, 0x24020001, 0x26020001, 0x28020001, 0x2A020001, 0x2C020001, 0x2E020001, 
+        0x30020001, 0x32020001, 0x34020001, 0x36020001, 0x38020001, 0x3A020001, 0x3C020001, 0x3E020001, 
+        0x40020001, 0x42020001, 0x44020001, 0x46020001, 0x48020001, 0x060005B5, 0x080005B6, 0x000001BB, 
+        0x000001B7, 0x16000802, 0x18000802, 0x1A000802, 0x1C000802, 0x1E000802, 0x20000802, 0x22000802, 
+        0x24000802, 0x26000802, 0x28000802, 0x2A000802, 0x2C000802, 0x2E000802, 0x30000802, 0x32000802, 
+        0x34000802, 0x36000802, 0x38000802, 0x3A000802, 0x3C000802, 0x3E000802, 0x40000802, 0x42000802, 
+        0x44000802, 0x46000802, 0x48000802, 0x000000EC, 0x000001BC, 0x00000002, 0x0A0005BD, 0x00000130, 
+        0x000000BC, 0x000000B9, 0x0600006B, 0x0800006B, 0x00001002, 0x0400006B, 0x0C0005BE, 0x4A0001AB, 
+        0x00020001, 0x00000802, 0x00001802, 0x00040001, 0x00060001, 0x00002002, 0x00080001, 0x000C0001, 
+        0x000E0001, 0x00100001, 0x00140001, 0x00160001, 0x00180001, 0x00004002, 0x00004802, 0x00200001, 
+        0x00220001, 0x00000005, 0x00A60001, 0x01805802, 0x01042003, 0x00280001, 0x002C0001, 0x00000001, 
+        0x00000000, 0x00007002, 0x00007802, 0x00009802, 0x0000A802, 0x0000B802, 0x0000C002, 0x0000C802, 
+        0x0000D002, 0x00000004, 0x000001A4, 0x00000106, 0x00320001, 0x00340001, 0x00360001, 0x00380001, 
+        0x0000E002, 0x0000E802, 0x0000F002, 0x0000F802, 0x00010002, 0x00010802, 0x00012002, 0x00012802, 
+        0x00013802, 0x003A0001, 0x003E0001, 0x00013002, 0x0000001C, 0x00000107, 0x00400001, 0x00000018, 
+        0x00014802, 0x000001B4, 0x00000038, 0x00000025, 0x00000050, 0x00000058, 0x00000045, 0x00000044, 
+        0x020000C9, 0x060000C9, 0x0A0000C9, 0x0E0000C9, 0x120000C9, 0x000000D8, 0x0000005C, 0x00000008, 
+        0x02000009, 0x06000009, 0x0A000009, 0x0E000009, 0x12000009, 0x0400000B, 0x0800000B, 0x0000000B, 
+        0x1600000B, 0x4E00000B, 0x00000006, 0x4A00000B, 0x000001B5, 0x00420001, 0x0600000B, 0x0A00000B, 
+        0x0E00000B, 0x1200000B, 0x3E00000B, 0x5200000B, 0x5600000B, 0x5A00000B, 0x5C00000B, 0x000001B6, 
+        0x2400000A, 0x2800000A, 0x00000010, 0x020001AB, 0x060001AB, 0x0A0001AB, 0x0E0001AB, 0x120001AB, 
+        0x00000108, 0x00015802, 0x00440001, 0x00016002, 0x00016802, 0x00017002, 0x00017802, 0x00018002, 
+        0x00018802, 0x00440003, 0x00460001, 0x00480003, 0x00019802, 0x004A0001, 0x004C0001, 0x004E0001, 
+        0x003C0001, 0x00500001, 0x00520001, 0x000001BD, 0x0000018D, 0x000001D0, 0x00000250, 0x00000230, 
+        0x040005BE, 0x000000F9, 0x0200006B, 0x0A00006B, 0x0E00006B, 0x1200006B, 0x00540001, 0x00560001, 
+        0x000005B9, 0x045A000A, 0x085A000A, 0x0C5A000A, 0x105A000A, 0x145A000A, 0x185A000A, 0x525A000A, 
+        0x5E5A000A, 0x0401A00A, 0x0801A00A, 0x0C01A00A, 0x1001A00A, 0x1401A00A, 0x1801A00A, 0x5201A00A, 
+        0x5E01A00A, 0x4E00000A, 0x5C00000A, 0x0E0005B9, 0x100005B9, 0x020005B9, 0x040005B9, 0x160005B9, 
+        0x180005B9, 0x1A0005B9, 0x200005B9, 0x220005B9, 0x240005B9, 0x260005B9, 0x040001AB, 0x080001AB, 
+        0x0C0001AB, 0x100001AB, 0x140001AB, 0x180001AB, 0x1C0001AB, 0x200001AB, 0x240001AB, 0x280001AB, 
+        0x0C00006B, 0x1000006B, 0x1400006B, 0x1800006B, 0x1C00006B, 0x2000006B, 0x2400006B, 0x2800006B, 
+        0x005C001C, 0x0001A81C, 0x1A0001AB, 0x1E0001AB, 0x220001AB, 0x260001AB, 0x2A0001AB, 0x160001AB, 
+        0x020005B6, 0x100005B6, 0x280005B9, 0x2C0005B9, 0x300005B9, 0x0001B002, 0x020005BD, 0x0600000A, 
+        0x0A00000A, 0x0E00000A, 0x1200000A, 0x1600000A, 0x3E00000A, 0x0C00000B, 0x1000000B, 0x1400000B, 
+        0x2E0001AB, 0x320001AB, 0x360001AB, 0x3A0001AB, 0x3E0001AB, 0x420001AB, 0x460001AB, 0x640001AB, 
+        0x680001AB, 0x6A0001AB, 0x6E0001AB, 0x720001AB, 0x760001AB, 0x7A0001AB, 0x00000013, 0x00000012, 
+        0x0000005A, 0x000001B0, 0x7C00000B, 0x8000000B, 0x8200000B, 0x8600000B, 0x8C00000B, 0x6000000B, 
+        0x9200000B, 0x9600000B, 0x9800000B, 0x9C00000B, 0xA000000B, 0xA400000B, 0x4A0001AA, 0x040001AA, 
+        0x520001AA, 0x600001AA, 0x0C0001AA, 0x5E0001AA, 0x160001AA, 0x4C0001AA, 0x4E0001AA, 0x9E0001AA, 
+        0x060001AA, 0x8800000A, 0x2A0001AA, 0x005E0001, 0x0001B802, 0x0400002B, 0x0800002B, 0x1600002B, 
+        0x4C00002B, 0x00002802, 0x00003002, 0x000A0001, 0x00120001, 0x00003802, 0x001A0001, 0x001C0001, 
+        0x001E0001, 0x00240001, 0x00005002, 0x00006002, 0x002A0001, 0x002E0001, 0x00300001, 0x00006802, 
+        0x00008002, 0x00008802, 0x00009002, 0x0000A002, 0x0000B002, 0x0000D906, 0x00011002, 0x00011802, 
+        0x00014002, 0x040000C9, 0x080000C9, 0x0C0000C9, 0x100000C9, 0x140000C9, 0x04000009, 0x08000009, 
+        0x0C000009, 0x10000009, 0x14000009, 0x2200000B, 0x4C00000B, 0x2A00000B, 0x5000000B, 0x5400000B, 
+        0x5800000B, 0x2600000A, 0x00015002, 0x00019002, 0x00000030, 0x000001BE, 0x0000014E, 0x00000210, 
+        0x000001F0, 0x00580001, 0x065A000A, 0x0A5A000A, 0x0E5A000A, 0x125A000A, 0x165A000A, 0x1A5A000A, 
+        0x4C5A000A, 0x4E5A000A, 0x0601A00A, 0x0A01A00A, 0x0E01A00A, 0x1201A00A, 0x1601A00A, 0x1A01A00A, 
+        0x4C01A00A, 0x4E01A00A, 0x6000000A, 0x0000000A, 0x120005B9, 0x140005B9, 0x1C0005B9, 0x1E0005B9, 
+        0x1600006B, 0x1A00006B, 0x1E00006B, 0x2200006B, 0x2600006B, 0x2A00006B, 0x0E0005B5, 0x040005B5, 
+        0x2A0005B9, 0x2E0005B9, 0x0200000A, 0x0400000A, 0x0800000A, 0x0C00000A, 0x1000000A, 0x1400000A, 
+        0x2A00000A, 0x2C0001AB, 0x300001AB, 0x340001AB, 0x380001AB, 0x3C0001AB, 0x400001AB, 0x440001AB, 
+        0x480001AB, 0x620001AB, 0x660001AB, 0x500001AB, 0x6C0001AB, 0x700001AB, 0x740001AB, 0x780001AB, 
+        0x520001AB, 0x7E00000B, 0x5E00000B, 0x8400000B, 0x8800000B, 0x8A00000B, 0x8E00000B, 0x9000000B, 
+        0x9400000B, 0x9A00000B, 0x9E00000B, 0xA200000B, 0xA600000B, 0x5C0001AA, 0x3E0001AA, 0x7E0001AA, 
+        0x0600002B, 0x0A00002B, 0x2A00002B, 0x4E00002B, 0x00000019
+    };
+}
diff --git a/libs/utils/executablepath_darwin.cpp b/libs/utils/executablepath_darwin.cpp
new file mode 100644
index 0000000..2e3c3a0
--- /dev/null
+++ b/libs/utils/executablepath_darwin.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#include <utils/executablepath.h>
+#import <Carbon/Carbon.h>
+#include <unistd.h>
+
+void executablepath(char s[PATH_MAX])
+{
+    ProcessSerialNumber psn;
+    GetCurrentProcess(&psn);
+    CFDictionaryRef dict;
+    dict = ProcessInformationCopyDictionary(&psn, 0xffffffff);
+    CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict,
+                CFSTR("CFBundleExecutable"));
+    CFStringGetCString(value, s, PATH_MAX+1, kCFStringEncodingUTF8);
+}
+
diff --git a/libs/utils/executablepath_linux.cpp b/libs/utils/executablepath_linux.cpp
new file mode 100644
index 0000000..b8d2a3d
--- /dev/null
+++ b/libs/utils/executablepath_linux.cpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+#include <utils/executablepath.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <limits.h>
+#include <stdio.h>
+
+void executablepath(char exe[PATH_MAX])
+{
+    char proc[100];
+    sprintf(proc, "/proc/%d/exe", getpid());
+    
+    int err = readlink(proc, exe, PATH_MAX);
+}
+
diff --git a/libs/utils/futex_synchro.c b/libs/utils/futex_synchro.c
new file mode 100644
index 0000000..ba19520
--- /dev/null
+++ b/libs/utils/futex_synchro.c
@@ -0,0 +1,175 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <limits.h>
+
+#include <sys/time.h>
+#include <sched.h>
+
+#include <errno.h>
+
+#include <private/utils/futex_synchro.h>
+
+
+// This futex glue code is need on desktop linux, but is already part of bionic.
+#if !defined(HAVE_FUTEX_WRAPPERS)
+
+#include <sys/syscall.h>
+typedef unsigned int u32;
+#define asmlinkage
+#define __user
+#include <linux/futex.h>
+#include <utils/Atomic.h>
+
+
+int futex (int *uaddr, int op, int val, const struct timespec *timeout, int *uaddr2, int val3)
+{
+    int err = syscall(SYS_futex, uaddr, op, val, timeout, uaddr2, val3);
+    return err == 0 ? 0 : -errno;
+}
+
+int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout)
+{
+    return futex((int*)ftx, FUTEX_WAIT, val, timeout, NULL, 0);
+}
+
+int __futex_wake(volatile void *ftx, int count)
+{
+    return futex((int*)ftx, FUTEX_WAKE, count, NULL, NULL, 0);
+}
+
+int __atomic_cmpxchg(int old, int _new, volatile int *ptr)
+{
+    return android_atomic_cmpxchg(old, _new, ptr);
+}
+
+int __atomic_swap(int _new, volatile int *ptr)
+{
+    return android_atomic_swap(_new, ptr);
+}
+
+int __atomic_dec(volatile int *ptr)
+{
+    return android_atomic_dec(ptr);
+}
+
+#else // !defined(__arm__)
+
+int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
+int __futex_wake(volatile void *ftx, int count);
+
+int __atomic_cmpxchg(int old, int _new, volatile int *ptr);
+int __atomic_swap(int _new, volatile int *ptr);
+int __atomic_dec(volatile int *ptr);
+
+#endif // !defined(HAVE_FUTEX_WRAPPERS)
+
+
+// lock states
+//
+// 0: unlocked
+// 1: locked, no waiters
+// 2: locked, maybe waiters
+
+void futex_mutex_init(futex_mutex_t *m)
+{
+    m->value = 0;
+}
+
+int futex_mutex_lock(futex_mutex_t *m, unsigned msec)
+{
+    if(__atomic_cmpxchg(0, 1, &m->value) == 0) {
+        return 0;
+    }
+    if(msec == FUTEX_WAIT_INFINITE) {
+        while(__atomic_swap(2, &m->value) != 0) {
+            __futex_wait(&m->value, 2, 0);
+        }
+    } else {
+        struct timespec ts;
+        ts.tv_sec = msec / 1000;
+        ts.tv_nsec = (msec % 1000) * 1000000;
+        while(__atomic_swap(2, &m->value) != 0) {
+            if(__futex_wait(&m->value, 2, &ts) == -ETIMEDOUT) {
+                return -1;
+            }
+        }
+    }
+    return 0;
+}
+
+int futex_mutex_trylock(futex_mutex_t *m)
+{
+    if(__atomic_cmpxchg(0, 1, &m->value) == 0) {
+        return 0;
+    }
+    return -1;
+}
+
+void futex_mutex_unlock(futex_mutex_t *m)
+{
+    if(__atomic_dec(&m->value) != 1) {
+        m->value = 0;
+        __futex_wake(&m->value, 1);
+    }
+}
+
+/* XXX *technically* there is a race condition that could allow
+ * XXX a signal to be missed.  If thread A is preempted in _wait()
+ * XXX after unlocking the mutex and before waiting, and if other
+ * XXX threads call signal or broadcast UINT_MAX times (exactly),
+ * XXX before thread A is scheduled again and calls futex_wait(),
+ * XXX then the signal will be lost.
+ */
+
+void futex_cond_init(futex_cond_t *c)
+{
+    c->value = 0;
+}
+
+int futex_cond_wait(futex_cond_t *c, futex_mutex_t *m, unsigned msec)
+{
+    if(msec == FUTEX_WAIT_INFINITE){
+        int oldvalue = c->value;
+        futex_mutex_unlock(m);
+        __futex_wait(&c->value, oldvalue, 0);
+        futex_mutex_lock(m, FUTEX_WAIT_INFINITE);
+        return 0;
+    } else {
+        int oldvalue = c->value;
+        struct timespec ts;        
+        ts.tv_sec = msec / 1000;
+        ts.tv_nsec = (msec % 1000) * 1000000;
+        futex_mutex_unlock(m);
+        const int err = __futex_wait(&c->value, oldvalue, &ts);
+        futex_mutex_lock(m, FUTEX_WAIT_INFINITE);
+        return err;
+    }
+}
+
+void futex_cond_signal(futex_cond_t *c)
+{
+    __atomic_dec(&c->value);
+    __futex_wake(&c->value, 1);
+}
+
+void futex_cond_broadcast(futex_cond_t *c)
+{
+    __atomic_dec(&c->value);
+    __futex_wake(&c->value, INT_MAX);
+}
+
diff --git a/libs/utils/misc.cpp b/libs/utils/misc.cpp
new file mode 100644
index 0000000..dc89d15
--- /dev/null
+++ b/libs/utils/misc.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+//
+// Miscellaneous utility functions.
+//
+#include <utils/misc.h>
+
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdio.h>
+
+using namespace android;
+
+namespace android {
+
+/*
+ * Like strdup(), but uses C++ "new" operator instead of malloc.
+ */
+char* strdupNew(const char* str)
+{
+    char* newStr;
+    int len;
+
+    if (str == NULL)
+        return NULL;
+
+    len = strlen(str);
+    newStr = new char[len+1];
+    memcpy(newStr, str, len+1);
+
+    return newStr;
+}
+
+/*
+ * Concatenate an argument vector.
+ */
+char* concatArgv(int argc, const char* const argv[])
+{
+    char* newStr = NULL;
+    int len, totalLen, posn, idx;
+
+    /*
+     * First, figure out the total length.
+     */
+    totalLen = idx = 0;
+    while (1) {
+        if (idx == argc || argv[idx] == NULL)
+            break;
+        if (idx)
+            totalLen++;  // leave a space between args
+        totalLen += strlen(argv[idx]);
+        idx++;
+    }
+
+    /*
+     * Alloc the string.
+     */
+    newStr = new char[totalLen +1];
+    if (newStr == NULL)
+        return NULL;
+
+    /*
+     * Finally, allocate the string and copy data over.
+     */
+    idx = posn = 0;
+    while (1) {
+        if (idx == argc || argv[idx] == NULL)
+            break;
+        if (idx)
+            newStr[posn++] = ' ';
+
+        len = strlen(argv[idx]);
+        memcpy(&newStr[posn], argv[idx], len);
+        posn += len;
+
+        idx++;
+    }
+
+    assert(posn == totalLen);
+    newStr[posn] = '\0';
+
+    return newStr;
+}
+
+/*
+ * Count the #of args in an argument vector.  Don't count the final NULL.
+ */
+int countArgv(const char* const argv[])
+{
+    int count = 0;
+
+    while (argv[count] != NULL)
+        count++;
+
+    return count;
+}
+
+
+#include <stdio.h>
+/*
+ * Get a file's type.
+ */
+FileType getFileType(const char* fileName)
+{
+    struct stat sb;
+
+    if (stat(fileName, &sb) < 0) {
+        if (errno == ENOENT || errno == ENOTDIR)
+            return kFileTypeNonexistent;
+        else {
+            fprintf(stderr, "getFileType got errno=%d on '%s'\n",
+                errno, fileName);
+            return kFileTypeUnknown;
+        }
+    } else {
+        if (S_ISREG(sb.st_mode))
+            return kFileTypeRegular;
+        else if (S_ISDIR(sb.st_mode))
+            return kFileTypeDirectory;
+        else if (S_ISCHR(sb.st_mode))
+            return kFileTypeCharDev;
+        else if (S_ISBLK(sb.st_mode))
+            return kFileTypeBlockDev;
+        else if (S_ISFIFO(sb.st_mode))
+            return kFileTypeFifo;
+#ifdef HAVE_SYMLINKS            
+        else if (S_ISLNK(sb.st_mode))
+            return kFileTypeSymlink;
+        else if (S_ISSOCK(sb.st_mode))
+            return kFileTypeSocket;
+#endif            
+        else
+            return kFileTypeUnknown;
+    }
+}
+
+/*
+ * Get a file's modification date.
+ */
+time_t getFileModDate(const char* fileName)
+{
+    struct stat sb;
+
+    if (stat(fileName, &sb) < 0)
+        return (time_t) -1;
+
+    return sb.st_mtime;
+}
+
+/*
+ * Round up to the next highest power of 2.
+ *
+ * Found on http://graphics.stanford.edu/~seander/bithacks.html.
+ */
+unsigned int roundUpPower2(unsigned int val)
+{
+    val--;
+    val |= val >> 1;
+    val |= val >> 2;
+    val |= val >> 4;
+    val |= val >> 8;
+    val |= val >> 16;
+    val++;
+
+    return val;
+}
+
+}; // namespace android
+
diff --git a/libs/utils/ported.cpp b/libs/utils/ported.cpp
new file mode 100644
index 0000000..656e46f
--- /dev/null
+++ b/libs/utils/ported.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+//
+// Ports of standard functions that don't exist on a specific platform.
+//
+// Note these are NOT in the "android" namespace.
+//
+#include <utils/ported.h>
+
+#if defined(NEED_GETTIMEOFDAY) || defined(NEED_USLEEP)
+# include <sys/time.h>
+# include <windows.h>
+#endif
+
+
+#if defined(NEED_GETTIMEOFDAY)
+/*
+ * Replacement gettimeofday() for Windows environments (primarily MinGW).
+ *
+ * Ignores "tz".
+ */
+int gettimeofday(struct timeval* ptv, struct timezone* tz)
+{
+    long long nsTime;   // time in 100ns units since Jan 1 1601
+    FILETIME ft;
+
+    if (tz != NULL) {
+        // oh well
+    }
+
+    ::GetSystemTimeAsFileTime(&ft);
+    nsTime = (long long) ft.dwHighDateTime << 32 |
+             (long long) ft.dwLowDateTime;
+    // convert to time in usec since Jan 1 1970
+    ptv->tv_usec = (long) ((nsTime / 10LL) % 1000000LL);
+    ptv->tv_sec = (long) ((nsTime - 116444736000000000LL) / 10000000LL);
+
+    return 0;
+}
+#endif
+
+#if defined(NEED_USLEEP)
+//
+// Replacement usleep for Windows environments (primarily MinGW).
+//
+void usleep(unsigned long usec)
+{
+    // Win32 API function Sleep() takes milliseconds
+    ::Sleep((usec + 500) / 1000);
+}
+#endif
+
+#if 0 //defined(NEED_PIPE)
+//
+// Replacement pipe() command for MinGW
+//
+// The _O_NOINHERIT flag sets bInheritHandle to FALSE in the
+// SecurityAttributes argument to CreatePipe().  This means the handles
+// aren't inherited when a new process is created.  The examples I've seen
+// use it, possibly because there's a lot of junk going on behind the
+// scenes.  (I'm assuming "process" and "thread" are different here, so
+// we should be okay spinning up a thread.)  The recommended practice is
+// to dup() the descriptor you want the child to have.
+//
+// It appears that unnamed pipes can't do non-blocking ("overlapped") I/O.
+// You can't use select() either, since that only works on sockets.  The
+// Windows API calls that are useful here all operate on a HANDLE, not
+// an integer file descriptor, and I don't think you can get there from
+// here.  The "named pipe" stuff is insane.
+//
+int pipe(int filedes[2])
+{
+    return _pipe(filedes, 0, _O_BINARY | _O_NOINHERIT);
+}
+#endif
+
+#if defined(NEED_SETENV)
+/*
+ * MinGW lacks these.  For now, just stub them out so the code compiles.
+ */
+int setenv(const char* name, const char* value, int overwrite)
+{
+    return 0;
+}
+void unsetenv(const char* name)
+{
+}
+char* getenv(const char* name)
+{
+    return NULL;
+}
+#endif
