Merge change 2318 into donut

* changes:
  Fixed vertical text position in search suggestion items.
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index f85ea9f..4e6859c 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -1052,8 +1052,6 @@
 }
 
 
-#if DEBUG_HEAP_LEAKS
-
 #define CHECK_INTERFACE(interface, data, reply) \
         do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
             LOGW("Call incorrectly routed to " #interface); \
@@ -1085,6 +1083,7 @@
 
     status_t err = BnCameraService::onTransact(code, data, reply, flags);
 
+#if DEBUG_HEAP_LEAKS
     LOGD("+++ onTransact err %d code %d", err, code);
 
     if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
@@ -1120,9 +1119,9 @@
             break;
         }
     }
+#endif // DEBUG_HEAP_LEAKS
+
     return err;
 }
 
-#endif // DEBUG_HEAP_LEAKS
-
 }; // namespace android
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index 6752f26..a421fd3 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -58,10 +58,8 @@
 
             void            removeClient(const sp<ICameraClient>& cameraClient);
 
-#if DEBUG_HEAP_LEAKS
     virtual status_t onTransact(
         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
-#endif
 
 private:
 
diff --git a/include/tts/TtsEngine.h b/include/tts/TtsEngine.h
new file mode 100644
index 0000000..06f3820
--- /dev/null
+++ b/include/tts/TtsEngine.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2009 Google 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.
+ */
+#include <media/AudioSystem.h>
+
+// This header defines the interface used by the Android platform
+// to access Text-To-Speech functionality in shared libraries that implement speech
+// synthesis and the management of resources associated with the synthesis.
+// An example of the implementation of this interface can be found in 
+// FIXME: add path+name to implementation of default TTS engine
+// Libraries implementing this interface are used in:
+//  frameworks/base/tts/jni/android_tts_SpeechSynthesis.cpp
+
+namespace android {
+
+// The callback is used by the implementation of this interface to notify its
+// client, the Android TTS service, that the last requested synthesis has been
+// completed.
+// The callback for synthesis completed takes:
+//    void *       - The userdata pointer set in the original synth call
+//    uint32_t     - Track sampling rate in Hz
+//    audio_format - The AudioSystem::audio_format enum
+//    int          - The number of channels
+//    int8_t *     - A buffer of audio data only valid during the execution of the callback
+//    size_t       - The size of the buffer
+// Note about memory management:
+//    The implementation of TtsEngine is responsible for the management of the memory
+//    it allocates to store the synthesized speech. After the execution of the callback
+//    to hand the synthesized data to the client of TtsEngine, the TTS engine is
+//    free to reuse or free the previously allocated memory.
+//    This implies that the implementation of the "synthDoneCB" callback cannot use
+//    the pointer to the buffer of audio samples outside of the callback itself.
+typedef void (synthDoneCB_t)(void *, uint32_t, AudioSystem::audio_format, int, int8_t *, size_t);
+
+class TtsEngine;
+extern "C" TtsEngine* getTtsEngine();
+
+enum tts_result {
+    TTS_SUCCESS                 = 0,
+    TTS_FAILURE                 = -1,
+    TTS_FEATURE_UNSUPPORTED     = -2,
+    TTS_VALUE_INVALID           = -3,
+    TTS_PROPERTY_UNSUPPORTED    = -4,
+    TTS_PROPERTY_SIZE_TOO_SMALL = -5
+};
+
+class TtsEngine
+{
+public:
+    // Initialize the TTS engine and returns whether initialization succeeded.
+    // @param synthDoneCBPtr synthesis callback function pointer
+    // @return TTS_SUCCESS, or TTS_FAILURE
+    virtual tts_result init(synthDoneCB_t synthDoneCBPtr);
+
+    // Shut down the TTS engine and releases all associated resources.
+    // @return TTS_SUCCESS, or TTS_FAILURE
+    virtual tts_result shutdown();
+
+    // Interrupt synthesis and flushes any synthesized data that hasn't been output yet.
+    // This will block until callbacks underway are completed.
+    // @return TTS_SUCCESS, or TTS_FAILURE
+    virtual tts_result stop();
+
+    // Load the resources associated with the specified language. The loaded language will
+    // only be used once a call to setLanguage() with the same language value is issued.
+    // Language values are based on the Android conventions for localization as described in
+    // the Android platform documentation on internationalization. This implies that language
+    // data is specified in the format xx-rYY, where xx is a two letter ISO 639-1 language code
+    // in lowercase and rYY is a two letter ISO 3166-1-alpha-2 language code in uppercase
+    // preceded by a lowercase "r".
+    // @param value pointer to the language value
+    // @param size  length of the language value
+    // @return TTS_SUCCESS, or TTS_FAILURE
+    virtual tts_result loadLanguage(const char *value, const size_t size);
+
+    // Signal the engine to use the specified language. This will force the language to be
+    // loaded if it wasn't loaded previously with loadLanguage().
+    // See loadLanguage for the specification of the language.
+    // @param value pointer to the language value
+    // @param size  length of the language value
+    // @return TTS_SUCCESS, or TTS_FAILURE
+    virtual tts_result setLanguage(const char *value, const size_t size);
+
+    // Retrieve the currently set language, or an empty "value" if no language has
+    // been set.
+    // @param[out]   value pointer to the retrieved language value
+    // @param[inout] iosize  in: stores the size available to store the language value in *value
+    //                       out: stores the size required to hold the language value if
+    //                         getLanguage() returned  TTS_PROPERTY_SIZE_TOO_SMALL,
+    //                         unchanged otherwise.
+    // @return TTS_SUCCESS, or TTS_PROPERTY_SIZE_TOO_SMALL, or TTS_FAILURE
+    virtual tts_result getLanguage(char *value, size_t *iosize);
+
+    // Set a property for the the TTS engine
+    // "size" is the maximum size of "value" for properties "property"
+    // @param property pointer to the property name
+    // @param value    pointer to the property value
+    // @param size     maximum size required to store this type of property
+    // @return         TTS_PROPERTY_UNSUPPORTED, or TTS_SUCCESS, or TTS_FAILURE, 
+    //                  or TTS_VALUE_INVALID
+    virtual tts_result setProperty(const char *property, const char *value, const size_t size);
+
+    // Retrieve a property from the TTS engine
+    // @param        property pointer to the property name
+    // @param[out]   value    pointer to the retrieved language value
+    // @param[inout] iosize   in: stores the size available to store the property value
+    //                        out: stores the size required to hold the language value if
+    //                         getLanguage() returned  TTS_PROPERTY_SIZE_TOO_SMALL,
+    //                         unchanged otherwise.
+    // @return TTS_PROPERTY_UNSUPPORTED, or TTS_SUCCESS, or TTS_PROPERTY_SIZE_TOO_SMALL
+    virtual tts_result getProperty(const char *property, char *value, size_t *iosize);
+
+    // Synthesize the text.
+    // When synthesis completes, the engine invokes the callback to notify the TTS framework.
+    // Note about the format of the input: the text parameter may use the following elements
+    // and their respective attributes as defined in the SSML 1.0 specification:
+    //    * lang
+    //    * say-as:
+    //          o interpret-as
+    //    * phoneme
+    //    * voice:
+    //          o gender,
+    //          o age,
+    //          o variant,
+    //          o name
+    //    * emphasis
+    //    * break:
+    //          o strength,
+    //          o time
+    //    * prosody:
+    //          o pitch,
+    //          o contour,
+    //          o range,
+    //          o rate,
+    //          o duration,
+    //          o volume
+    //    * mark
+    // Differences between this text format and SSML are:
+    //    * full SSML documents are not supported
+    //    * namespaces are not supported
+    // Text is coded in UTF-8.
+    // @param text      the UTF-8 text to synthesize
+    // @param userdata  pointer to be returned when the call is invoked
+    // @return          TTS_SUCCESS or TTS_FAILURE
+    virtual tts_result synthesizeText(const char *text, void *userdata);
+
+    // Synthesize IPA text. When synthesis completes, the engine must call the given callback to notify the TTS API.
+    // @param ipa      the IPA data to synthesize
+    // @param userdata  pointer to be returned when the call is invoked
+    // @return TTS_FEATURE_UNSUPPORTED if IPA is not supported, otherwise TTS_SUCCESS or TTS_FAILURE
+    virtual tts_result synthesizeIpa(const char *ipa, void *userdata);
+};
+
+} // namespace android
+
diff --git a/include/utils/Parcel.h b/include/utils/Parcel.h
index 9087c44..af1490a 100644
--- a/include/utils/Parcel.h
+++ b/include/utils/Parcel.h
@@ -80,8 +80,11 @@
     status_t            writeStrongBinder(const sp<IBinder>& val);
     status_t            writeWeakBinder(const wp<IBinder>& val);
 
-    // doesn't take ownership of the native_handle
-    status_t            writeNativeHandle(const native_handle& handle);
+    // Place a native_handle into the parcel (the native_handle's file-
+    // descriptors are dup'ed, so it is safe to delete the native_handle
+    // when this function returns). 
+    // Doesn't take ownership of the native_handle.
+    status_t            writeNativeHandle(const native_handle* handle);
     
     // Place a file descriptor into the parcel.  The given fd must remain
     // valid for the lifetime of the parcel.
@@ -114,12 +117,11 @@
     wp<IBinder>         readWeakBinder() const;
 
     
-    // if alloc is NULL, native_handle is allocated with malloc(), otherwise
-    // alloc is used. If the function fails, the effects of alloc() must be
-    // reverted by the caller.
-    native_handle*     readNativeHandle(
-            native_handle* (*alloc)(void* cookie, int numFds, int ints),
-            void* cookie) const;
+    // Retrieve native_handle from the parcel. This returns a copy of the
+    // parcel's native_handle (the caller takes ownership). The caller
+    // must free the native_handle with native_handle_close() and 
+    // native_handle_delete().
+    native_handle*     readNativeHandle() const;
 
     
     // Retrieve a file descriptor from the parcel.  This returns the raw fd
diff --git a/include/utils/backup_helpers.h b/include/utils/backup_helpers.h
index 0c59fec..24b6c9e 100644
--- a/include/utils/backup_helpers.h
+++ b/include/utils/backup_helpers.h
@@ -22,24 +22,27 @@
 
 namespace android {
 
-int back_up_files(int oldSnapshotFD, int oldDataStream, int newSnapshotFD,
-        char const* fileBase, char const* const* files, int fileCount);
+enum {
+    BACKUP_HEADER_APP_V1 = 0x31707041, // App1 (little endian)
+    BACKUP_HEADER_ENTITY_V1 = 0x61746144, // Data (little endian)
+    BACKUP_FOOTER_APP_V1 = 0x746f6f46, // Foot (little endian)
+};
 
 // the sizes of all of these match.
 typedef struct {
-    int type; // == APP_MAGIC_V1
+    int type; // == BACKUP_HEADER_APP_V1
     int packageLen; // length of the name of the package that follows, not including the null.
     int cookie;
 } app_header_v1;
 
 typedef struct {
-    int type; // ENTITY_MAGIC_V1
+    int type; // BACKUP_HEADER_ENTITY_V1
     int keyLen; // length of the key name, not including the null terminator
-    int dataSize; // size of the data, not including the padding
+    int dataSize; // size of the data, not including the padding, -1 means delete
 } entity_header_v1;
 
 typedef struct {
-    int type; // FOOTER_MAGIC_V1
+    int type; // BACKUP_FOOTER_APP_V1
     int entityCount; // the number of entities that were written
     int cookie;
 } app_footer_v1;
@@ -89,11 +92,12 @@
     ~BackupDataReader();
 
     status_t Status();
-    status_t ReadNextHeader();
+    status_t ReadNextHeader(int* type = NULL);
 
     status_t ReadAppHeader(String8* packageName, int* cookie);
     bool HasEntities();
     status_t ReadEntityHeader(String8* key, size_t* dataSize);
+    status_t SkipEntityData(); // must be called with the pointer at the begining of the data.
     status_t ReadEntityData(void* data, size_t size);
     status_t ReadAppFooter(int* cookie);
 
@@ -113,7 +117,11 @@
     } m_header;
 };
 
