Code drop from //branches/cupcake/...@124589
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 71579c5..7b51300 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -2,7 +2,6 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-	BlitHardware.cpp \
 	Camera.cpp \
 	CameraParameters.cpp \
 	EGLDisplaySurface.cpp \
@@ -14,10 +13,12 @@
 	ICamera.cpp \
 	ICameraClient.cpp \
 	ICameraService.cpp \
+	IOverlay.cpp \
 	ISurfaceComposer.cpp \
 	ISurface.cpp \
 	ISurfaceFlingerClient.cpp \
 	LayerState.cpp \
+	Overlay.cpp \
 	PixelFormat.cpp \
 	Point.cpp \
 	Rect.cpp \
diff --git a/libs/ui/BlitHardware.cpp b/libs/ui/BlitHardware.cpp
deleted file mode 100644
index 90838b4..0000000
--- a/libs/ui/BlitHardware.cpp
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * 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 <stdint.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 <utils/Errors.h>
-
-#if HAVE_ANDROID_OS
-#include <linux/fb.h>
-#include <linux/msm_mdp.h>
-#endif
-
-#include <ui/BlitHardware.h>
-
-/******************************************************************************/
-
-namespace android {
-class CopybitMSM7K : public copybit_t {
-public:
-    CopybitMSM7K();
-    ~CopybitMSM7K();
-    
-    status_t getStatus() const {
-        if (mFD<0) return mFD;
-        return NO_ERROR;
-    }
-
-    status_t setParameter(int name, int value);
-
-    status_t get(int name);
-
-    status_t blit( 
-            const copybit_image_t& dst,
-            const copybit_image_t& src,
-            copybit_region_t const* region);
-
-    status_t stretch( 
-            const copybit_image_t& dst,
-            const copybit_image_t& src, 
-            const copybit_rect_t& dst_rect,
-            const copybit_rect_t& src_rect,
-            copybit_region_t const* region);
-
-#if HAVE_ANDROID_OS
-private:
-    static int copybit_set_parameter(copybit_t* handle, int name, int value);
-    static int copybit_blit( copybit_t* handle, 
-            copybit_image_t const* dst, copybit_image_t const* src,
-            copybit_region_t const* region);
-    static int copybit_stretch(copybit_t* handle, 
-            copybit_image_t const* dst,  copybit_image_t const* src, 
-            copybit_rect_t const* dst_rect, copybit_rect_t const* src_rect,
-            copybit_region_t const* region);
-    static int copybit_get(copybit_t* handle, int name);
-
-    int getFormat(int format);
-    void setImage(mdp_img* img, const copybit_image_t& rhs);
-    void setRects(mdp_blit_req* req, const copybit_rect_t& dst,
-            const copybit_rect_t& src, const copybit_rect_t& scissor);
-    void setInfos(mdp_blit_req* req);
-    static void intersect(copybit_rect_t* out, 
-            const copybit_rect_t& lhs, const copybit_rect_t& rhs);
-    status_t msm_copybit(void const* list);
-#endif
-    int mFD;
-    uint8_t mAlpha;
-    uint8_t mFlags;
-};
-}; // namespace android
-
-using namespace android;
-
-/******************************************************************************/
-
-struct copybit_t* copybit_init()
-{
-    CopybitMSM7K* engine = new CopybitMSM7K();
-    if (engine->getStatus() != NO_ERROR) {
-        delete engine;
-        engine = 0;
-    }
-    return (struct copybit_t*)engine;
-        
-}
-
-int copybit_term(copybit_t* handle)
-{
-    delete static_cast<CopybitMSM7K*>(handle);
-    return NO_ERROR;
-}
-
-namespace android {
-/******************************************************************************/
-
-static inline
-int min(int a, int b) {
-    return (a<b) ? a : b;
-}
-
-static inline
-int max(int a, int b) {
-    return (a>b) ? a : b;
-}
-
-static inline
-void MULDIV(uint32_t& a, uint32_t& b, int mul, int div)
-{
-    if (mul != div) {
-        a = (mul * a) / div;
-        b = (mul * b) / div;
-    }
-}
-
-//-----------------------------------------------------------------------------
-
-#if HAVE_ANDROID_OS
-
-int CopybitMSM7K::copybit_set_parameter(copybit_t* handle, int name, int value)
-{
-    return static_cast<CopybitMSM7K*>(handle)->setParameter(name, value);
-}
-
-int CopybitMSM7K::copybit_get(copybit_t* handle, int name)
-{
-    return static_cast<CopybitMSM7K*>(handle)->get(name);
-}
-
-int CopybitMSM7K::copybit_blit(
-        copybit_t* handle, 
-        copybit_image_t const* dst, 
-        copybit_image_t const* src,
-        struct copybit_region_t const* region)
-{
-    return static_cast<CopybitMSM7K*>(handle)->blit(*dst, *src, region);
-}
-
-int CopybitMSM7K::copybit_stretch(
-        copybit_t* handle, 
-        copybit_image_t const* dst, 
-        copybit_image_t const* src, 
-        copybit_rect_t const* dst_rect,
-        copybit_rect_t const* src_rect,
-        struct copybit_region_t const* region)
-{
-    return static_cast<CopybitMSM7K*>(handle)->stretch(
-            *dst, *src, *dst_rect, *src_rect, region);
-}
-
-//-----------------------------------------------------------------------------
-
-CopybitMSM7K::CopybitMSM7K()
-    : mFD(-1), mAlpha(MDP_ALPHA_NOP), mFlags(0)
-{
-    int fd = open("/dev/graphics/fb0", O_RDWR, 0);
-    if (fd > 0) {
-        struct fb_fix_screeninfo finfo;
-        if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == 0) {
-            if (!strcmp(finfo.id, "msmfb")) {
-                mFD = fd;
-                copybit_t::set_parameter = copybit_set_parameter;
-                copybit_t::get = copybit_get;
-                copybit_t::blit = copybit_blit;
-                copybit_t::stretch = copybit_stretch;
-            }
-        }
-    }
-    if (fd<0 || mFD<0) {
-        if (fd>0) { close(fd); }
-        mFD = -errno;
-    }
-}
-
-CopybitMSM7K::~CopybitMSM7K()
-{
-    if (mFD > 0){
-        close(mFD);
-    }
-}
-
-status_t CopybitMSM7K::setParameter(int name, int value)
-{
-    switch(name) {
-    case COPYBIT_ROTATION_DEG:
-        switch (value) {
-        case 0:
-            mFlags &= ~0x7;
-            break;
-        case 90:
-            mFlags &= ~0x7;
-            mFlags |= MDP_ROT_90;
-            break;
-        case 180:
-            mFlags &= ~0x7;
-            mFlags |= MDP_ROT_180;
-            break;
-        case 270:
-            mFlags &= ~0x7;
-            mFlags |= MDP_ROT_270;
-            break;
-        default:
-            return BAD_VALUE;
-        }
-        break;
-    case COPYBIT_PLANE_ALPHA:
-        if (value < 0)      value = 0;
-        if (value >= 256)   value = 255;
-        mAlpha = value;
-        break;
-    case COPYBIT_DITHER:
-        if (value == COPYBIT_ENABLE) {
-            mFlags |= MDP_DITHER;
-        } else if (value == COPYBIT_DISABLE) {
-            mFlags &= ~MDP_DITHER;
-        }
-        break;
-    case COPYBIT_TRANSFORM:
-        mFlags &= ~0x7;
-        mFlags |= value & 0x7;
-        break;
-    default:
-        return BAD_VALUE;
-    }
-    return NO_ERROR;
-}
-
-status_t CopybitMSM7K::get(int name)
-{
-    switch(name) {
-    case COPYBIT_MINIFICATION_LIMIT:
-        return 4;
-    case COPYBIT_MAGNIFICATION_LIMIT:
-        return 4;
-    case COPYBIT_SCALING_FRAC_BITS:
-        return 32;
-    case COPYBIT_ROTATION_STEP_DEG:
-        return 90;
-    }
-    return BAD_VALUE;
-}
-
-status_t CopybitMSM7K::blit( 
-        const copybit_image_t& dst,
-        const copybit_image_t& src,
-        copybit_region_t const* region)
-{
-    
-    copybit_rect_t dr = { 0, 0, dst.w, dst.h };
-    copybit_rect_t sr = { 0, 0, src.w, src.h };
-    return CopybitMSM7K::stretch(dst, src, dr, sr, region);
-}
-
-status_t CopybitMSM7K::stretch( 
-        const copybit_image_t& dst,
-        const copybit_image_t& src, 
-        const copybit_rect_t& dst_rect,
-        const copybit_rect_t& src_rect,
-        copybit_region_t const* region)
-{
-    struct {
-        uint32_t count;
-        struct mdp_blit_req req[12];
-    } list;
-    
-    if (mAlpha<255) {
-        switch (src.format) {
-            // we dont' support plane alpha with RGBA formats
-            case COPYBIT_RGBA_8888:
-            case COPYBIT_RGBA_5551:
-            case COPYBIT_RGBA_4444:
-                return INVALID_OPERATION;
-        }
-    }
-        
-    const uint32_t maxCount = sizeof(list.req)/sizeof(list.req[0]);
-    const copybit_rect_t bounds = { 0, 0, dst.w, dst.h };
-    copybit_rect_t clip;
-    list.count = 0;
-    int err = 0;
-    while (!err && region->next(region, &clip)) {
-        intersect(&clip, bounds, clip);
-        setInfos(&list.req[list.count]);
-        setImage(&list.req[list.count].dst, dst);
-        setImage(&list.req[list.count].src, src);
-        setRects(&list.req[list.count], dst_rect, src_rect, clip);
-        if (++list.count == maxCount) {
-            err = msm_copybit(&list);
-            list.count = 0;
-        }
-    }
-    if (!err && list.count) {
-        err = msm_copybit(&list);
-    }
-    return err;
-}
-
-status_t CopybitMSM7K::msm_copybit(void const* list)
-{
-    int err = ioctl(mFD, MSMFB_BLIT, static_cast<mdp_blit_req_list const*>(list));
-    LOGE_IF(err<0, "copyBits failed (%s)", strerror(errno));
-    if (err == 0)
-        return NO_ERROR;
-    return -errno;
-}
-
-int CopybitMSM7K::getFormat(int format)
-{
-    switch (format) {
-    case COPYBIT_RGBA_8888:     return MDP_RGBA_8888;
-    case COPYBIT_RGB_565:       return MDP_RGB_565;
-    case COPYBIT_YCbCr_422_SP:  return MDP_Y_CBCR_H2V1;
-    case COPYBIT_YCbCr_420_SP:  return MDP_Y_CBCR_H2V2;
-    }
-    return -1;
-}
-
-void CopybitMSM7K::setInfos(mdp_blit_req* req)
-{
-    req->alpha = mAlpha;
-    req->transp_mask = MDP_TRANSP_NOP;
-    req->flags = mFlags;
-}
-
-void CopybitMSM7K::setImage(mdp_img* img, const copybit_image_t& rhs)
-{
-    img->width      = rhs.w;
-    img->height     = rhs.h;
-    img->format     = getFormat(rhs.format);
-    img->offset     = rhs.offset;
-    img->memory_id  = rhs.fd;
-}
-    
-void CopybitMSM7K::setRects(mdp_blit_req* e, 
-        const copybit_rect_t& dst, const copybit_rect_t& src,
-        const copybit_rect_t& scissor)
-{
-    copybit_rect_t clip;
-    intersect(&clip, scissor, dst);
-
-    e->dst_rect.x  = clip.l;
-    e->dst_rect.y  = clip.t;
-    e->dst_rect.w  = clip.r - clip.l;
-    e->dst_rect.h  = clip.b - clip.t;
-
-    uint32_t W, H;
-    if (mFlags & COPYBIT_TRANSFORM_ROT_90) {
-        e->src_rect.x  = (clip.t - dst.t) + src.t;
-        e->src_rect.y  = (dst.r - clip.r) + src.l;
-        e->src_rect.w  = (clip.b - clip.t);
-        e->src_rect.h  = (clip.r - clip.l);
-        W = dst.b - dst.t;
-        H = dst.r - dst.l;
-    } else {
-        e->src_rect.x  = (clip.l - dst.l) + src.l;
-        e->src_rect.y  = (clip.t - dst.t) + src.t;
-        e->src_rect.w  = (clip.r - clip.l);
-        e->src_rect.h  = (clip.b - clip.t);
-        W = dst.r - dst.l;
-        H = dst.b - dst.t;
-    }
-    MULDIV(e->src_rect.x, e->src_rect.w, src.r - src.l, W);
-    MULDIV(e->src_rect.y, e->src_rect.h, src.b - src.t, H);
-    if (mFlags & COPYBIT_TRANSFORM_FLIP_V) {
-        e->src_rect.y = e->src.height - (e->src_rect.y + e->src_rect.h);
-    }
-    if (mFlags & COPYBIT_TRANSFORM_FLIP_H) {
-        e->src_rect.x = e->src.width  - (e->src_rect.x + e->src_rect.w);
-    }
-}
-
-void CopybitMSM7K::intersect(copybit_rect_t* out, 
-        const copybit_rect_t& lhs, const copybit_rect_t& rhs)
-{
-    out->l = max(lhs.l, rhs.l);
-    out->t = max(lhs.t, rhs.t);
-    out->r = min(lhs.r, rhs.r);
-    out->b = min(lhs.b, rhs.b);
-}
-
-/******************************************************************************/
-#else // HAVE_ANDROID_OS
-
-CopybitMSM7K::CopybitMSM7K()
-    : mFD(-1)
-{
-}
-
-CopybitMSM7K::~CopybitMSM7K()
-{
-}
-
-status_t CopybitMSM7K::setParameter(int name, int value)
-{
-    return NO_INIT;
-}
-
-status_t CopybitMSM7K::get(int name)
-{
-    return BAD_VALUE;
-}
-
-status_t CopybitMSM7K::blit( 
-        const copybit_image_t& dst,
-        const copybit_image_t& src,
-        copybit_region_t const* region)
-{
-    return NO_INIT;
-}
-
-status_t CopybitMSM7K::stretch( 
-        const copybit_image_t& dst,
-        const copybit_image_t& src, 
-        const copybit_rect_t& dst_rect,
-        const copybit_rect_t& src_rect,
-        copybit_region_t const* region)
-{
-    return NO_INIT;
-}
-
-#endif // HAVE_ANDROID_OS
-
-/******************************************************************************/
-}; // namespace android
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
index 1528e6e..9527009 100644
--- a/libs/ui/Camera.cpp
+++ b/libs/ui/Camera.cpp
@@ -1,28 +1,28 @@
 /*
 **
-** Copyright 2008, The Android Open Source Project
+** 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 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
+//#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>
 
@@ -60,20 +60,36 @@
 // ---------------------------------------------------------------------------
 
 Camera::Camera()
-      : mStatus(UNKNOWN_ERROR),
-        mShutterCallback(0),
-        mShutterCallbackCookie(0),
-        mRawCallback(0),
-        mRawCallbackCookie(0),
-        mJpegCallback(0),
-        mJpegCallbackCookie(0),
-        mFrameCallback(0),
-        mFrameCallbackCookie(0),
-        mErrorCallback(0),
-        mErrorCallbackCookie(0),
-        mAutoFocusCallback(0),
-        mAutoFocusCallbackCookie(0)
 {
+    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;
+    mFrameCallback = 0;
+    mFrameCallbackCookie = 0;
+    mErrorCallback = 0;
+    mErrorCallbackCookie = 0;
+    mAutoFocusCallback = 0;
+    mAutoFocusCallbackCookie = 0;
 }
 
 Camera::~Camera()
@@ -83,6 +99,7 @@
 
 sp<Camera> Camera::connect()
 {
+    LOGV("connect");
     sp<Camera> c = new Camera();
     const sp<ICameraService>& cs = getCameraService();
     if (cs != 0) {
@@ -97,6 +114,7 @@
 
 void Camera::disconnect()
 {
+    LOGV("disconnect");
     if (mCamera != 0) {
         mErrorCallback = 0;
         mCamera->disconnect();
@@ -104,9 +122,24 @@
     }
 }
 
+status_t Camera::reconnect()
+{
+    LOGV("reconnect");
+    if (mCamera != 0) {
+        return mCamera->connect(this);
+    }
+    return NO_INIT;
+}
+
+sp<ICamera> Camera::remote()
+{
+    return mCamera;
+}
+
 // 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;
@@ -114,81 +147,105 @@
     return mCamera->setPreviewDisplay(surface->getISurface());
 }
 
+status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
+{
+    LOGV("setPreviewDisplay");
+    if (surface == 0) {
+        LOGE("app passed NULL surface");
+        return NO_INIT;
+    }
+    return mCamera->setPreviewDisplay(surface);
+}
+
+
 // start preview mode, must call setPreviewDisplay first
 status_t Camera::startPreview()
 {
+    LOGV("startPreview");
     return mCamera->startPreview();
 }
 
 // stop preview mode
 void Camera::stopPreview()
 {
+    LOGV("stopPreview");
     mCamera->stopPreview();
 }
 
 status_t Camera::autoFocus()
 {
+    LOGV("autoFocus");
     return mCamera->autoFocus();
 }
 
 // take a picture
 status_t Camera::takePicture()
 {
+    LOGV("takePicture");
     return mCamera->takePicture();
 }
 
 // set preview/capture parameters - key/value pairs
 status_t Camera::setParameters(const String8& params)
 {
+    LOGV("setParameters");
     return mCamera->setParameters(params);
 }
 
 // get preview/capture parameters - key/value pairs
 String8 Camera::getParameters() const
 {
+    LOGV("getParameters");
     String8 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::setFrameCallback(frame_callback cb, void *cookie)
+void Camera::setFrameCallback(frame_callback cb, void *cookie, int frame_callback_flag)
 {
+    LOGV("setFrameCallback");
     mFrameCallback = cb;
     mFrameCallbackCookie = cookie;
-    mCamera->setHasFrameCallback(cb != NULL);
+    mCamera->setFrameCallbackFlag(frame_callback_flag);
 }
 
 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);
     }
@@ -196,6 +253,7 @@
 
 void Camera::shutterCallback()
 {
+    LOGV("shutterCallback");
     if (mShutterCallback) {
         mShutterCallback(mShutterCallbackCookie);
     }
@@ -203,6 +261,7 @@
 
 void Camera::rawCallback(const sp<IMemory>& picture)
 {
+    LOGV("rawCallback");
     if (mRawCallback) {
         mRawCallback(picture, mRawCallbackCookie);
     }
@@ -211,6 +270,7 @@
 // callback from camera service when image is ready
 void Camera::jpegCallback(const sp<IMemory>& picture)
 {
+    LOGV("jpegCallback");
     if (mJpegCallback) {
         mJpegCallback(picture, mJpegCallbackCookie);
     }
@@ -219,6 +279,7 @@
 // callback from camera service when video frame is ready
 void Camera::frameCallback(const sp<IMemory>& frame)
 {
+    LOGV("frameCallback");
     if (mFrameCallback) {
         mFrameCallback(frame, mFrameCallbackCookie);
     }
@@ -227,19 +288,21 @@
 // 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) {    
+void Camera::binderDied(const wp<IBinder>& who) {
     LOGW("ICamera died");
     if (mErrorCallback) {
         mErrorCallback(DEAD_OBJECT, mErrorCallbackCookie);
     }
 }
 
-void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {    
+void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
+    LOGV("binderDied");
     Mutex::Autolock _l(Camera::mLock);
     Camera::mCameraService.clear();
     LOGW("Camera server died!");
diff --git a/libs/ui/EGLDisplaySurface.cpp b/libs/ui/EGLDisplaySurface.cpp
index ea245f5..44258a8 100644
--- a/libs/ui/EGLDisplaySurface.cpp
+++ b/libs/ui/EGLDisplaySurface.cpp
@@ -28,11 +28,15 @@
 
 #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>
@@ -42,7 +46,6 @@
 
 #include <pixelflinger/format.h>
 
-#include <ui/EGLDisplaySurface.h>
 
 // ----------------------------------------------------------------------------
 
@@ -78,7 +81,12 @@
     mBlitEngine = 0;
     egl_native_window_t::fd = mapFrameBuffer();
     if (egl_native_window_t::fd >= 0) {
-        mBlitEngine = copybit_init();
+        
+        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 )
@@ -108,7 +116,7 @@
 EGLDisplaySurface::~EGLDisplaySurface()
 {
     magic = 0;
-    copybit_term(mBlitEngine);
+    copybit_close(mBlitEngine);
     mBlitEngine = 0;
     close(egl_native_window_t::fd);
     munmap(mFb[0].data, mSize);
@@ -147,9 +155,6 @@
 
 uint32_t EGLDisplaySurface::swapBuffers()
 {
-    if (!(mFlags & PAGE_FLIP))
-        return 0;
-
 #define SHOW_FPS 0
 #if SHOW_FPS
     nsecs_t now = systemTime();
@@ -171,6 +176,11 @@
         }
     }
 #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;
@@ -192,7 +202,7 @@
      * with msm7k.
      */
     if (egl_native_window_t::memory_type == NATIVE_MEMORY_TYPE_GPU && oem[0] && mBlitEngine) {
-        copybit_t *copybit = 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 = {
@@ -273,6 +283,12 @@
     } 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;
@@ -373,12 +389,11 @@
         // 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  = 51;
-        info.height = 38;
+        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;
diff --git a/libs/ui/EGLNativeWindowSurface.cpp b/libs/ui/EGLNativeWindowSurface.cpp
index 0b6afc0..d55fb70 100644
--- a/libs/ui/EGLNativeWindowSurface.cpp
+++ b/libs/ui/EGLNativeWindowSurface.cpp
@@ -163,7 +163,12 @@
         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);
-        egl_native_window_t::memory_type = mSurface->getMemoryType();
+        // 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;
     }
 }
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index f0c77ba..abe7407 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -315,9 +315,8 @@
         }
 
         //printf("poll %d, returned %d\n", mFDCount, pollres);
-        if(mFDs[0].revents & POLLIN) {
-            read_notify(mFDs[0].fd);
-        }
+
+        // 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);
@@ -357,6 +356,12 @@
                 }
             }
         }
+        
+        // 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);
+        }
     }
 }
 
@@ -607,7 +612,7 @@
         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",
+        LOGI("New keyboard: publicID=%d device->id=%d devname='%s' propName='%s' keylayout='%s'\n",
                 publicID, device->id, devname, propName, keylayoutFilename);
     }
 
diff --git a/libs/ui/ICamera.cpp b/libs/ui/ICamera.cpp
index 420bb49..6a2dc6b 100644
--- a/libs/ui/ICamera.cpp
+++ b/libs/ui/ICamera.cpp
@@ -2,41 +2,40 @@
 **
 ** Copyright 2008, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
+//#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>
 
-#define LOG_TAG "@@@@@@@@@@@ CAMERA @@@@@@@@@@@"
-#include <utils/Log.h>
-
 namespace android {
 
 enum {
     DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
     SET_PREVIEW_DISPLAY,
-    SET_HAS_FRAME_CALLBACK,
+    SET_FRAME_CALLBACK_FLAG,
     START_PREVIEW,
     STOP_PREVIEW,
     AUTO_FOCUS,
     TAKE_PICTURE,
     SET_PARAMETERS,
-    GET_PARAMETERS
+    GET_PARAMETERS,
+    CONNECT
 };
 
 class BpCamera: public BpInterface<ICamera>
@@ -50,6 +49,7 @@
     // disconnect from camera service
     void disconnect()
     {
+        LOGV("disconnect");
         Parcel data, reply;
         data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
         remote()->transact(DISCONNECT, data, &reply);
@@ -58,25 +58,29 @@
     // 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();
     }
-    
-    // tell the service whether to callback with each preview frame
-    void setHasFrameCallback(bool installed)
+
+    // set the frame callback flag to affect how the received frames from
+    // preview are handled.
+    void setFrameCallbackFlag(int frame_callback_flag)
     {
+        LOGV("setFrameCallbackFlag(%d)", frame_callback_flag);
         Parcel data, reply;
         data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        data.writeInt32((int32_t)installed);
-        remote()->transact(SET_HAS_FRAME_CALLBACK, data, &reply);
+        data.writeInt32(frame_callback_flag);
+        remote()->transact(SET_FRAME_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);
@@ -86,6 +90,7 @@
     // stop preview mode
     void stopPreview()
     {
+        LOGV("stopPreview");
         Parcel data, reply;
         data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
         remote()->transact(STOP_PREVIEW, data, &reply);
@@ -94,6 +99,7 @@
     // auto focus
     status_t autoFocus()
     {
+        LOGV("autoFocus");
         Parcel data, reply;
         data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
         remote()->transact(AUTO_FOCUS, data, &reply);
@@ -104,6 +110,7 @@
     // 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);
@@ -114,6 +121,7 @@
     // 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);
@@ -124,11 +132,20 @@
     // 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();
+    }
 };
 
 IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera");
@@ -146,53 +163,68 @@
 {
     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_HAS_FRAME_CALLBACK: {
+        case SET_FRAME_CALLBACK_FLAG: {
+            LOGV("SET_FRAME_CALLBACK_TYPE");
             CHECK_INTERFACE(ICamera, data, reply);
-            bool installed = (bool)data.readInt32();
-            setHasFrameCallback(installed);
+            int frame_callback_flag = data.readInt32();
+            setFrameCallbackFlag(frame_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 STOP_PREVIEW: {
+            LOGV("STOP_PREVIEW");
             CHECK_INTERFACE(ICamera, data, reply);
             stopPreview();
             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));
+            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;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libs/ui/ICameraClient.cpp b/libs/ui/ICameraClient.cpp
index 3737034..c5d6d52 100644
--- a/libs/ui/ICameraClient.cpp
+++ b/libs/ui/ICameraClient.cpp
@@ -15,9 +15,11 @@
 ** 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 {
@@ -42,6 +44,7 @@
     // 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);
@@ -50,6 +53,7 @@
     // 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());
@@ -59,6 +63,7 @@
     // 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());
@@ -68,6 +73,7 @@
     // callback from camera service to app with video frame data
     void frameCallback(const sp<IMemory>& frame)
     {
+        LOGV("frameCallback");
         Parcel data, reply;
         data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
         data.writeStrongBinder(frame->asBinder());
@@ -77,6 +83,7 @@
     // 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);
@@ -86,6 +93,7 @@
     // 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);
@@ -108,35 +116,41 @@
 {
     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 FRAME_CALLBACK: {
+            LOGV("FRAME_CALLBACK");
             CHECK_INTERFACE(ICameraClient, data, reply);
             sp<IMemory> frame = interface_cast<IMemory>(data.readStrongBinder());
             frameCallback(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);
diff --git a/libs/ui/IOverlay.cpp b/libs/ui/IOverlay.cpp
new file mode 100644
index 0000000..59d1ea0
--- /dev/null
+++ b/libs/ui/IOverlay.cpp
@@ -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.
+ */
+
+#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
+    SWAP_BUFFERS,
+};
+
+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);
+    }
+
+    virtual ssize_t swapBuffers()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOverlay::getInterfaceDescriptor());
+        remote()->transact(SWAP_BUFFERS, data, &reply);
+        return reply.readInt32();
+    }
+};
+
+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;
+        case SWAP_BUFFERS: {
+            CHECK_INTERFACE(IOverlay, data, reply);
+            ssize_t offset = swapBuffers();
+            reply->writeInt32(offset);
+            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
index 817f4d9..c1c9596 100644
--- a/libs/ui/ISurface.cpp
+++ b/libs/ui/ISurface.cpp
@@ -22,6 +22,7 @@
 #include <utils/IMemory.h>
 
 #include <ui/ISurface.h>
+#include <ui/Overlay.h>
 
 
 namespace android {
@@ -30,6 +31,7 @@
     REGISTER_BUFFERS = IBinder::FIRST_CALL_TRANSACTION,
     UNREGISTER_BUFFERS,
     POST_BUFFER, // one-way transaction
+    CREATE_OVERLAY,
 };
 
 class BpSurface : public BpInterface<ISurface>
@@ -70,6 +72,18 @@
         data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
         remote()->transact(UNREGISTER_BUFFERS, data, &reply);
     }
+
+    virtual sp<Overlay> 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 Overlay::readFromParcel(reply);
+    }
 };
 
 IMPLEMENT_META_INTERFACE(Surface, "android.ui.ISurface");
@@ -109,6 +123,14 @@
             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<Overlay> o = createOverlay(w, h, w);
+            return Overlay::writeToParcel(reply, o);
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libs/ui/ISurfaceFlingerClient.cpp b/libs/ui/ISurfaceFlingerClient.cpp
index 9444af7..dd6a798 100644
--- a/libs/ui/ISurfaceFlingerClient.cpp
+++ b/libs/ui/ISurfaceFlingerClient.cpp
@@ -82,7 +82,7 @@
         data.writeInt32(format);
         data.writeInt32(flags);
         remote()->transact(CREATE_SURFACE, data, &reply);
-        params->readFromParcel(data);
+        params->readFromParcel(reply);
         return interface_cast<ISurface>(reply.readStrongBinder());
     }
                                     