-#define TEST_BACKUP_HELPERS 0
+int back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
+        char const* fileBase, char const* const* files, int fileCount);
+
+
+#define TEST_BACKUP_HELPERS 1
 
 #if TEST_BACKUP_HELPERS
 int backup_helper_test_empty();
diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
index b6d5078..16a4f2d 100644
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ b/libs/audioflinger/A2dpAudioInterface.cpp
@@ -71,8 +71,8 @@
 }
 
 AudioStreamIn* A2dpAudioInterface::openInputStream(
-        int format, int channelCount, uint32_t sampleRate, status_t *status,
-        AudioSystem::audio_in_acoustics acoustics)
+        int inputSource, int format, int channelCount, uint32_t sampleRate,
+        status_t *status, AudioSystem::audio_in_acoustics acoustics)
 {
     if (status)
         *status = -1;
diff --git a/libs/audioflinger/A2dpAudioInterface.h b/libs/audioflinger/A2dpAudioInterface.h
index 7901a8c..091e775 100644
--- a/libs/audioflinger/A2dpAudioInterface.h
+++ b/libs/audioflinger/A2dpAudioInterface.h
@@ -55,6 +55,7 @@
                                 status_t *status=0);
 
     virtual AudioStreamIn* openInputStream(
+                                int inputSource,
                                 int format,
                                 int channelCount,
                                 uint32_t sampleRate,
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
index 9a94102..b72c94e 100644
--- a/libs/audioflinger/AudioDumpInterface.h
+++ b/libs/audioflinger/AudioDumpInterface.h
@@ -78,9 +78,9 @@
     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 AudioStreamIn* openInputStream(int inputSource, int format, int channelCount,
+            uint32_t sampleRate, status_t *status, AudioSystem::audio_in_acoustics acoustics)
+        { return mFinalInterface->openInputStream(inputSource, format, channelCount, sampleRate, status, acoustics); }
 
     virtual status_t    dump(int fd, const Vector<String16>& args) { return mFinalInterface->dumpState(fd, args); }
 
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index b56221f..e4f4aad 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -2407,7 +2407,9 @@
                
                 LOGV("AudioRecordThread: loop starting");
                 if (mRecordTrack != 0) {
-                    input = mAudioHardware->openInputStream(mRecordTrack->format(), 
+                    input = mAudioHardware->openInputStream(
+                                    mRecordTrack->type(),
+                                    mRecordTrack->format(), 
                                     mRecordTrack->channelCount(), 
                                     mRecordTrack->sampleRate(), 
                                     &mStartStatus,
diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp
index 62beada..a97c0bc 100644
--- a/libs/audioflinger/AudioHardwareGeneric.cpp
+++ b/libs/audioflinger/AudioHardwareGeneric.cpp
@@ -30,6 +30,7 @@
 #include <utils/String8.h>
 
 #include "AudioHardwareGeneric.h"
+#include <media/AudioRecord.h>
 
 namespace android {
 
@@ -93,9 +94,15 @@
 }
 
 AudioStreamIn* AudioHardwareGeneric::openInputStream(
-        int format, int channelCount, uint32_t sampleRate, status_t *status,
-        AudioSystem::audio_in_acoustics acoustics)
+        int inputSource, int format, int channelCount, uint32_t sampleRate,
+        status_t *status, AudioSystem::audio_in_acoustics acoustics)
 {
+    // check for valid input source
+    if ((inputSource != AudioRecord::DEFAULT_INPUT) &&
+            (inputSource != AudioRecord::MIC_INPUT)) {
+        return 0;
+    }
+
     AutoMutex lock(mLock);
 
     // only one input stream allowed
diff --git a/libs/audioflinger/AudioHardwareGeneric.h b/libs/audioflinger/AudioHardwareGeneric.h
index c949aa1..c89df87 100644
--- a/libs/audioflinger/AudioHardwareGeneric.h
+++ b/libs/audioflinger/AudioHardwareGeneric.h
@@ -112,6 +112,7 @@
             status_t *status=0);
 
     virtual AudioStreamIn* openInputStream(
+            int inputSource,
             int format,
             int channelCount,
             uint32_t sampleRate,
diff --git a/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp
index b13cb1c..c61e6e6 100644
--- a/libs/audioflinger/AudioHardwareStub.cpp
+++ b/libs/audioflinger/AudioHardwareStub.cpp
@@ -23,6 +23,7 @@
 #include <utils/String8.h>
 
 #include "AudioHardwareStub.h"
+#include <media/AudioRecord.h>
 
 namespace android {
 
@@ -56,9 +57,15 @@
 }
 
 AudioStreamIn* AudioHardwareStub::openInputStream(
-        int format, int channelCount, uint32_t sampleRate,
+        int inputSource, int format, int channelCount, uint32_t sampleRate,
         status_t *status, AudioSystem::audio_in_acoustics acoustics)
 {
+    // check for valid input source
+    if ((inputSource != AudioRecord::DEFAULT_INPUT) &&
+            (inputSource != AudioRecord::MIC_INPUT)) {
+        return 0;
+    }
+
     AudioStreamInStub* in = new AudioStreamInStub();
     status_t lStatus = in->set(format, channelCount, sampleRate, acoustics);
     if (status) {
diff --git a/libs/audioflinger/AudioHardwareStub.h b/libs/audioflinger/AudioHardwareStub.h
index d406424..bf63cc5 100644
--- a/libs/audioflinger/AudioHardwareStub.h
+++ b/libs/audioflinger/AudioHardwareStub.h
@@ -78,6 +78,7 @@
                                 status_t *status=0);
 
     virtual AudioStreamIn* openInputStream(
+                                int inputSource,
                                 int format,
                                 int channelCount,
                                 uint32_t sampleRate,
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index 2212436..9272983 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -6,7 +6,6 @@
     DisplayHardware/DisplayHardware.cpp \
     DisplayHardware/DisplayHardwareBase.cpp \
     GPUHardware/GPUHardware.cpp \
-    BootAnimation.cpp \
     BlurFilter.cpp.arm \
     CPUGauge.cpp \
     Layer.cpp \
diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp
deleted file mode 100644
index db40385..0000000
--- a/libs/surfaceflinger/BootAnimation.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * 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_TEXTURE_2D);
-    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-logo-mask.png");
-    initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");
-
-    // clear screen
-    glDisable(GL_DITHER);
-    glDisable(GL_SCISSOR_TEST);
-    glClear(GL_COLOR_BUFFER_BIT);
-    eglSwapBuffers(mDisplay, mSurface);
-
-    const GLint xc = (mWidth  - mAndroid[0].w) / 2;
-    const GLint yc = (mHeight - mAndroid[0].h) / 2;
-    const Rect updateRect(xc, yc, xc + mAndroid[0].w, yc + mAndroid[0].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());
-
-    // Blend state
-    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
-    const nsecs_t startTime = systemTime();
-    do {
-        nsecs_t now = systemTime();
-        double time = now - startTime;
-        float t = 4.0f * float(time / us2ns(16667)) / mAndroid[1].w;
-        GLint offset = (1 - (t - floorf(t))) * mAndroid[1].w;
-        GLint x = xc - offset;
-
-        glDisable(GL_BLEND);
-        glBindTexture(GL_TEXTURE_2D, mAndroid[1].name);
-        glDrawTexiOES(x,                 yc, 0, mAndroid[1].w, mAndroid[1].h);
-        glDrawTexiOES(x + mAndroid[1].w, yc, 0, mAndroid[1].w, mAndroid[1].h);
-
-        glEnable(GL_BLEND);
-        glBindTexture(GL_TEXTURE_2D, mAndroid[0].name);
-        glDrawTexiOES(xc, yc, 0, mAndroid[0].w, mAndroid[0].h);
-
-        eglSwapBuffers(mDisplay, mSurface);
-        
-        // 12fps: don't animate too fast to preserve CPU
-        const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now);
-        if (sleepTime > 0)
-            usleep(sleepTime); 
-    } while (!exitPending());
-
-    glDeleteTextures(1, &mAndroid[0].name);
-    glDeleteTextures(1, &mAndroid[1].name);
-    return false;
-}
-
-// ---------------------------------------------------------------------------
-
-}
-; // namespace android
diff --git a/libs/surfaceflinger/BootAnimation.h b/libs/surfaceflinger/BootAnimation.h
deleted file mode 100644
index 3fb6670..0000000
--- a/libs/surfaceflinger/BootAnimation.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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();
-
-    sp<SurfaceComposerClient>       mSession;
-    AssetManager mAssets;
-    Texture     mAndroid[2];
-    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/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 167a59b..0e998bf 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -61,6 +61,13 @@
 #include "GPUHardware/GPUHardware.h"
 
 
+/* ideally AID_GRAPHICS would be in a semi-public header
+ * or there would be a way to map a user/group name to its id
+ */
+#ifndef AID_GRAPHICS
+#define AID_GRAPHICS 1003
+#endif
+
 #define DISPLAY_COUNT       1
 
 namespace android {
@@ -184,7 +191,6 @@
         mDebugCpu(0),
         mDebugFps(0),
         mDebugBackground(0),
-        mDebugNoBootAnimation(0),
         mSyncObject(),
         mDeplayedTransactionPending(0),
         mConsoleSignals(0),
@@ -207,14 +213,11 @@
     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()
@@ -324,11 +327,8 @@
 {
     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();
-    }
+    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );  
+    property_set("ctl.stop", "bootanim");
 }
 
 void SurfaceFlinger::onFirstRef()
@@ -456,10 +456,10 @@
     if (mDebugCpu)
         mCpuGauge = new CPUGauge(this, ms2ns(500));
 
-    // the boot animation!
-    if (mDebugNoBootAnimation == false)
-        mBootAnimation = new BootAnimation(this);
-
+    
+    // start boot animation
+    property_set("ctl.start", "bootanim");
+    
     return NO_ERROR;
 }
 