@@ -191,7 +191,6 @@
 {
     token = parcel.readInt32();
     identity  = parcel.readInt32();
-    type = parcel.readInt32();
     heap[0] = interface_cast<IMemoryHeap>(parcel.readStrongBinder());
     heap[1] = interface_cast<IMemoryHeap>(parcel.readStrongBinder());
     return NO_ERROR;
@@ -201,7 +200,6 @@
 {
     parcel->writeInt32(token);
     parcel->writeInt32(identity);
-    parcel->writeInt32(type);
     parcel->writeStrongBinder(heap[0]!=0 ? heap[0]->asBinder() : NULL);
     parcel->writeStrongBinder(heap[1]!=0 ? heap[1]->asBinder() : NULL);
     return NO_ERROR;
diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp
new file mode 100644
index 0000000..2267c3e
--- /dev/null
+++ b/libs/ui/Overlay.cpp
@@ -0,0 +1,145 @@
+/*
+ * 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 <ui/IOverlay.h>
+#include <ui/Overlay.h>
+
+namespace android {
+
+Overlay::Overlay(overlay_handle_t* handle, 
+        const sp<IOverlay>& o, const sp<IMemoryHeap>& heap, 
+        uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs)
+    : mOverlay(o), mHeap(heap), mCurrentBufferOffset(0), mOverlayHandle(handle),
+      mWidth(w), mHeight(h), mFormat(f), mWidthStride(ws), mHeightStride(hs)
+{
+}
+
+Overlay::Overlay(overlay_t* overlay, 
+        const sp<IOverlay>& o, const sp<IMemoryHeap>& heap)
+    : mOverlay(o), mHeap(heap) 
+{
+    mCurrentBufferOffset = 0; 
+    mOverlayHandle = overlay->getHandleRef(overlay);
+    mWidth = overlay->w;
+    mHeight = overlay->h;
+    mFormat = overlay->format; 
+    mWidthStride = overlay->w_stride;
+    mHeightStride = overlay->h_stride;
+}
+
+
+Overlay::~Overlay() {
+}
+
+void Overlay::destroy() {  
+    mOverlay->destroy();
+}
+
+status_t Overlay::swapBuffers() {
+    ssize_t result = mOverlay->swapBuffers();
+    if (result < 0)
+        return status_t(result);
+    mCurrentBufferOffset = result;
+    return NO_ERROR;
+}
+
+overlay_handle_t const* Overlay::getHandleRef() const {
+    return mOverlayHandle;
+}
+
+size_t Overlay::getBufferOffset() const {
+    return mCurrentBufferOffset;
+}
+
+sp<IMemoryHeap> Overlay::getHeap() const {
+    return mHeap;
+}
+
+uint32_t Overlay::getWidth() const {
+    return mWidth;
+}
+
+uint32_t Overlay::getHeight() const {
+    return mHeight;
+}
+
+int32_t Overlay::getFormat() const {
+    return mFormat;
+}
+
+int32_t Overlay::getWidthStride() const {
+    return mWidthStride;
+}
+
+int32_t Overlay::getHeightStride() const {
+    return mHeightStride;
+}
+
+sp<Overlay> Overlay::readFromParcel(const Parcel& data) {
+    sp<Overlay> result;
+    sp<IOverlay> overlay = IOverlay::asInterface(data.readStrongBinder());
+    if (overlay != NULL) {
+        sp<IMemoryHeap> heap = IMemoryHeap::asInterface(data.readStrongBinder());
+        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();
+        /* FIXME: handles should be promoted to "real" API and be handled by 
+         * the framework */
+        int numfd = data.readInt32();
+        int numint = data.readInt32();
+        overlay_handle_t* handle = (overlay_handle_t*)malloc(
+                sizeof(overlay_handle_t) + numint*sizeof(int));
+        for (int i=0 ; i<numfd ; i++)
+            handle->fds[i] = data.readFileDescriptor();
+        for (int i=0 ; i<numint ; i++)
+            handle->data[i] = data.readInt32();
+        result = new Overlay(handle, overlay, heap, w, h, f, ws, hs);
+    }
+    return result;
+}
+
+status_t Overlay::writeToParcel(Parcel* reply, const sp<Overlay>& o) {
+    if (o != NULL) {
+        reply->writeStrongBinder(o->mOverlay->asBinder());
+        reply->writeStrongBinder(o->mHeap->asBinder());
+        reply->writeInt32(o->mWidth);
+        reply->writeInt32(o->mHeight);
+        reply->writeInt32(o->mFormat);
+        reply->writeInt32(o->mWidthStride);
+        reply->writeInt32(o->mHeightStride);
+        /* FIXME: handles should be promoted to "real" API and be handled by 
+         * the framework */
+        reply->writeInt32(o->mOverlayHandle->numFds);
+        reply->writeInt32(o->mOverlayHandle->numInts);
+        for (int i=0 ; i<o->mOverlayHandle->numFds ; i++)
+            reply->writeFileDescriptor(o->mOverlayHandle->fds[i]);
+        for (int i=0 ; i<o->mOverlayHandle->numInts ; i++)
+            reply->writeInt32(o->mOverlayHandle->data[i]);
+    } else {
+        reply->writeStrongBinder(NULL);
+    }
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
index 0a9aaad..4ea9ae2 100644
--- a/libs/ui/Surface.cpp
+++ b/libs/ui/Surface.cpp
@@ -47,7 +47,7 @@
         const ISurfaceFlingerClient::surface_data_t& data,
         uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
         bool owner)
-    : mClient(client), mSurface(surface), mMemoryType(data.type),
+    : mClient(client), mSurface(surface),
       mToken(data.token), mIdentity(data.identity),
       mFormat(format), mFlags(flags), mOwner(owner)
 {
@@ -67,7 +67,6 @@
     mSurface = rhs->mSurface;
     mHeap[0] = rhs->mHeap[0];
     mHeap[1] = rhs->mHeap[1];
-    mMemoryType = rhs->mMemoryType;
     mFormat  = rhs->mFormat;
     mFlags   = rhs->mFlags;
     mSurfaceHeapBase[0] = rhs->mSurfaceHeapBase[0];
@@ -186,7 +185,6 @@
     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.type               = parcel->readInt32();
     data.token              = parcel->readInt32();
     data.identity           = parcel->readInt32();
     PixelFormat format      = parcel->readInt32();
@@ -207,7 +205,6 @@
     sp<SurfaceComposerClient> client;
     sp<ISurface> sur;
     sp<IMemoryHeap> heap[2];
-    int type = 0;
     if (surface->isValid()) {
         token = surface->mToken;
         identity = surface->mIdentity;
@@ -215,7 +212,6 @@
         sur = surface->mSurface;
         heap[0] = surface->mHeap[0];
         heap[1] = surface->mHeap[1];
-        type = surface->mMemoryType;
         format = surface->mFormat;
         flags = surface->mFlags;
     }
@@ -223,7 +219,6 @@
     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(type);
     parcel->writeInt32(token);
     parcel->writeInt32(identity);
     parcel->writeInt32(format);
diff --git a/libs/ui/Time.cpp b/libs/ui/Time.cpp
index c98667f..b553913 100644
--- a/libs/ui/Time.cpp
+++ b/libs/ui/Time.cpp
@@ -85,10 +85,10 @@
 }
 
 String8 
-Time::format(const char *format) const
+Time::format(const char *format, const struct strftime_locale *locale) const
 {
     char buf[257];
-    int n = strftime(buf, 257, format, &(this->t));
+    int n = strftime_tz(buf, 257, format, &(this->t), locale);
     if (n > 0) {
         return String8(buf);
     } else {