@@ -1543,13 +1543,13 @@
             // codes that require permission check
             IPCThreadState* ipc = IPCThreadState::self();
             const int pid = ipc->getCallingPid();
+            const int uid = ipc->getCallingUid();
             const int self_pid = getpid();
-            if (UNLIKELY(pid != self_pid)) {
+            if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
                 // 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;
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index e023182..15913f2 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -36,7 +36,6 @@
 #include <private/ui/SurfaceFlingerSynchro.h>
 
 #include "Barrier.h"
-#include "BootAnimation.h"
 #include "CPUGauge.h"
 #include "Layer.h"
 #include "Tokenizer.h"
@@ -347,7 +346,6 @@
                 sp<SurfaceHeapManager>      mSurfaceHeapManager;
                 sp<GPUHardwareInterface>    mGPU;
                 GLuint                      mWormholeTexName;
-                sp<BootAnimation>           mBootAnimation;
                 nsecs_t                     mBootTime;
                 
                 // Can only accessed from the main thread, these members
@@ -374,7 +372,6 @@
                 int                         mDebugCpu;
                 int                         mDebugFps;
                 int                         mDebugBackground;
-                int                         mDebugNoBootAnimation;
 
                 // these are thread safe
     mutable     Barrier                     mReadyToRunBarrier;
diff --git a/libs/surfaceflinger/VRamHeap.cpp b/libs/surfaceflinger/VRamHeap.cpp
index 238c602..5f633bd 100644
--- a/libs/surfaceflinger/VRamHeap.cpp
+++ b/libs/surfaceflinger/VRamHeap.cpp
@@ -35,6 +35,8 @@
 #include <utils/MemoryHeapPmem.h>
 #include <utils/MemoryHeapBase.h>
 
+#include <EGL/eglnatives.h>
+
 #include "GPUHardware/GPUHardware.h"
 #include "SurfaceFlinger.h"
 #include "VRamHeap.h"
diff --git a/libs/ui/ISurfaceFlingerClient.cpp b/libs/ui/ISurfaceFlingerClient.cpp
index dd6a798..dab5f71 100644
--- a/libs/ui/ISurfaceFlingerClient.cpp
+++ b/libs/ui/ISurfaceFlingerClient.cpp
@@ -35,6 +35,13 @@
 
 // ---------------------------------------------------------------------------
 
+/* ideally AID_GRAPHICS would be in a semi-public header
+ * or there would be a way to map a user/group name to its id
+ */
+#ifndef AID_GRAPHICS
+#define AID_GRAPHICS 1003
+#endif
+
 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
 
@@ -136,13 +143,13 @@
      
      IPCThreadState* ipc = IPCThreadState::self();
      const int pid = ipc->getCallingPid();
-     const int self_pid    = getpid();
-     if (UNLIKELY(pid != self_pid)) {
+     const int uid = ipc->getCallingUid();
+     const int self_pid = getpid();
+     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
          // 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;
diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp
index b236edc..59c6514 100644
--- a/libs/ui/Overlay.cpp
+++ b/libs/ui/Overlay.cpp
@@ -129,12 +129,8 @@
 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);
+        native_handle_close(mOverlayHandle);
+        native_handle_delete(const_cast<native_handle*>(mOverlayHandle));
     }
 }
 
@@ -147,7 +143,7 @@
         uint32_t f = data.readInt32();
         uint32_t ws = data.readInt32();
         uint32_t hs = data.readInt32();
-        native_handle* handle = data.readNativeHandle(NULL, NULL);
+        native_handle* handle = data.readNativeHandle();
 
         result = new OverlayRef();
         result->mOverlayHandle = handle;
@@ -169,7 +165,7 @@
         reply->writeInt32(o->mFormat);
         reply->writeInt32(o->mWidthStride);
         reply->writeInt32(o->mHeightStride);
-        reply->writeNativeHandle(*(o->mOverlayHandle));
+        reply->writeNativeHandle(o->mOverlayHandle);
     } else {
         reply->writeStrongBinder(NULL);
     }
diff --git a/libs/utils/Parcel.cpp b/libs/utils/Parcel.cpp
index 0f4b647..e74ad4a 100644
--- a/libs/utils/Parcel.cpp
+++ b/libs/utils/Parcel.cpp
@@ -650,28 +650,26 @@
     return flatten_binder(ProcessState::self(), val, this);
 }
 
-status_t Parcel::writeNativeHandle(const native_handle& handle)
+status_t Parcel::writeNativeHandle(const native_handle* handle)
 {
-    if (handle.version != sizeof(native_handle))
+    if (handle->version != sizeof(native_handle))
         return BAD_TYPE;
 
     status_t err;
-    err = writeInt32(handle.numFds);
+    err = writeInt32(handle->numFds);
     if (err != NO_ERROR) return err;
 
-    err = writeInt32(handle.numInts);
+    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]);
+    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);
-
+    err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
     return err;
 }
 
@@ -928,7 +926,7 @@
 }
 
 
-native_handle* Parcel::readNativeHandle(native_handle* (*alloc)(void*, int, int), void* cookie) const
+native_handle* Parcel::readNativeHandle() const
 {
     int numFds, numInts;
     status_t err;
@@ -937,31 +935,15 @@
     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;
-        }
-    }
-    
+    native_handle* h = native_handle_create(numFds, numInts);
     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);
-        }
+        native_handle_close(h);
+        native_handle_delete(h);
         h = 0;
     }
     return h;
diff --git a/libs/utils/backup_data.cpp b/libs/utils/backup_data.cpp
index dd04449..95c05b7 100644
--- a/libs/utils/backup_data.cpp
+++ b/libs/utils/backup_data.cpp
@@ -39,10 +39,6 @@
  *      - The value, padded to 4 byte boundary
  */
 
-#define APP_MAGIC_V1 0x31707041 // App1 (little endian)
-#define ENTITY_MAGIC_V1 0x61746144 // Data (little endian)
-#define FOOTER_MAGIC_V1 0x746f6f46 // Foot (little endian)
-
 const static int ROUND_UP[4] = { 0, 3, 2, 1 };
 
 static inline size_t
@@ -108,7 +104,7 @@
 
     nameLen = packageName.length();
 
-    header.type = tolel(APP_MAGIC_V1);
+    header.type = tolel(BACKUP_HEADER_APP_V1);
     header.packageLen = tolel(nameLen);
     header.cookie = cookie;
 
@@ -148,7 +144,7 @@
 
     keyLen = key.length();
 
-    header.type = tolel(ENTITY_MAGIC_V1);
+    header.type = tolel(BACKUP_HEADER_ENTITY_V1);
     header.keyLen = tolel(keyLen);
     header.dataSize = tolel(dataSize);
 
@@ -209,7 +205,7 @@
     app_footer_v1 footer;
     ssize_t nameLen;
 
-    footer.type = tolel(FOOTER_MAGIC_V1);
+    footer.type = tolel(BACKUP_FOOTER_APP_V1);
     footer.entityCount = tolel(m_entityCount);
     footer.cookie = cookie;
 
@@ -264,7 +260,7 @@
     } while(0)
 
 status_t
-BackupDataReader::ReadNextHeader()
+BackupDataReader::ReadNextHeader(int* type)
 {
     if (m_status != NO_ERROR) {
         return m_status;
@@ -280,7 +276,7 @@
     m_header.type = fromlel(m_header.type);
     switch (m_header.type)
     {
-        case APP_MAGIC_V1:
+        case BACKUP_HEADER_APP_V1:
             m_header.app.packageLen = fromlel(m_header.app.packageLen);
             if (m_header.app.packageLen < 0) {
                 LOGD("App header at %d has packageLen<0: 0x%08x\n", (int)m_pos,
@@ -289,7 +285,7 @@
             }
             m_header.app.cookie = m_header.app.cookie;
             break;
-        case ENTITY_MAGIC_V1:
+        case BACKUP_HEADER_ENTITY_V1:
             m_header.entity.keyLen = fromlel(m_header.entity.keyLen);
             if (m_header.entity.keyLen <= 0) {
                 LOGD("Entity header at %d has keyLen<=0: 0x%08x\n", (int)m_pos,
@@ -297,14 +293,9 @@
                 m_status = EINVAL;
             }
             m_header.entity.dataSize = fromlel(m_header.entity.dataSize);
-            if (m_header.entity.dataSize < 0) {
-                LOGD("Entity header at %d has dataSize<0: 0x%08x\n", (int)m_pos,
-                        (int)m_header.entity.dataSize);
-                m_status = EINVAL;
-            }
             m_entityCount++;
             break;
-        case FOOTER_MAGIC_V1:
+        case BACKUP_FOOTER_APP_V1:
             m_header.footer.entityCount = fromlel(m_header.footer.entityCount);
             if (m_header.footer.entityCount < 0) {
                 LOGD("Entity header at %d has entityCount<0: 0x%08x\n", (int)m_pos,
@@ -318,6 +309,9 @@
             m_status = EINVAL;
     }
     m_pos += sizeof(m_header);
+    if (type) {
+        *type = m_header.type;
+    }
     
     return m_status;
 }
@@ -328,7 +322,7 @@
     if (m_status != NO_ERROR) {
         return m_status;
     }
-    if (m_header.type != APP_MAGIC_V1) {
+    if (m_header.type != BACKUP_HEADER_APP_V1) {
         return EINVAL;
     }
     size_t size = m_header.app.packageLen;
@@ -349,7 +343,7 @@
 bool
 BackupDataReader::HasEntities()
 {
-    return m_status == NO_ERROR && m_header.type == ENTITY_MAGIC_V1;
+    return m_status == NO_ERROR && m_header.type == BACKUP_HEADER_ENTITY_V1;
 }
 
 status_t
@@ -358,10 +352,10 @@
     if (m_status != NO_ERROR) {
         return m_status;
     }
-    if (m_header.type != ENTITY_MAGIC_V1) {
+    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {
         return EINVAL;
     }
-    size_t size = m_header.app.packageLen;
+    size_t size = m_header.entity.keyLen;
     char* buf = key->lockBuffer(size);
     if (key == NULL) {
         key->unlockBuffer();
@@ -378,6 +372,23 @@
 }
 
 status_t
+BackupDataReader::SkipEntityData()
+{
+    if (m_status != NO_ERROR) {
+        return m_status;
+    }
+    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {
+        return EINVAL;
+    }
+    if (m_header.entity.dataSize > 0) {
+        int pos = lseek(m_fd, m_header.entity.dataSize, SEEK_CUR);
+        return pos == -1 ? (int)errno : (int)NO_ERROR;
+    } else {
+        return NO_ERROR;
+    }
+}
+
+status_t
 BackupDataReader::ReadEntityData(void* data, size_t size)
 {
     if (m_status != NO_ERROR) {
@@ -395,7 +406,7 @@
     if (m_status != NO_ERROR) {
         return m_status;
     }
-    if (m_header.type != FOOTER_MAGIC_V1) {
+    if (m_header.type != BACKUP_FOOTER_APP_V1) {
         return EINVAL;
     }
     if (m_header.footer.entityCount != m_entityCount) {
diff --git a/libs/utils/backup_helper_file.cpp b/libs/utils/backup_helper_file.cpp
index bf56945..8efb3eb 100644
--- a/libs/utils/backup_helper_file.cpp
+++ b/libs/utils/backup_helper_file.cpp
@@ -40,7 +40,7 @@
 #define MAGIC0 0x70616e53 // Snap
 #define MAGIC1 0x656c6946 // File
 
-#if TEST_BACKUP_HELPERS
+#if 0 // TEST_BACKUP_HELPERS
 #define LOGP(x...) printf(x)
 #else
 #define LOGP(x...) LOGD(x)
@@ -181,45 +181,105 @@
 }
 
 static int
-write_delete_file(const String8& key)
+write_delete_file(BackupDataWriter* dataStream, const String8& key)
 {
     LOGP("write_delete_file %s\n", key.string());
-    return 0;
+    return dataStream->WriteEntityHeader(key, -1);
 }
 
 static int
-write_update_file(const String8& realFilename, const String8& key)
+write_update_file(BackupDataWriter* dataStream, int fd, const String8& key,
+        const String8& realFilename)
 {
     LOGP("write_update_file %s (%s)\n", realFilename.string(), key.string());
-    return 0;
+
+    const int bufsize = 4*1024;
+    int err;
+    int amt;
+    int fileSize;
+    int bytesLeft;
+
+    char* buf = (char*)malloc(bufsize);
+    int crc = crc32(0L, Z_NULL, 0);
+
+
+    bytesLeft = fileSize = lseek(fd, 0, SEEK_END);
+    lseek(fd, 0, SEEK_SET);
+
+    err = dataStream->WriteEntityHeader(key, bytesLeft);
+    if (err != 0) {
+        return err;
+    }
+
+    while ((amt = read(fd, buf, bufsize)) != 0 && bytesLeft > 0) {
+        bytesLeft -= amt;
+        if (bytesLeft < 0) {
+            amt += bytesLeft; // Plus a negative is minus.  Don't write more than we promised.
+        }
+        err = dataStream->WriteEntityData(buf, amt);
+        if (err != 0) {
+            return err;
+        }
+    }
+    if (bytesLeft != 0) {
+        if (bytesLeft > 0) {
+            // Pad out the space we promised in the buffer.  We can't corrupt the buffer,
+            // even though the data we're sending is probably bad.
+            memset(buf, 0, bufsize);
+            while (bytesLeft > 0) {
+                amt = bytesLeft < bufsize ? bytesLeft : bufsize;
+                bytesLeft -= amt;
+                err = dataStream->WriteEntityData(buf, amt);
+                if (err != 0) {
+                    return err;
+                }
+            }
+        }
+        LOGE("write_update_file size mismatch for %s. expected=%d actual=%d."
+                " You aren't doing proper locking!",
+                realFilename.string(), fileSize, fileSize-bytesLeft);
+    }
+
+    free(buf);
+
+    return NO_ERROR;
 }
 
 static int
-compute_crc32(const String8& filename)
+write_update_file(BackupDataWriter* dataStream, const String8& key, const String8& realFilename)
+{
+    int err;
+    int fd = open(realFilename.string(), O_RDONLY);
+    if (fd == -1) {
+        return errno;
+    }
+    err = write_update_file(dataStream, fd, key, realFilename);
+    close(fd);
+    return err;
+}
+
+static int
+compute_crc32(int fd)
 {
     const int bufsize = 4*1024;
     int amt;
 
-    int fd = open(filename.string(), O_RDONLY);
-    if (fd == -1) {
-        return -1;
-    }
-
     char* buf = (char*)malloc(bufsize);
     int crc = crc32(0L, Z_NULL, 0);
 
+    lseek(fd, 0, SEEK_SET);
+
     while ((amt = read(fd, buf, bufsize)) != 0) {
         crc = crc32(crc, (Bytef*)buf, amt);
     }
 
-    close(fd);
     free(buf);
 
     return crc;
 }
 
 int
-back_up_files(int oldSnapshotFD, int oldDataStream, int newSnapshotFD,
+back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
         char const* fileBase, char const* const* files, int fileCount)
 {
     int err;
@@ -252,7 +312,8 @@
         s.modTime_nsec = 0; // workaround sim breakage
         //s.modTime_nsec = st.st_mtime_nsec;
         s.size = st.st_size;
-        s.crc32 = compute_crc32(realFilename);
+
+        // we compute the crc32 later down below, when we already have the file open.
 
         newSnapshot.add(name, s);
     }
@@ -270,30 +331,42 @@
             String8 realFilename(base);
             realFilename.appendPath(q);
             LOGP("file added: %s\n", realFilename.string());
-            write_update_file(realFilename, q);
+            write_update_file(dataStream, q, realFilename);
             m++;
         }
         else if (cmp < 0) {
             // file removed
             LOGP("file removed: %s\n", p.string());
-            write_delete_file(p);
+            dataStream->WriteEntityHeader(p, -1);
             n++;
         }
         else {
+
             // both files exist, check them
             String8 realFilename(base);
             realFilename.appendPath(q);
             const FileState& f = oldSnapshot.valueAt(n);
-            const FileState& g = newSnapshot.valueAt(m);
+            FileState& g = newSnapshot.editValueAt(m);
 
-            LOGP("%s\n", q.string());
-            LOGP("  new: modTime=%d,%d size=%-3d crc32=0x%08x\n",
-                    f.modTime_sec, f.modTime_nsec, f.size, f.crc32);
-            LOGP("  old: modTime=%d,%d size=%-3d crc32=0x%08x\n",
-                    g.modTime_sec, g.modTime_nsec, g.size, g.crc32);
-            if (f.modTime_sec != g.modTime_sec || f.modTime_nsec != g.modTime_nsec
-                    || f.size != g.size || f.crc32 != g.crc32) {
-                write_update_file(realFilename, p);
+            int fd = open(realFilename.string(), O_RDONLY);
+            if (fd != -1) {
+                // We can't open the file.  Don't report it as a delete either.  Let the
+                // server keep the old version.  Maybe they'll be able to deal with it
+                // on restore.
+            } else {
+                g.crc32 = compute_crc32(fd);
+
+                LOGP("%s\n", q.string());
+                LOGP("  new: modTime=%d,%d size=%-3d crc32=0x%08x\n",
+                        f.modTime_sec, f.modTime_nsec, f.size, f.crc32);
+                LOGP("  old: modTime=%d,%d size=%-3d crc32=0x%08x\n",
+                        g.modTime_sec, g.modTime_nsec, g.size, g.crc32);
+                if (f.modTime_sec != g.modTime_sec || f.modTime_nsec != g.modTime_nsec
+                        || f.size != g.size || f.crc32 != g.crc32) {
+                    write_update_file(dataStream, fd, p, realFilename);
+                }
+
+                close(fd);
             }
             n++;
             m++;
@@ -302,7 +375,7 @@
 
     // these were deleted
     while (n<N) {
-        write_delete_file(oldSnapshot.keyAt(n));
+        dataStream->WriteEntityHeader(oldSnapshot.keyAt(n), -1);
         n++;
     }
 
@@ -311,7 +384,7 @@
         const String8& q = newSnapshot.keyAt(m);
         String8 realFilename(base);
         realFilename.appendPath(q);
-        write_update_file(realFilename, q);
+        write_update_file(dataStream, q, realFilename);
         m++;
     }
 
@@ -911,10 +984,14 @@
         fprintf(stderr, "error creating: %s\n", strerror(errno));
         return errno;
     }
+
+    {
+        BackupDataWriter dataStream(dataStreamFD);
     
-    err = back_up_files(-1, dataStreamFD, newSnapshotFD, SCRATCH_DIR, files_before, 5);
-    if (err != 0) {
-        return err;
+        err = back_up_files(-1, &dataStream, newSnapshotFD, SCRATCH_DIR, files_before, 5);
+        if (err != 0) {
+            return err;
+        }
     }
 
     close(dataStreamFD);
@@ -968,10 +1045,15 @@
         return errno;
     }
 
-    err = back_up_files(oldSnapshotFD, dataStreamFD, newSnapshotFD, SCRATCH_DIR, files_after, 6);
-    if (err != 0) {
-        return err;
-    }
+    {
+        BackupDataWriter dataStream(dataStreamFD);
+    
+        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, SCRATCH_DIR,
+                files_after, 6);
+        if (err != 0) {
+            return err;
+        }
+}
 
     close(oldSnapshotFD);
     close(dataStreamFD);
diff --git a/opengl/libs/EGL/gpu.cpp b/opengl/libs/EGL/gpu.cpp
index f9dc5f1..4c902c8 100644
--- a/opengl/libs/EGL/gpu.cpp
+++ b/opengl/libs/EGL/gpu.cpp
@@ -118,6 +118,11 @@
         return 0;
     }
 
+    if (info.regs == 0) {
+        LOGD("requestGPU() failed");
+        return 0;
+    }
+
     bool failed = false;
     request_gpu_t* gpu = &gRegions;
     memset(gpu, 0, sizeof(*gpu));