diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 84aec61..f7acd97 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -2,8 +2,6 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-	Camera.cpp \
-	CameraParameters.cpp \
 	EGLUtils.cpp \
 	EventHub.cpp \
 	EventRecurrence.cpp \
@@ -13,21 +11,11 @@
 	GraphicBufferMapper.cpp \
 	KeyLayoutMap.cpp \
 	KeyCharacterMap.cpp \
-	ICamera.cpp \
-	ICameraClient.cpp \
-	ICameraService.cpp \
 	IOverlay.cpp \
-	ISurfaceComposer.cpp \
-	ISurface.cpp \
-	ISurfaceFlingerClient.cpp \
-	LayerState.cpp \
 	Overlay.cpp \
 	PixelFormat.cpp \
 	Rect.cpp \
-	Region.cpp \
-	SharedBufferStack.cpp \
-	Surface.cpp \
-	SurfaceComposerClient.cpp
+	Region.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
deleted file mode 100644
index f374fbc..0000000
--- a/libs/ui/Camera.cpp
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
-**
-** Copyright (C) 2008, The Android Open Source Project
-** Copyright (C) 2008 HTC Inc.
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "Camera"
-#include <utils/Log.h>
-#include <binder/IServiceManager.h>
-#include <utils/threads.h>
-#include <binder/IMemory.h>
-#include <ui/Surface.h>
-#include <ui/Camera.h>
-#include <ui/ICameraService.h>
-
-namespace android {
-
-// client singleton for camera service binder interface
-Mutex Camera::mLock;
-sp<ICameraService> Camera::mCameraService;
-sp<Camera::DeathNotifier> Camera::mDeathNotifier;
-
-// establish binder interface to camera service
-const sp<ICameraService>& Camera::getCameraService()
-{
-    Mutex::Autolock _l(mLock);
-    if (mCameraService.get() == 0) {
-        sp<IServiceManager> sm = defaultServiceManager();
-        sp<IBinder> binder;
-        do {
-            binder = sm->getService(String16("media.camera"));
-            if (binder != 0)
-                break;
-            LOGW("CameraService not published, waiting...");
-            usleep(500000); // 0.5 s
-        } while(true);
-        if (mDeathNotifier == NULL) {
-            mDeathNotifier = new DeathNotifier();
-        }
-        binder->linkToDeath(mDeathNotifier);
-        mCameraService = interface_cast<ICameraService>(binder);
-    }
-    LOGE_IF(mCameraService==0, "no CameraService!?");
-    return mCameraService;
-}
-
-// ---------------------------------------------------------------------------
-
-Camera::Camera()
-{
-    init();
-}
-
-// construct a camera client from an existing camera remote
-sp<Camera> Camera::create(const sp<ICamera>& camera)
-{
-     LOGV("create");
-     if (camera == 0) {
-         LOGE("camera remote is a NULL pointer");
-         return 0;
-     }
-
-    sp<Camera> c = new Camera();
-    if (camera->connect(c) == NO_ERROR) {
-        c->mStatus = NO_ERROR;
-        c->mCamera = camera;
-        camera->asBinder()->linkToDeath(c);
-    }
-    return c;
-}
-
-void Camera::init()
-{
-    mStatus = UNKNOWN_ERROR;
-}
-
-Camera::~Camera()
-{
-    disconnect();
-}
-
-sp<Camera> Camera::connect()
-{
-    LOGV("connect");
-    sp<Camera> c = new Camera();
-    const sp<ICameraService>& cs = getCameraService();
-    if (cs != 0) {
-        c->mCamera = cs->connect(c);
-    }
-    if (c->mCamera != 0) {
-        c->mCamera->asBinder()->linkToDeath(c);
-        c->mStatus = NO_ERROR;
-    } else {
-        c.clear();
-    }
-    return c;
-}
-
-void Camera::disconnect()
-{
-    LOGV("disconnect");
-    if (mCamera != 0) {
-        mCamera->disconnect();
-        mCamera = 0;
-    }
-}
-
-status_t Camera::reconnect()
-{
-    LOGV("reconnect");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return NO_INIT;
-    return c->connect(this);
-}
-
-sp<ICamera> Camera::remote()
-{
-    return mCamera;
-}
-
-status_t Camera::lock()
-{
-    sp <ICamera> c = mCamera;
-    if (c == 0) return NO_INIT;
-    return c->lock();
-}
-
-status_t Camera::unlock()
-{
-    sp <ICamera> c = mCamera;
-    if (c == 0) return NO_INIT;
-    return c->unlock();
-}
-
-// pass the buffered ISurface to the camera service
-status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
-{
-    LOGV("setPreviewDisplay");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return NO_INIT;
-    if (surface != 0) {
-        return c->setPreviewDisplay(surface->getISurface());
-    } else {
-        LOGD("app passed NULL surface");
-        return c->setPreviewDisplay(0);
-    }
-}
-
-status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
-{
-    LOGV("setPreviewDisplay");
-    if (surface == 0) {
-        LOGD("app passed NULL surface");
-    }
-    sp <ICamera> c = mCamera;
-    if (c == 0) return NO_INIT;
-    return c->setPreviewDisplay(surface);
-}
-
-
-// start preview mode
-status_t Camera::startPreview()
-{
-    LOGV("startPreview");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return NO_INIT;
-    return c->startPreview();
-}
-
-// start recording mode, must call setPreviewDisplay first
-status_t Camera::startRecording()
-{
-    LOGV("startRecording");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return NO_INIT;
-    return c->startRecording();
-}
-
-// stop preview mode
-void Camera::stopPreview()
-{
-    LOGV("stopPreview");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return;
-    c->stopPreview();
-}
-
-// stop recording mode
-void Camera::stopRecording()
-{
-    LOGV("stopRecording");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return;
-    c->stopRecording();
-}
-
-// release a recording frame
-void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
-{
-    LOGV("releaseRecordingFrame");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return;
-    c->releaseRecordingFrame(mem);
-}
-
-// get preview state
-bool Camera::previewEnabled()
-{
-    LOGV("previewEnabled");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return false;
-    return c->previewEnabled();
-}
-
-// get recording state
-bool Camera::recordingEnabled()
-{
-    LOGV("recordingEnabled");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return false;
-    return c->recordingEnabled();
-}
-
-status_t Camera::autoFocus()
-{
-    LOGV("autoFocus");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return NO_INIT;
-    return c->autoFocus();
-}
-
-status_t Camera::cancelAutoFocus()
-{
-    LOGV("cancelAutoFocus");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return NO_INIT;
-    return c->cancelAutoFocus();
-}
-
-// take a picture
-status_t Camera::takePicture()
-{
-    LOGV("takePicture");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return NO_INIT;
-    return c->takePicture();
-}
-
-// set preview/capture parameters - key/value pairs
-status_t Camera::setParameters(const String8& params)
-{
-    LOGV("setParameters");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return NO_INIT;
-    return c->setParameters(params);
-}
-
-// get preview/capture parameters - key/value pairs
-String8 Camera::getParameters() const
-{
-    LOGV("getParameters");
-    String8 params;
-    sp <ICamera> c = mCamera;
-    if (c != 0) params = mCamera->getParameters();
-    return params;
-}
-
-// send command to camera driver
-status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
-{
-    LOGV("sendCommand");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return NO_INIT;
-    return c->sendCommand(cmd, arg1, arg2);
-}
-
-void Camera::setListener(const sp<CameraListener>& listener)
-{
-    Mutex::Autolock _l(mLock);
-    mListener = listener;
-}
-
-void Camera::setPreviewCallbackFlags(int flag)
-{
-    LOGV("setPreviewCallbackFlags");
-    sp <ICamera> c = mCamera;
-    if (c == 0) return;
-    mCamera->setPreviewCallbackFlag(flag);
-}
-
-// callback from camera service
-void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
-{
-    sp<CameraListener> listener;
-    {
-        Mutex::Autolock _l(mLock);
-        listener = mListener;
-    }
-    if (listener != NULL) {
-        listener->notify(msgType, ext1, ext2);
-    }
-}
-
-// callback from camera service when frame or image is ready
-void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
-{
-    sp<CameraListener> listener;
-    {
-        Mutex::Autolock _l(mLock);
-        listener = mListener;
-    }
-    if (listener != NULL) {
-        listener->postData(msgType, dataPtr);
-    }
-}
-
-// callback from camera service when timestamped frame is ready
-void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
-{
-    sp<CameraListener> listener;
-    {
-        Mutex::Autolock _l(mLock);
-        listener = mListener;
-    }
-    if (listener != NULL) {
-        listener->postDataTimestamp(timestamp, msgType, dataPtr);
-    }
-}
-
-void Camera::binderDied(const wp<IBinder>& who) {
-    LOGW("ICamera died");
-    notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
-}
-
-void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
-    LOGV("binderDied");
-    Mutex::Autolock _l(Camera::mLock);
-    Camera::mCameraService.clear();
-    LOGW("Camera server died!");
-}
-
-}; // namespace android
-
diff --git a/libs/ui/CameraParameters.cpp b/libs/ui/CameraParameters.cpp
deleted file mode 100644
index 493b9c1..0000000
--- a/libs/ui/CameraParameters.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "CameraParams"
-#include <utils/Log.h>
-
-#include <string.h>
-#include <stdlib.h>
-#include <ui/CameraParameters.h>
-
-namespace android {
-// Parameter keys to communicate between camera application and driver.
-const char CameraParameters::KEY_PREVIEW_SIZE[] = "preview-size";
-const char CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES[] = "preview-size-values";
-const char CameraParameters::KEY_PREVIEW_FORMAT[] = "preview-format";
-const char CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS[] = "preview-format-values";
-const char CameraParameters::KEY_PREVIEW_FRAME_RATE[] = "preview-frame-rate";
-const char CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES[] = "preview-frame-rate-values";
-const char CameraParameters::KEY_PICTURE_SIZE[] = "picture-size";
-const char CameraParameters::KEY_SUPPORTED_PICTURE_SIZES[] = "picture-size-values";
-const char CameraParameters::KEY_PICTURE_FORMAT[] = "picture-format";
-const char CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS[] = "picture-format-values";
-const char CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH[] = "jpeg-thumbnail-width";
-const char CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT[] = "jpeg-thumbnail-height";
-const char CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[] = "jpeg-thumbnail-size-values";
-const char CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY[] = "jpeg-thumbnail-quality";
-const char CameraParameters::KEY_JPEG_QUALITY[] = "jpeg-quality";
-const char CameraParameters::KEY_ROTATION[] = "rotation";
-const char CameraParameters::KEY_GPS_LATITUDE[] = "gps-latitude";
-const char CameraParameters::KEY_GPS_LONGITUDE[] = "gps-longitude";
-const char CameraParameters::KEY_GPS_ALTITUDE[] = "gps-altitude";
-const char CameraParameters::KEY_GPS_TIMESTAMP[] = "gps-timestamp";
-const char CameraParameters::KEY_WHITE_BALANCE[] = "whitebalance";
-const char CameraParameters::KEY_SUPPORTED_WHITE_BALANCE[] = "whitebalance-values";
-const char CameraParameters::KEY_EFFECT[] = "effect";
-const char CameraParameters::KEY_SUPPORTED_EFFECTS[] = "effect-values";
-const char CameraParameters::KEY_ANTIBANDING[] = "antibanding";
-const char CameraParameters::KEY_SUPPORTED_ANTIBANDING[] = "antibanding-values";
-const char CameraParameters::KEY_SCENE_MODE[] = "scene-mode";
-const char CameraParameters::KEY_SUPPORTED_SCENE_MODES[] = "scene-mode-values";
-const char CameraParameters::KEY_FLASH_MODE[] = "flash-mode";
-const char CameraParameters::KEY_SUPPORTED_FLASH_MODES[] = "flash-mode-values";
-const char CameraParameters::KEY_FOCUS_MODE[] = "focus-mode";
-const char CameraParameters::KEY_SUPPORTED_FOCUS_MODES[] = "focus-mode-values";
-const char CameraParameters::KEY_FOCAL_LENGTH[] = "focal-length";
-const char CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE[] = "horizontal-view-angle";
-const char CameraParameters::KEY_VERTICAL_VIEW_ANGLE[] = "vertical-view-angle";
-const char CameraParameters::KEY_EXPOSURE_COMPENSATION[] = "exposure-compensation";
-const char CameraParameters::KEY_SUPPORTED_EXPOSURE_COMPENSATION[] = "exposure-compensation-values";
-
-// Values for white balance settings.
-const char CameraParameters::WHITE_BALANCE_AUTO[] = "auto";
-const char CameraParameters::WHITE_BALANCE_INCANDESCENT[] = "incandescent";
-const char CameraParameters::WHITE_BALANCE_FLUORESCENT[] = "fluorescent";
-const char CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT[] = "warm-fluorescent";
-const char CameraParameters::WHITE_BALANCE_DAYLIGHT[] = "daylight";
-const char CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT[] = "cloudy-daylight";
-const char CameraParameters::WHITE_BALANCE_TWILIGHT[] = "twilight";
-const char CameraParameters::WHITE_BALANCE_SHADE[] = "shade";
-
-// Values for effect settings.
-const char CameraParameters::EFFECT_NONE[] = "none";
-const char CameraParameters::EFFECT_MONO[] = "mono";
-const char CameraParameters::EFFECT_NEGATIVE[] = "negative";
-const char CameraParameters::EFFECT_SOLARIZE[] = "solarize";
-const char CameraParameters::EFFECT_SEPIA[] = "sepia";
-const char CameraParameters::EFFECT_POSTERIZE[] = "posterize";
-const char CameraParameters::EFFECT_WHITEBOARD[] = "whiteboard";
-const char CameraParameters::EFFECT_BLACKBOARD[] = "blackboard";
-const char CameraParameters::EFFECT_AQUA[] = "aqua";
-
-// Values for antibanding settings.
-const char CameraParameters::ANTIBANDING_AUTO[] = "auto";
-const char CameraParameters::ANTIBANDING_50HZ[] = "50hz";
-const char CameraParameters::ANTIBANDING_60HZ[] = "60hz";
-const char CameraParameters::ANTIBANDING_OFF[] = "off";
-
-// Values for flash mode settings.
-const char CameraParameters::FLASH_MODE_OFF[] = "off";
-const char CameraParameters::FLASH_MODE_AUTO[] = "auto";
-const char CameraParameters::FLASH_MODE_ON[] = "on";
-const char CameraParameters::FLASH_MODE_RED_EYE[] = "red-eye";
-const char CameraParameters::FLASH_MODE_TORCH[] = "torch";
-
-// Values for scene mode settings.
-const char CameraParameters::SCENE_MODE_AUTO[] = "auto";
-const char CameraParameters::SCENE_MODE_ACTION[] = "action";
-const char CameraParameters::SCENE_MODE_PORTRAIT[] = "portrait";
-const char CameraParameters::SCENE_MODE_LANDSCAPE[] = "landscape";
-const char CameraParameters::SCENE_MODE_NIGHT[] = "night";
-const char CameraParameters::SCENE_MODE_NIGHT_PORTRAIT[] = "night-portrait";
-const char CameraParameters::SCENE_MODE_THEATRE[] = "theatre";
-const char CameraParameters::SCENE_MODE_BEACH[] = "beach";
-const char CameraParameters::SCENE_MODE_SNOW[] = "snow";
-const char CameraParameters::SCENE_MODE_SUNSET[] = "sunset";
-const char CameraParameters::SCENE_MODE_STEADYPHOTO[] = "steadyphoto";
-const char CameraParameters::SCENE_MODE_FIREWORKS[] = "fireworks";
-const char CameraParameters::SCENE_MODE_SPORTS[] = "sports";
-const char CameraParameters::SCENE_MODE_PARTY[] = "party";
-const char CameraParameters::SCENE_MODE_CANDLELIGHT[] = "candlelight";
-
-// Formats for setPreviewFormat and setPictureFormat.
-const char CameraParameters::PIXEL_FORMAT_YUV422SP[] = "yuv422sp";
-const char CameraParameters::PIXEL_FORMAT_YUV420SP[] = "yuv420sp";
-const char CameraParameters::PIXEL_FORMAT_YUV422I[] = "yuv422i-yuyv";
-const char CameraParameters::PIXEL_FORMAT_RGB565[] = "rgb565";
-const char CameraParameters::PIXEL_FORMAT_JPEG[] = "jpeg";
-
-// Values for focus mode settings.
-const char CameraParameters::FOCUS_MODE_AUTO[] = "auto";
-const char CameraParameters::FOCUS_MODE_INFINITY[] = "infinity";
-const char CameraParameters::FOCUS_MODE_MACRO[] = "macro";
-const char CameraParameters::FOCUS_MODE_FIXED[] = "fixed";
-
-CameraParameters::CameraParameters()
-                : mMap()
-{
-}
-
-CameraParameters::~CameraParameters()
-{
-}
-
-String8 CameraParameters::flatten() const
-{
-    String8 flattened("");
-    size_t size = mMap.size();
-
-    for (size_t i = 0; i < size; i++) {
-        String8 k, v;
-        k = mMap.keyAt(i);
-        v = mMap.valueAt(i);
-
-        flattened += k;
-        flattened += "=";
-        flattened += v;
-        if (i != size-1)
-            flattened += ";";
-    }
-
-    return flattened;
-}
-
-void CameraParameters::unflatten(const String8 &params)
-{
-    const char *a = params.string();
-    const char *b;
-
-    mMap.clear();
-
-    for (;;) {
-        // Find the bounds of the key name.
-        b = strchr(a, '=');
-        if (b == 0)
-            break;
-
-        // Create the key string.
-        String8 k(a, (size_t)(b-a));
-
-        // Find the value.
-        a = b+1;
-        b = strchr(a, ';');
-        if (b == 0) {
-            // If there's no semicolon, this is the last item.
-            String8 v(a);
-            mMap.add(k, v);
-            break;
-        }
-
-        String8 v(a, (size_t)(b-a));
-        mMap.add(k, v);
-        a = b+1;
-    }
-}
-
-
-void CameraParameters::set(const char *key, const char *value)
-{
-    // XXX i think i can do this with strspn()
-    if (strchr(key, '=') || strchr(key, ';')) {
-        //XXX LOGE("Key \"%s\"contains invalid character (= or ;)", key);
-        return;
-    }
-
-    if (strchr(value, '=') || strchr(key, ';')) {
-        //XXX LOGE("Value \"%s\"contains invalid character (= or ;)", value);
-        return;
-    }
-
-    mMap.replaceValueFor(String8(key), String8(value));
-}
-
-void CameraParameters::set(const char *key, int value)
-{
-    char str[16];
-    sprintf(str, "%d", value);
-    set(key, str);
-}
-
-void CameraParameters::setFloat(const char *key, float value)
-{
-    char str[16];  // 14 should be enough. We overestimate to be safe.
-    snprintf(str, sizeof(str), "%g", value);
-    set(key, str);
-}
-
-const char *CameraParameters::get(const char *key) const
-{
-    String8 v = mMap.valueFor(String8(key));
-    if (v.length() == 0)
-        return 0;
-    return v.string();
-}
-
-int CameraParameters::getInt(const char *key) const
-{
-    const char *v = get(key);
-    if (v == 0)
-        return -1;
-    return strtol(v, 0, 0);
-}
-
-float CameraParameters::getFloat(const char *key) const
-{
-    const char *v = get(key);
-    if (v == 0) return -1;
-    return strtof(v, 0);
-}
-
-static int parse_size(const char *str, int &width, int &height)
-{
-    // Find the width.
-    char *end;
-    int w = (int)strtol(str, &end, 10);
-    // If an 'x' does not immediately follow, give up.
-    if (*end != 'x')
-        return -1;
-
-    // Find the height, immediately after the 'x'.
-    int h = (int)strtol(end+1, 0, 10);
-
-    width = w;
-    height = h;
-
-    return 0;
-}
-
-void CameraParameters::setPreviewSize(int width, int height)
-{
-    char str[32];
-    sprintf(str, "%dx%d", width, height);
-    set(KEY_PREVIEW_SIZE, str);
-}
-
-void CameraParameters::getPreviewSize(int *width, int *height) const
-{
-    *width = -1;
-    *height = -1;
-
-    // Get the current string, if it doesn't exist, leave the -1x-1
-    const char *p = get(KEY_PREVIEW_SIZE);
-    if (p == 0)
-        return;
-
-    int w, h;
-    if (parse_size(p, w, h) == 0) {
-        *width = w;
-        *height = h;
-    }
-}
-
-void CameraParameters::setPreviewFrameRate(int fps)
-{
-    set(KEY_PREVIEW_FRAME_RATE, fps);
-}
-
-int CameraParameters::getPreviewFrameRate() const
-{
-    return getInt(KEY_PREVIEW_FRAME_RATE);
-}
-
-void CameraParameters::setPreviewFormat(const char *format)
-{
-    set(KEY_PREVIEW_FORMAT, format);
-}
-
-const char *CameraParameters::getPreviewFormat() const
-{
-    return get(KEY_PREVIEW_FORMAT);
-}
-
-void CameraParameters::setPictureSize(int width, int height)
-{
-    char str[32];
-    sprintf(str, "%dx%d", width, height);
-    set(KEY_PICTURE_SIZE, str);
-}
-
-void CameraParameters::getPictureSize(int *width, int *height) const
-{
-    *width = -1;
-    *height = -1;
-
-    // Get the current string, if it doesn't exist, leave the -1x-1
-    const char *p = get(KEY_PICTURE_SIZE);
-    if (p == 0)
-        return;
-
-    int w, h;
-    if (parse_size(p, w, h) == 0) {
-        *width = w;
-        *height = h;
-    }
-}
-
-void CameraParameters::setPictureFormat(const char *format)
-{
-    set(KEY_PICTURE_FORMAT, format);
-}
-
-const char *CameraParameters::getPictureFormat() const
-{
-    return get(KEY_PICTURE_FORMAT);
-}
-
-void CameraParameters::dump() const
-{
-    LOGD("dump: mMap.size = %d", mMap.size());
-    for (size_t i = 0; i < mMap.size(); i++) {
-        String8 k, v;
-        k = mMap.keyAt(i);
-        v = mMap.valueAt(i);
-        LOGD("%s: %s\n", k.string(), v.string());
-    }
-}
-
-status_t CameraParameters::dump(int fd, const Vector<String16>& args) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %d\n", mMap.size());
-    result.append(buffer);
-    for (size_t i = 0; i < mMap.size(); i++) {
-        String8 k, v;
-        k = mMap.keyAt(i);
-        v = mMap.valueAt(i);
-        snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string());
-        result.append(buffer);
-    }
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-}; // namespace android
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index c5e22e5..1fa2c68 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -27,7 +27,6 @@
 #include <utils/threads.h>
 #include <utils/RefBase.h>
 
-#include <ui/SurfaceComposerClient.h>
 #include <ui/Rect.h>
 #include <ui/FramebufferNativeWindow.h>
 
diff --git a/libs/ui/ICamera.cpp b/libs/ui/ICamera.cpp
deleted file mode 100644
index 4154b05..0000000
--- a/libs/ui/ICamera.cpp
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "ICamera"
-#include <utils/Log.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <binder/Parcel.h>
-#include <ui/ICamera.h>
-
-namespace android {
-
-enum {
-    DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
-    SET_PREVIEW_DISPLAY,
-    SET_PREVIEW_CALLBACK_FLAG,
-    START_PREVIEW,
-    STOP_PREVIEW,
-    AUTO_FOCUS,
-    CANCEL_AUTO_FOCUS,
-    TAKE_PICTURE,
-    SET_PARAMETERS,
-    GET_PARAMETERS,
-    SEND_COMMAND,
-    CONNECT,
-    LOCK,
-    UNLOCK,
-    PREVIEW_ENABLED,
-    START_RECORDING,
-    STOP_RECORDING,
-    RECORDING_ENABLED,
-    RELEASE_RECORDING_FRAME,
-};
-
-class BpCamera: public BpInterface<ICamera>
-{
-public:
-    BpCamera(const sp<IBinder>& impl)
-        : BpInterface<ICamera>(impl)
-    {
-    }
-
-    // disconnect from camera service
-    void disconnect()
-    {
-        LOGV("disconnect");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        remote()->transact(DISCONNECT, data, &reply);
-    }
-
-    // pass the buffered ISurface to the camera service
-    status_t setPreviewDisplay(const sp<ISurface>& surface)
-    {
-        LOGV("setPreviewDisplay");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        data.writeStrongBinder(surface->asBinder());
-        remote()->transact(SET_PREVIEW_DISPLAY, data, &reply);
-        return reply.readInt32();
-    }
-
-    // set the preview callback flag to affect how the received frames from
-    // preview are handled. See Camera.h for details.
-    void setPreviewCallbackFlag(int flag)
-    {
-        LOGV("setPreviewCallbackFlag(%d)", flag);
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        data.writeInt32(flag);
-        remote()->transact(SET_PREVIEW_CALLBACK_FLAG, data, &reply);
-    }
-
-    // start preview mode, must call setPreviewDisplay first
-    status_t startPreview()
-    {
-        LOGV("startPreview");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        remote()->transact(START_PREVIEW, data, &reply);
-        return reply.readInt32();
-    }
-
-    // start recording mode, must call setPreviewDisplay first
-    status_t startRecording()
-    {
-        LOGV("startRecording");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        remote()->transact(START_RECORDING, data, &reply);
-        return reply.readInt32();
-    }
-
-    // stop preview mode
-    void stopPreview()
-    {
-        LOGV("stopPreview");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        remote()->transact(STOP_PREVIEW, data, &reply);
-    }
-
-    // stop recording mode
-    void stopRecording()
-    {
-        LOGV("stopRecording");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        remote()->transact(STOP_RECORDING, data, &reply);
-    }
-
-    void releaseRecordingFrame(const sp<IMemory>& mem)
-    {
-        LOGV("releaseRecordingFrame");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        data.writeStrongBinder(mem->asBinder());
-        remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);
-    }
-
-    // check preview state
-    bool previewEnabled()
-    {
-        LOGV("previewEnabled");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        remote()->transact(PREVIEW_ENABLED, data, &reply);
-        return reply.readInt32();
-    }
-
-    // check recording state
-    bool recordingEnabled()
-    {
-        LOGV("recordingEnabled");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        remote()->transact(RECORDING_ENABLED, data, &reply);
-        return reply.readInt32();
-    }
-
-    // auto focus
-    status_t autoFocus()
-    {
-        LOGV("autoFocus");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        remote()->transact(AUTO_FOCUS, data, &reply);
-        status_t ret = reply.readInt32();
-        return ret;
-    }
-
-    // cancel focus
-    status_t cancelAutoFocus()
-    {
-        LOGV("cancelAutoFocus");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        remote()->transact(CANCEL_AUTO_FOCUS, data, &reply);
-        status_t ret = reply.readInt32();
-        return ret;
-    }
-
-    // take a picture - returns an IMemory (ref-counted mmap)
-    status_t takePicture()
-    {
-        LOGV("takePicture");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        remote()->transact(TAKE_PICTURE, data, &reply);
-        status_t ret = reply.readInt32();
-        return ret;
-    }
-
-    // set preview/capture parameters - key/value pairs
-    status_t setParameters(const String8& params)
-    {
-        LOGV("setParameters");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        data.writeString8(params);
-        remote()->transact(SET_PARAMETERS, data, &reply);
-        return reply.readInt32();
-    }
-
-    // get preview/capture parameters - key/value pairs
-    String8 getParameters() const
-    {
-        LOGV("getParameters");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        remote()->transact(GET_PARAMETERS, data, &reply);
-        return reply.readString8();
-    }
-    virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
-    {
-        LOGD("sendCommand");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        data.writeInt32(cmd);
-        data.writeInt32(arg1);
-        data.writeInt32(arg2);
-        remote()->transact(SEND_COMMAND, data, &reply);
-        return reply.readInt32();
-    }
-    virtual status_t connect(const sp<ICameraClient>& cameraClient)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        data.writeStrongBinder(cameraClient->asBinder());
-        remote()->transact(CONNECT, data, &reply);
-        return reply.readInt32();
-    }
-    virtual status_t lock()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        remote()->transact(LOCK, data, &reply);
-        return reply.readInt32();
-    }
-    virtual status_t unlock()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        remote()->transact(UNLOCK, data, &reply);
-        return reply.readInt32();
-    }
-};
-
-IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera");
-
-// ----------------------------------------------------------------------
-
-status_t BnCamera::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case DISCONNECT: {
-            LOGV("DISCONNECT");
-            CHECK_INTERFACE(ICamera, data, reply);
-            disconnect();
-            return NO_ERROR;
-        } break;
-        case SET_PREVIEW_DISPLAY: {
-            LOGV("SET_PREVIEW_DISPLAY");
-            CHECK_INTERFACE(ICamera, data, reply);
-            sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
-            reply->writeInt32(setPreviewDisplay(surface));
-            return NO_ERROR;
-        } break;
-        case SET_PREVIEW_CALLBACK_FLAG: {
-            LOGV("SET_PREVIEW_CALLBACK_TYPE");
-            CHECK_INTERFACE(ICamera, data, reply);
-            int callback_flag = data.readInt32();
-            setPreviewCallbackFlag(callback_flag);
-            return NO_ERROR;
-        } break;
-        case START_PREVIEW: {
-            LOGV("START_PREVIEW");
-            CHECK_INTERFACE(ICamera, data, reply);
-            reply->writeInt32(startPreview());
-            return NO_ERROR;
-        } break;
-        case START_RECORDING: {
-            LOGV("START_RECORDING");
-            CHECK_INTERFACE(ICamera, data, reply);
-            reply->writeInt32(startRecording());
-            return NO_ERROR;
-        } break;
-        case STOP_PREVIEW: {
-            LOGV("STOP_PREVIEW");
-            CHECK_INTERFACE(ICamera, data, reply);
-            stopPreview();
-            return NO_ERROR;
-        } break;
-        case STOP_RECORDING: {
-            LOGV("STOP_RECORDING");
-            CHECK_INTERFACE(ICamera, data, reply);
-            stopRecording();
-            return NO_ERROR;
-        } break;
-        case RELEASE_RECORDING_FRAME: {
-            LOGV("RELEASE_RECORDING_FRAME");
-            CHECK_INTERFACE(ICamera, data, reply);
-            sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());
-            releaseRecordingFrame(mem);
-            return NO_ERROR;
-        } break;
-        case PREVIEW_ENABLED: {
-            LOGV("PREVIEW_ENABLED");
-            CHECK_INTERFACE(ICamera, data, reply);
-            reply->writeInt32(previewEnabled());
-            return NO_ERROR;
-        } break;
-        case RECORDING_ENABLED: {
-            LOGV("RECORDING_ENABLED");
-            CHECK_INTERFACE(ICamera, data, reply);
-            reply->writeInt32(recordingEnabled());
-            return NO_ERROR;
-        } break;
-        case AUTO_FOCUS: {
-            LOGV("AUTO_FOCUS");
-            CHECK_INTERFACE(ICamera, data, reply);
-            reply->writeInt32(autoFocus());
-            return NO_ERROR;
-        } break;
-        case CANCEL_AUTO_FOCUS: {
-            LOGV("CANCEL_AUTO_FOCUS");
-            CHECK_INTERFACE(ICamera, data, reply);
-            reply->writeInt32(cancelAutoFocus());
-            return NO_ERROR;
-        } break;
-        case TAKE_PICTURE: {
-            LOGV("TAKE_PICTURE");
-            CHECK_INTERFACE(ICamera, data, reply);
-            reply->writeInt32(takePicture());
-            return NO_ERROR;
-        } break;
-        case SET_PARAMETERS: {
-            LOGV("SET_PARAMETERS");
-            CHECK_INTERFACE(ICamera, data, reply);
-            String8 params(data.readString8());
-            reply->writeInt32(setParameters(params));
-            return NO_ERROR;
-         } break;
-        case GET_PARAMETERS: {
-            LOGV("GET_PARAMETERS");
-            CHECK_INTERFACE(ICamera, data, reply);
-             reply->writeString8(getParameters());
-            return NO_ERROR;
-         } break;
-        case SEND_COMMAND: {
-            LOGV("SEND_COMMAND");
-            CHECK_INTERFACE(ICamera, data, reply);
-            int command = data.readInt32();
-            int arg1 = data.readInt32();
-            int arg2 = data.readInt32();
-            reply->writeInt32(sendCommand(command, arg1, arg2));
-            return NO_ERROR;
-         } break;
-        case CONNECT: {
-            CHECK_INTERFACE(ICamera, data, reply);
-            sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());
-            reply->writeInt32(connect(cameraClient));
-            return NO_ERROR;
-        } break;
-        case LOCK: {
-            CHECK_INTERFACE(ICamera, data, reply);
-            reply->writeInt32(lock());
-            return NO_ERROR;
-        } break;
-        case UNLOCK: {
-            CHECK_INTERFACE(ICamera, data, reply);
-            reply->writeInt32(unlock());
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
diff --git a/libs/ui/ICameraClient.cpp b/libs/ui/ICameraClient.cpp
deleted file mode 100644
index 42b4da4..0000000
--- a/libs/ui/ICameraClient.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "ICameraClient"
-#include <utils/Log.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <ui/ICameraClient.h>
-
-namespace android {
-
-enum {
-    NOTIFY_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
-    DATA_CALLBACK,
-    DATA_CALLBACK_TIMESTAMP,
-};
-
-class BpCameraClient: public BpInterface<ICameraClient>
-{
-public:
-    BpCameraClient(const sp<IBinder>& impl)
-        : BpInterface<ICameraClient>(impl)
-    {
-    }
-
-    // generic callback from camera service to app
-    void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
-    {
-        LOGV("notifyCallback");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
-        data.writeInt32(msgType);
-        data.writeInt32(ext1);
-        data.writeInt32(ext2);
-        remote()->transact(NOTIFY_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
-    // generic data callback from camera service to app with image data
-    void dataCallback(int32_t msgType, const sp<IMemory>& imageData)
-    {
-        LOGV("dataCallback");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
-        data.writeInt32(msgType);
-        data.writeStrongBinder(imageData->asBinder());
-        remote()->transact(DATA_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
-    // generic data callback from camera service to app with image data
-    void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& imageData)
-    {
-        LOGV("dataCallback");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
-        data.writeInt64(timestamp);
-        data.writeInt32(msgType);
-        data.writeStrongBinder(imageData->asBinder());
-        remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-};
-
-IMPLEMENT_META_INTERFACE(CameraClient, "android.hardware.ICameraClient");
-
-// ----------------------------------------------------------------------
-
-status_t BnCameraClient::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case NOTIFY_CALLBACK: {
-            LOGV("NOTIFY_CALLBACK");
-            CHECK_INTERFACE(ICameraClient, data, reply);
-            int32_t msgType = data.readInt32();
-            int32_t ext1 = data.readInt32();
-            int32_t ext2 = data.readInt32();
-            notifyCallback(msgType, ext1, ext2);
-            return NO_ERROR;
-        } break;
-        case DATA_CALLBACK: {
-            LOGV("DATA_CALLBACK");
-            CHECK_INTERFACE(ICameraClient, data, reply);
-            int32_t msgType = data.readInt32();
-            sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
-            dataCallback(msgType, imageData);
-            return NO_ERROR;
-        } break;
-        case DATA_CALLBACK_TIMESTAMP: {
-            LOGV("DATA_CALLBACK_TIMESTAMP");
-            CHECK_INTERFACE(ICameraClient, data, reply);
-            nsecs_t timestamp = data.readInt64();
-            int32_t msgType = data.readInt32();
-            sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
-            dataCallbackTimestamp(timestamp, msgType, imageData);
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
diff --git a/libs/ui/ICameraService.cpp b/libs/ui/ICameraService.cpp
deleted file mode 100644
index 84986c6..0000000
--- a/libs/ui/ICameraService.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <ui/ICameraService.h>
-
-namespace android {
-
-class BpCameraService: public BpInterface<ICameraService>
-{
-public:
-    BpCameraService(const sp<IBinder>& impl)
-        : BpInterface<ICameraService>(impl)
-    {
-    }
-
-    // connect to camera service
-    virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
-        data.writeStrongBinder(cameraClient->asBinder());
-        remote()->transact(BnCameraService::CONNECT, data, &reply);
-        return interface_cast<ICamera>(reply.readStrongBinder());
-    }
-};
-
-IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
-
-// ----------------------------------------------------------------------
-
-status_t BnCameraService::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case CONNECT: {
-            CHECK_INTERFACE(ICameraService, data, reply);
-            sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());
-            sp<ICamera> camera = connect(cameraClient);
-            reply->writeStrongBinder(camera->asBinder());
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp
deleted file mode 100644
index 6f3d762..0000000
--- a/libs/ui/ISurface.cpp
+++ /dev/null
@@ -1,186 +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 "ISurface"
-
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-#include <binder/IMemory.h>
-
-#include <ui/ISurface.h>
-#include <ui/Overlay.h>
-#include <ui/Surface.h>
-
-#include <ui/GraphicBuffer.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------
-
-ISurface::BufferHeap::BufferHeap() 
-    : w(0), h(0), hor_stride(0), ver_stride(0), format(0),
-    transform(0), flags(0) 
-{     
-}
-
-ISurface::BufferHeap::BufferHeap(uint32_t w, uint32_t h,
-        int32_t hor_stride, int32_t ver_stride,
-        PixelFormat format, const sp<IMemoryHeap>& heap)
-    : w(w), h(h), hor_stride(hor_stride), ver_stride(ver_stride),
-      format(format), transform(0), flags(0), heap(heap) 
-{
-}
-
-ISurface::BufferHeap::BufferHeap(uint32_t w, uint32_t h,
-        int32_t hor_stride, int32_t ver_stride,
-        PixelFormat format, uint32_t transform, uint32_t flags,
-        const sp<IMemoryHeap>& heap)
-        : w(w), h(h), hor_stride(hor_stride), ver_stride(ver_stride),
-          format(format), transform(transform), flags(flags), heap(heap) 
-{
-}
-
-
-ISurface::BufferHeap::~BufferHeap() 
-{     
-}
-
-// ----------------------------------------------------------------------
-
-class BpSurface : public BpInterface<ISurface>
-{
-public:
-    BpSurface(const sp<IBinder>& impl)
-        : BpInterface<ISurface>(impl)
-    {
-    }
-
-    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
-        data.writeInt32(bufferIdx);
-        data.writeInt32(usage);
-        remote()->transact(REQUEST_BUFFER, data, &reply);
-        sp<GraphicBuffer> buffer = new GraphicBuffer(reply);
-        return buffer;
-    }
-
-    virtual status_t registerBuffers(const BufferHeap& buffers)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
-        data.writeInt32(buffers.w);
-        data.writeInt32(buffers.h);
-        data.writeInt32(buffers.hor_stride);
-        data.writeInt32(buffers.ver_stride);
-        data.writeInt32(buffers.format);
-        data.writeInt32(buffers.transform);
-        data.writeInt32(buffers.flags);
-        data.writeStrongBinder(buffers.heap->asBinder());
-        remote()->transact(REGISTER_BUFFERS, data, &reply);
-        status_t result = reply.readInt32();
-        return result;
-    }
-
-    virtual void postBuffer(ssize_t offset)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
-        data.writeInt32(offset);
-        remote()->transact(POST_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
-    virtual void unregisterBuffers()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
-        remote()->transact(UNREGISTER_BUFFERS, data, &reply);
-    }
-
-    virtual sp<OverlayRef> createOverlay(
-             uint32_t w, uint32_t h, int32_t format, int32_t orientation)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
-        data.writeInt32(w);
-        data.writeInt32(h);
-        data.writeInt32(format);
-        data.writeInt32(orientation);
-        remote()->transact(CREATE_OVERLAY, data, &reply);
-        return OverlayRef::readFromParcel(reply);
-    }
-};
-
-IMPLEMENT_META_INTERFACE(Surface, "android.ui.ISurface");
-
-// ----------------------------------------------------------------------
-
-status_t BnSurface::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case REQUEST_BUFFER: {
-            CHECK_INTERFACE(ISurface, data, reply);
-            int bufferIdx = data.readInt32();
-            int usage = data.readInt32();
-            sp<GraphicBuffer> buffer(requestBuffer(bufferIdx, usage));
-            return GraphicBuffer::writeToParcel(reply, buffer.get());
-        }
-        case REGISTER_BUFFERS: {
-            CHECK_INTERFACE(ISurface, data, reply);
-            BufferHeap buffer;
-            buffer.w = data.readInt32();
-            buffer.h = data.readInt32();
-            buffer.hor_stride = data.readInt32();
-            buffer.ver_stride= data.readInt32();
-            buffer.format = data.readInt32();
-            buffer.transform = data.readInt32();
-            buffer.flags = data.readInt32();
-            buffer.heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
-            status_t err = registerBuffers(buffer);
-            reply->writeInt32(err);
-            return NO_ERROR;
-        } break;
-        case UNREGISTER_BUFFERS: {
-            CHECK_INTERFACE(ISurface, data, reply);
-            unregisterBuffers();
-            return NO_ERROR;
-        } break;
-        case POST_BUFFER: {
-            CHECK_INTERFACE(ISurface, data, reply);
-            ssize_t offset = data.readInt32();
-            postBuffer(offset);
-            return NO_ERROR;
-        } break;
-        case CREATE_OVERLAY: {
-            CHECK_INTERFACE(ISurface, data, reply);
-            int w = data.readInt32();
-            int h = data.readInt32();
-            int f = data.readInt32();
-            int orientation = data.readInt32();
-            sp<OverlayRef> o = createOverlay(w, h, f, orientation);
-            return OverlayRef::writeToParcel(reply, o);
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-}; // namespace android
diff --git a/libs/ui/ISurfaceComposer.cpp b/libs/ui/ISurfaceComposer.cpp
deleted file mode 100644
index fd2a590..0000000
--- a/libs/ui/ISurfaceComposer.cpp
+++ /dev/null
@@ -1,186 +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.
- */
-
-// tag as surfaceflinger
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-#include <binder/IMemory.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <ui/ISurfaceComposer.h>
-#include <ui/DisplayInfo.h>
-
-// ---------------------------------------------------------------------------
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
-{
-public:
-    BpSurfaceComposer(const sp<IBinder>& impl)
-        : BpInterface<ISurfaceComposer>(impl)
-    {
-    }
-
-    virtual sp<ISurfaceFlingerClient> createConnection()
-    {
-        uint32_t n;
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
-        return interface_cast<ISurfaceFlingerClient>(reply.readStrongBinder());
-    }
-
-    virtual sp<IMemoryHeap> getCblk() const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        remote()->transact(BnSurfaceComposer::GET_CBLK, data, &reply);
-        return interface_cast<IMemoryHeap>(reply.readStrongBinder());
-    }
-
-    virtual void openGlobalTransaction()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        remote()->transact(BnSurfaceComposer::OPEN_GLOBAL_TRANSACTION, data, &reply);
-    }
-
-    virtual void closeGlobalTransaction()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        remote()->transact(BnSurfaceComposer::CLOSE_GLOBAL_TRANSACTION, data, &reply);
-    }
-
-    virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        data.writeInt32(dpy);
-        data.writeInt32(flags);
-        remote()->transact(BnSurfaceComposer::FREEZE_DISPLAY, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        data.writeInt32(dpy);
-        data.writeInt32(flags);
-        remote()->transact(BnSurfaceComposer::UNFREEZE_DISPLAY, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        data.writeInt32(dpy);
-        data.writeInt32(orientation);
-        data.writeInt32(flags);
-        remote()->transact(BnSurfaceComposer::SET_ORIENTATION, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual void bootFinished()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
-    }
-
-    virtual void signal() const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        remote()->transact(BnSurfaceComposer::SIGNAL, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-};
-
-IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
-
-// ----------------------------------------------------------------------
-
-status_t BnSurfaceComposer::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case CREATE_CONNECTION: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            sp<IBinder> b = createConnection()->asBinder();
-            reply->writeStrongBinder(b);
-        } break;
-        case OPEN_GLOBAL_TRANSACTION: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            openGlobalTransaction();
-        } break;
-        case CLOSE_GLOBAL_TRANSACTION: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            closeGlobalTransaction();
-        } break;
-        case SET_ORIENTATION: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            DisplayID dpy = data.readInt32();
-            int orientation = data.readInt32();
-            uint32_t flags = data.readInt32();
-            reply->writeInt32( setOrientation(dpy, orientation, flags) );
-        } break;
-        case FREEZE_DISPLAY: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            DisplayID dpy = data.readInt32();
-            uint32_t flags = data.readInt32();
-            reply->writeInt32( freezeDisplay(dpy, flags) );
-        } break;
-        case UNFREEZE_DISPLAY: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            DisplayID dpy = data.readInt32();
-            uint32_t flags = data.readInt32();
-            reply->writeInt32( unfreezeDisplay(dpy, flags) );
-        } break;
-        case BOOT_FINISHED: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            bootFinished();
-        } break;
-        case SIGNAL: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            signal();
-        } break;
-        case GET_CBLK: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            sp<IBinder> b = getCblk()->asBinder();
-            reply->writeStrongBinder(b);
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-    return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-};
diff --git a/libs/ui/ISurfaceFlingerClient.cpp b/libs/ui/ISurfaceFlingerClient.cpp
deleted file mode 100644
index 4a6a1d7..0000000
--- a/libs/ui/ISurfaceFlingerClient.cpp
+++ /dev/null
@@ -1,210 +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.
- */
-
-// tag as surfaceflinger
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-#include <binder/IMemory.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <ui/ISurface.h>
-#include <ui/ISurfaceFlingerClient.h>
-#include <ui/Point.h>
-#include <ui/Rect.h>
-
-#include <private/ui/LayerState.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 LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-enum {
-    GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
-    CREATE_SURFACE,
-    DESTROY_SURFACE,
-    SET_STATE
-};
-
-class BpSurfaceFlingerClient : public BpInterface<ISurfaceFlingerClient>
-{
-public:
-    BpSurfaceFlingerClient(const sp<IBinder>& impl)
-        : BpInterface<ISurfaceFlingerClient>(impl)
-    {
-    }
-
-    virtual sp<IMemoryHeap> getControlBlock() const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
-        remote()->transact(GET_CBLK, data, &reply);
-        return interface_cast<IMemoryHeap>(reply.readStrongBinder());
-    }
-
-    virtual sp<ISurface> createSurface( surface_data_t* params,
-                                        int pid,
-                                        DisplayID display,
-                                        uint32_t w,
-                                        uint32_t h,
-                                        PixelFormat format,
-                                        uint32_t flags)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
-        data.writeInt32(pid);
-        data.writeInt32(display);
-        data.writeInt32(w);
-        data.writeInt32(h);
-        data.writeInt32(format);
-        data.writeInt32(flags);
-        remote()->transact(CREATE_SURFACE, data, &reply);
-        params->readFromParcel(reply);
-        return interface_cast<ISurface>(reply.readStrongBinder());
-    }
-                                    
-    virtual status_t destroySurface(SurfaceID sid)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
-        data.writeInt32(sid);
-        remote()->transact(DESTROY_SURFACE, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t setState(int32_t count, const layer_state_t* states)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
-        data.writeInt32(count);
-        for (int i=0 ; i<count ; i++)
-            states[i].write(data);
-        remote()->transact(SET_STATE, data, &reply);
-        return reply.readInt32();
-    }
-};
-
-IMPLEMENT_META_INTERFACE(SurfaceFlingerClient, "android.ui.ISurfaceFlingerClient");
-
-// ----------------------------------------------------------------------
-
-status_t BnSurfaceFlingerClient::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    // codes that don't require permission check
-
-    switch(code) {
-        case GET_CBLK: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
-            sp<IMemoryHeap> ctl(getControlBlock());
-            reply->writeStrongBinder(ctl->asBinder());
-            return NO_ERROR;
-        } break;
-    }
-
-    // these must be checked
-     
-     IPCThreadState* ipc = IPCThreadState::self();
-     const int pid = ipc->getCallingPid();
-     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")))
-         {
-             LOGE("Permission Denial: "
-                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
-             return PERMISSION_DENIED;
-         }
-     }
-   
-     switch(code) {
-        case CREATE_SURFACE: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
-            surface_data_t params;
-            int32_t pid = data.readInt32();
-            DisplayID display = data.readInt32();
-            uint32_t w = data.readInt32();
-            uint32_t h = data.readInt32();
-            PixelFormat format = data.readInt32();
-            uint32_t flags = data.readInt32();
-            sp<ISurface> s = createSurface(&params, pid, display, w, h, format, flags);
-            params.writeToParcel(reply);
-            reply->writeStrongBinder(s->asBinder());
-            return NO_ERROR;
-        } break;
-        case DESTROY_SURFACE: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
-            reply->writeInt32( destroySurface( data.readInt32() ) );
-            return NO_ERROR;
-        } break;
-        case SET_STATE: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
-            int32_t count = data.readInt32();
-            layer_state_t* states = new layer_state_t[count];
-            for (int i=0 ; i<count ; i++)
-                states[i].read(data);
-            status_t err = setState(count, states);
-            delete [] states;
-            reply->writeInt32(err);
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-// ----------------------------------------------------------------------
-
-status_t ISurfaceFlingerClient::surface_data_t::readFromParcel(const Parcel& parcel)
-{
-    token    = parcel.readInt32();
-    identity = parcel.readInt32();
-    width    = parcel.readInt32();
-    height   = parcel.readInt32();
-    format   = parcel.readInt32();
-    return NO_ERROR;
-}
-
-status_t ISurfaceFlingerClient::surface_data_t::writeToParcel(Parcel* parcel) const
-{
-    parcel->writeInt32(token);
-    parcel->writeInt32(identity);
-    parcel->writeInt32(width);
-    parcel->writeInt32(height);
-    parcel->writeInt32(format);
-    return NO_ERROR;
-}
-
-}; // namespace android
diff --git a/libs/ui/LayerState.cpp b/libs/ui/LayerState.cpp
deleted file mode 100644
index a53ffb7..0000000
--- a/libs/ui/LayerState.cpp
+++ /dev/null
@@ -1,53 +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.
- */
-
-#include <utils/Errors.h>
-#include <binder/Parcel.h>
-#include <private/ui/LayerState.h>
-
-namespace android {
-
-status_t layer_state_t::write(Parcel& output) const
-{
-    size_t size = sizeof(layer_state_t);
-
-    //output.writeStrongBinder(surface->asBinder());
-    //size -= sizeof(surface);
-
-    transparentRegion.write(output);
-    size -= sizeof(transparentRegion);
-    
-    output.write(this, size);
-    
-    return NO_ERROR;
-}
-
-status_t layer_state_t::read(const Parcel& input)
-{
-    size_t size = sizeof(layer_state_t);
-
-    //surface = interface_cast<ISurface>(input.readStrongBinder());
-    //size -= sizeof(surface);
-
-    transparentRegion.read(input);
-    size -= sizeof(transparentRegion);
-
-    input.read(this, size);
-    
-    return NO_ERROR;
-}
-
-}; // namespace android
diff --git a/libs/ui/SharedBufferStack.cpp b/libs/ui/SharedBufferStack.cpp
deleted file mode 100644
index 46b6766..0000000
--- a/libs/ui/SharedBufferStack.cpp
+++ /dev/null
@@ -1,424 +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 "SharedBufferStack"
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <utils/threads.h>
-
-#include <private/ui/SharedBufferStack.h>
-
-#include <ui/Rect.h>
-#include <ui/Region.h>
-
-#define DEBUG_ATOMICS 0
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-SharedClient::SharedClient()
-    : lock(Mutex::SHARED)
-{
-}
-
-SharedClient::~SharedClient() {
-}
-
-
-// these functions are used by the clients
-status_t SharedClient::validate(size_t i) const {
-    if (uint32_t(i) >= uint32_t(NUM_LAYERS_MAX))
-        return BAD_INDEX;
-    return surfaces[i].status;
-}
-
-uint32_t SharedClient::getIdentity(size_t token) const {
-    return uint32_t(surfaces[token].identity);
-}
-
-// ----------------------------------------------------------------------------
-
-
-SharedBufferStack::SharedBufferStack()
-{
-}
-
-void SharedBufferStack::init(int32_t i)
-{
-    inUse = -1;
-    status = NO_ERROR;
-    identity = i;
-}
-
-status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty)
-{
-    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
-        return BAD_INDEX;
-
-    // in the current implementation we only send a single rectangle
-    const Rect bounds(dirty.getBounds());
-    FlatRegion& reg(dirtyRegion[buffer]);
-    reg.count = 1;
-    reg.rects[0] = uint16_t(bounds.left);
-    reg.rects[1] = uint16_t(bounds.top);
-    reg.rects[2] = uint16_t(bounds.right);
-    reg.rects[3] = uint16_t(bounds.bottom);
-    return NO_ERROR;
-}
-
-Region SharedBufferStack::getDirtyRegion(int buffer) const
-{
-    Region res;
-    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
-        return res;
-
-    const FlatRegion& reg(dirtyRegion[buffer]);
-    res.set(Rect(reg.rects[0], reg.rects[1], reg.rects[2], reg.rects[3]));
-    return res;
-}
-
-// ----------------------------------------------------------------------------
-
-SharedBufferBase::SharedBufferBase(SharedClient* sharedClient,
-        int surface, int num, int32_t identity)
-    : mSharedClient(sharedClient), 
-      mSharedStack(sharedClient->surfaces + surface),
-      mNumBuffers(num), mIdentity(identity)
-{
-}
-
-SharedBufferBase::~SharedBufferBase()
-{
-}
-
-uint32_t SharedBufferBase::getIdentity()
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.identity;
-}
-
-status_t SharedBufferBase::getStatus() const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.status;
-}
-
-size_t SharedBufferBase::getFrontBuffer() const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return size_t( stack.head );
-}
-
-String8 SharedBufferBase::dump(char const* prefix) const
-{
-    const size_t SIZE = 1024;
-    char buffer[SIZE];
-    String8 result;
-    SharedBufferStack& stack( *mSharedStack );
-    snprintf(buffer, SIZE, 
-            "%s[ head=%2d, available=%2d, queued=%2d ] "
-            "reallocMask=%08x, inUse=%2d, identity=%d, status=%d\n",
-            prefix, stack.head, stack.available, stack.queued, 
-            stack.reallocMask, stack.inUse, stack.identity, stack.status);
-    result.append(buffer);
-    return result;
-}
-
-// ============================================================================
-// conditions and updates
-// ============================================================================
-
-SharedBufferClient::DequeueCondition::DequeueCondition(
-        SharedBufferClient* sbc) : ConditionBase(sbc)  { 
-}
-bool SharedBufferClient::DequeueCondition::operator()() {
-    return stack.available > 0;
-}
-
-SharedBufferClient::LockCondition::LockCondition(
-        SharedBufferClient* sbc, int buf) : ConditionBase(sbc), buf(buf) { 
-}
-bool SharedBufferClient::LockCondition::operator()() {
-    return (buf != stack.head || 
-            (stack.queued > 0 && stack.inUse != buf));
-}
-
-SharedBufferServer::ReallocateCondition::ReallocateCondition(
-        SharedBufferBase* sbb, int buf) : ConditionBase(sbb), buf(buf) { 
-}
-bool SharedBufferServer::ReallocateCondition::operator()() {
-    // TODO: we should also check that buf has been dequeued
-    return (buf != stack.head);
-}
-
-// ----------------------------------------------------------------------------
-
-SharedBufferClient::QueueUpdate::QueueUpdate(SharedBufferBase* sbb)
-    : UpdateBase(sbb) {    
-}
-ssize_t SharedBufferClient::QueueUpdate::operator()() {
-    android_atomic_inc(&stack.queued);
-    return NO_ERROR;
-}
-
-SharedBufferClient::UndoDequeueUpdate::UndoDequeueUpdate(SharedBufferBase* sbb)
-    : UpdateBase(sbb) {    
-}
-ssize_t SharedBufferClient::UndoDequeueUpdate::operator()() {
-    android_atomic_inc(&stack.available);
-    return NO_ERROR;
-}
-
-SharedBufferServer::UnlockUpdate::UnlockUpdate(
-        SharedBufferBase* sbb, int lockedBuffer)
-    : UpdateBase(sbb), lockedBuffer(lockedBuffer) {
-}
-ssize_t SharedBufferServer::UnlockUpdate::operator()() {
-    if (stack.inUse != lockedBuffer) {
-        LOGE("unlocking %d, but currently locked buffer is %d",
-                lockedBuffer, stack.inUse);
-        return BAD_VALUE;
-    }
-    android_atomic_write(-1, &stack.inUse);
-    return NO_ERROR;
-}
-
-SharedBufferServer::RetireUpdate::RetireUpdate(
-        SharedBufferBase* sbb, int numBuffers)
-    : UpdateBase(sbb), numBuffers(numBuffers) {
-}
-ssize_t SharedBufferServer::RetireUpdate::operator()() {
-    // head is only written in this function, which is single-thread.
-    int32_t head = stack.head;
-
-    // Preventively lock the current buffer before updating queued.
-    android_atomic_write(head, &stack.inUse);
-
-    // Decrement the number of queued buffers 
-    int32_t queued;
-    do {
-        queued = stack.queued;
-        if (queued == 0) {
-            return NOT_ENOUGH_DATA;
-        }
-    } while (android_atomic_cmpxchg(queued, queued-1, &stack.queued));
-    
-    // update the head pointer
-    head = ((head+1 >= numBuffers) ? 0 : head+1);
-
-    // lock the buffer before advancing head, which automatically unlocks
-    // the buffer we preventively locked upon entering this function
-    android_atomic_write(head, &stack.inUse);
-
-    // advance head
-    android_atomic_write(head, &stack.head);
-    
-    // now that head has moved, we can increment the number of available buffers
-    android_atomic_inc(&stack.available);
-    return head;
-}
-
-SharedBufferServer::StatusUpdate::StatusUpdate(
-        SharedBufferBase* sbb, status_t status)
-    : UpdateBase(sbb), status(status) {
-}
-
-ssize_t SharedBufferServer::StatusUpdate::operator()() {
-    android_atomic_write(status, &stack.status);
-    return NO_ERROR;
-}
-
-// ============================================================================
-
-SharedBufferClient::SharedBufferClient(SharedClient* sharedClient,
-        int surface, int num, int32_t identity)
-    : SharedBufferBase(sharedClient, surface, num, identity), tail(0)
-{
-    tail = computeTail();
-}
-
-int32_t SharedBufferClient::computeTail() const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    // we need to make sure we read available and head coherently,
-    // w.r.t RetireUpdate.
-    int32_t newTail;
-    int32_t avail;
-    int32_t head;
-    do {
-        avail = stack.available;
-        head = stack.head;
-    } while (stack.available != avail);
-    newTail = head - avail + 1;
-    if (newTail < 0) {
-        newTail += mNumBuffers;
-    }
-    return newTail;
-}
-
-ssize_t SharedBufferClient::dequeue()
-{
-    SharedBufferStack& stack( *mSharedStack );
-
-    if (stack.head == tail && stack.available == 2) {
-        LOGW("dequeue: tail=%d, head=%d, avail=%d, queued=%d",
-                tail, stack.head, stack.available, stack.queued);
-    }
-        
-    const nsecs_t dequeueTime = systemTime(SYSTEM_TIME_THREAD);
-
-    //LOGD("[%d] about to dequeue a buffer",
-    //        mSharedStack->identity);
-    DequeueCondition condition(this);
-    status_t err = waitForCondition(condition);
-    if (err != NO_ERROR)
-        return ssize_t(err);
-
-    // NOTE: 'stack.available' is part of the conditions, however
-    // decrementing it, never changes any conditions, so we don't need
-    // to do this as part of an update.
-    if (android_atomic_dec(&stack.available) == 0) {
-        LOGW("dequeue probably called from multiple threads!");
-    }
-
-    int dequeued = tail;
-    tail = ((tail+1 >= mNumBuffers) ? 0 : tail+1);
-    LOGD_IF(DEBUG_ATOMICS, "dequeued=%d, tail=%d, %s",
-            dequeued, tail, dump("").string());
-
-    mDequeueTime[dequeued] = dequeueTime; 
-
-    return dequeued;
-}
-
-status_t SharedBufferClient::undoDequeue(int buf)
-{
-    UndoDequeueUpdate update(this);
-    status_t err = updateCondition( update );
-    if (err == NO_ERROR) {
-        tail = computeTail();
-    }
-    return err;
-}
-
-status_t SharedBufferClient::lock(int buf)
-{
-    LockCondition condition(this, buf);
-    status_t err = waitForCondition(condition);
-    return err;
-}
-
-status_t SharedBufferClient::queue(int buf)
-{
-    QueueUpdate update(this);
-    status_t err = updateCondition( update );
-    LOGD_IF(DEBUG_ATOMICS, "queued=%d, %s", buf, dump("").string());
-    SharedBufferStack& stack( *mSharedStack );
-    const nsecs_t now = systemTime(SYSTEM_TIME_THREAD);
-    stack.stats.totalTime = ns2us(now - mDequeueTime[buf]);
-    return err;
-}
-
-bool SharedBufferClient::needNewBuffer(int buffer) const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    const uint32_t mask = 1<<buffer;
-    return (android_atomic_and(~mask, &stack.reallocMask) & mask) != 0;
-}
-
-status_t SharedBufferClient::setDirtyRegion(int buffer, const Region& reg)
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.setDirtyRegion(buffer, reg);
-}
-
-// ----------------------------------------------------------------------------
-
-SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,
-        int surface, int num, int32_t identity)
-    : SharedBufferBase(sharedClient, surface, num, identity)
-{
-    mSharedStack->init(identity);
-    mSharedStack->head = num-1;
-    mSharedStack->available = num;
-    mSharedStack->queued = 0;
-    mSharedStack->reallocMask = 0;
-    memset(mSharedStack->dirtyRegion, 0, sizeof(mSharedStack->dirtyRegion));
-}
-
-ssize_t SharedBufferServer::retireAndLock()
-{
-    RetireUpdate update(this, mNumBuffers);
-    ssize_t buf = updateCondition( update );
-    LOGD_IF(DEBUG_ATOMICS && buf>=0, "retire=%d, %s", int(buf), dump("").string());
-    return buf;
-}
-
-status_t SharedBufferServer::unlock(int buffer)
-{
-    UnlockUpdate update(this, buffer);
-    status_t err = updateCondition( update );
-    return err;
-}
-
-void SharedBufferServer::setStatus(status_t status)
-{
-    if (status < NO_ERROR) {
-        StatusUpdate update(this, status);
-        updateCondition( update );
-    }
-}
-
-status_t SharedBufferServer::reallocate()
-{
-    SharedBufferStack& stack( *mSharedStack );
-    uint32_t mask = (1<<mNumBuffers)-1;
-    android_atomic_or(mask, &stack.reallocMask); 
-    return NO_ERROR;
-}
-
-int32_t SharedBufferServer::getQueuedCount() const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.queued;
-}
-
-status_t SharedBufferServer::assertReallocate(int buffer)
-{
-    ReallocateCondition condition(this, buffer);
-    status_t err = waitForCondition(condition);
-    return err;
-}
-
-Region SharedBufferServer::getDirtyRegion(int buffer) const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.getDirtyRegion(buffer);
-}
-
-SharedBufferStack::Statistics SharedBufferServer::getStats() const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.stats;
-}
-
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
deleted file mode 100644
index c7be05b..0000000
--- a/libs/ui/Surface.cpp
+++ /dev/null
@@ -1,755 +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 "Surface"
-
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <utils/Errors.h>
-#include <utils/threads.h>
-#include <utils/CallStack.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IMemory.h>
-#include <utils/Log.h>
-
-#include <ui/DisplayInfo.h>
-#include <ui/GraphicBuffer.h>
-#include <ui/GraphicBufferMapper.h>
-#include <ui/ISurface.h>
-#include <ui/Surface.h>
-#include <ui/SurfaceComposerClient.h>
-#include <ui/Rect.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include <private/ui/SharedBufferStack.h>
-#include <private/ui/LayerState.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------
-
-static status_t copyBlt(
-        const sp<GraphicBuffer>& dst, 
-        const sp<GraphicBuffer>& src, 
-        const Region& reg)
-{
-    status_t err;
-    uint8_t const * src_bits = NULL;
-    err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
-    LOGE_IF(err, "error locking src buffer %s", strerror(-err));
-
-    uint8_t* dst_bits = NULL;
-    err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
-    LOGE_IF(err, "error locking dst buffer %s", strerror(-err));
-
-    Region::const_iterator head(reg.begin());
-    Region::const_iterator tail(reg.end());
-    if (head != tail && src_bits && dst_bits) {
-        // NOTE: dst and src must be the same format
-        const size_t bpp = bytesPerPixel(src->format);
-        const size_t dbpr = dst->stride * bpp;
-        const size_t sbpr = src->stride * bpp;
-
-        while (head != tail) {
-            const Rect& r(*head++);
-            ssize_t h = r.height();
-            if (h <= 0) continue;
-            size_t size = r.width() * bpp;
-            uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
-            uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
-            if (dbpr==sbpr && size==sbpr) {
-                size *= h;
-                h = 1;
-            }
-            do {
-                memcpy(d, s, size);
-                d += dbpr;
-                s += sbpr;
-            } while (--h > 0);
-        }
-    }
-    
-    if (src_bits)
-        src->unlock();
-    
-    if (dst_bits)
-        dst->unlock();
-    
-    return err;
-}
-
-// ============================================================================
-//  SurfaceControl
-// ============================================================================
-
-SurfaceControl::SurfaceControl(
-        const sp<SurfaceComposerClient>& client, 
-        const sp<ISurface>& surface,
-        const ISurfaceFlingerClient::surface_data_t& data,
-        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
-    : mClient(client), mSurface(surface),
-      mToken(data.token), mIdentity(data.identity),
-      mWidth(data.width), mHeight(data.height), mFormat(data.format),
-      mFlags(flags)
-{
-}
-        
-SurfaceControl::~SurfaceControl()
-{
-    destroy();
-}
-
-void SurfaceControl::destroy()
-{
-    if (isValid()) {
-        mClient->destroySurface(mToken);
-    }
-
-    // clear all references and trigger an IPC now, to make sure things
-    // happen without delay, since these resources are quite heavy.
-    mClient.clear();
-    mSurface.clear();
-    IPCThreadState::self()->flushCommands();
-}
-
-void SurfaceControl::clear() 
-{
-    // here, the window manager tells us explicitly that we should destroy
-    // the surface's resource. Soon after this call, it will also release
-    // its last reference (which will call the dtor); however, it is possible
-    // that a client living in the same process still holds references which
-    // would delay the call to the dtor -- that is why we need this explicit
-    // "clear()" call.
-    destroy();
-}
-
-bool SurfaceControl::isSameSurface(
-        const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs) 
-{
-    if (lhs == 0 || rhs == 0)
-        return false;
-    return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
-}
-
-status_t SurfaceControl::setLayer(int32_t layer) {
-    const sp<SurfaceComposerClient>& client(mClient);
-    status_t err = validate();
-    if (err < 0) return err;
-    return client->setLayer(mToken, layer);
-}
-status_t SurfaceControl::setPosition(int32_t x, int32_t y) {
-    const sp<SurfaceComposerClient>& client(mClient);
-    status_t err = validate();
-    if (err < 0) return err;
-    return client->setPosition(mToken, x, y);
-}
-status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
-    const sp<SurfaceComposerClient>& client(mClient);
-    status_t err = validate();
-    if (err < 0) return err;
-    return client->setSize(mToken, w, h);
-}
-status_t SurfaceControl::hide() {
-    const sp<SurfaceComposerClient>& client(mClient);
-    status_t err = validate();
-    if (err < 0) return err;
-    return client->hide(mToken);
-}
-status_t SurfaceControl::show(int32_t layer) {
-    const sp<SurfaceComposerClient>& client(mClient);
-    status_t err = validate();
-    if (err < 0) return err;
-    return client->show(mToken, layer);
-}
-status_t SurfaceControl::freeze() {
-    const sp<SurfaceComposerClient>& client(mClient);
-    status_t err = validate();
-    if (err < 0) return err;
-    return client->freeze(mToken);
-}
-status_t SurfaceControl::unfreeze() {
-    const sp<SurfaceComposerClient>& client(mClient);
-    status_t err = validate();
-    if (err < 0) return err;
-    return client->unfreeze(mToken);
-}
-status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
-    const sp<SurfaceComposerClient>& client(mClient);
-    status_t err = validate();
-    if (err < 0) return err;
-    return client->setFlags(mToken, flags, mask);
-}
-status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
-    const sp<SurfaceComposerClient>& client(mClient);
-    status_t err = validate();
-    if (err < 0) return err;
-    return client->setTransparentRegionHint(mToken, transparent);
-}
-status_t SurfaceControl::setAlpha(float alpha) {
-    const sp<SurfaceComposerClient>& client(mClient);
-    status_t err = validate();
-    if (err < 0) return err;
-    return client->setAlpha(mToken, alpha);
-}
-status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
-    const sp<SurfaceComposerClient>& client(mClient);
-    status_t err = validate();
-    if (err < 0) return err;
-    return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy);
-}
-status_t SurfaceControl::setFreezeTint(uint32_t tint) {
-    const sp<SurfaceComposerClient>& client(mClient);
-    status_t err = validate();
-    if (err < 0) return err;
-    return client->setFreezeTint(mToken, tint);
-}
-
-status_t SurfaceControl::validate() const
-{
-    if (mToken<0 || mClient==0) {
-        LOGE("invalid token (%d, identity=%u) or client (%p)", 
-                mToken, mIdentity, mClient.get());
-        return NO_INIT;
-    }
-    SharedClient const* cblk = mClient->mControl;
-    if (cblk == 0) {
-        LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
-        return NO_INIT;
-    }
-    status_t err = cblk->validate(mToken);
-    if (err != NO_ERROR) {
-        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
-                mToken, mIdentity, err, strerror(-err));
-        return err;
-    }
-    uint32_t identity = cblk->getIdentity(mToken);
-    if (mIdentity != identity) {
-        LOGE("using an invalid surface id=%d, identity=%u should be %d",
-                mToken, mIdentity, identity);
-        return NO_INIT;
-    }
-    return NO_ERROR;
-}
-
-status_t SurfaceControl::writeSurfaceToParcel(
-        const sp<SurfaceControl>& control, Parcel* parcel)
-{
-    uint32_t flags = 0;
-    uint32_t format = 0;
-    SurfaceID token = -1;
-    uint32_t identity = 0;
-    uint32_t width = 0;
-    uint32_t height = 0;
-    sp<SurfaceComposerClient> client;
-    sp<ISurface> sur;
-    if (SurfaceControl::isValid(control)) {
-        token    = control->mToken;
-        identity = control->mIdentity;
-        client   = control->mClient;
-        sur      = control->mSurface;
-        width    = control->mWidth;
-        height   = control->mHeight;
-        format   = control->mFormat;
-        flags    = control->mFlags;
-    }
-    parcel->writeStrongBinder(client!=0  ? client->connection() : NULL);
-    parcel->writeStrongBinder(sur!=0     ? sur->asBinder()      : NULL);
-    parcel->writeInt32(token);
-    parcel->writeInt32(identity);
-    parcel->writeInt32(width);
-    parcel->writeInt32(height);
-    parcel->writeInt32(format);
-    parcel->writeInt32(flags);
-    return NO_ERROR;
-}
-
-sp<Surface> SurfaceControl::getSurface() const
-{
-    Mutex::Autolock _l(mLock);
-    if (mSurfaceData == 0) {
-        mSurfaceData = new Surface(const_cast<SurfaceControl*>(this));
-    }
-    return mSurfaceData;
-}
-
-// ============================================================================
-//  Surface
-// ============================================================================
-
-Surface::Surface(const sp<SurfaceControl>& surface)
-    : mClient(surface->mClient), mSurface(surface->mSurface),
-      mToken(surface->mToken), mIdentity(surface->mIdentity),
-      mFormat(surface->mFormat), mFlags(surface->mFlags),
-      mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL),
-      mWidth(surface->mWidth), mHeight(surface->mHeight)
-{
-    mSharedBufferClient = new SharedBufferClient(
-            mClient->mControl, mToken, 2, mIdentity);
-
-    init();
-}
-
-Surface::Surface(const Parcel& parcel)
-    :  mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL)
-{
-    sp<IBinder> clientBinder = parcel.readStrongBinder();
-    mSurface    = interface_cast<ISurface>(parcel.readStrongBinder());
-    mToken      = parcel.readInt32();
-    mIdentity   = parcel.readInt32();
-    mWidth      = parcel.readInt32();
-    mHeight     = parcel.readInt32();
-    mFormat     = parcel.readInt32();
-    mFlags      = parcel.readInt32();
-
-    // FIXME: what does that mean if clientBinder is NULL here?
-    if (clientBinder != NULL) {
-        mClient = SurfaceComposerClient::clientForConnection(clientBinder);
-
-        mSharedBufferClient = new SharedBufferClient(
-                mClient->mControl, mToken, 2, mIdentity);
-    }
-
-    init();
-}
-
-void Surface::init()
-{
-    android_native_window_t::setSwapInterval  = setSwapInterval;
-    android_native_window_t::dequeueBuffer    = dequeueBuffer;
-    android_native_window_t::lockBuffer       = lockBuffer;
-    android_native_window_t::queueBuffer      = queueBuffer;
-    android_native_window_t::query            = query;
-    android_native_window_t::perform          = perform;
-    mSwapRectangle.makeInvalid();
-    DisplayInfo dinfo;
-    SurfaceComposerClient::getDisplayInfo(0, &dinfo);
-    const_cast<float&>(android_native_window_t::xdpi) = dinfo.xdpi;
-    const_cast<float&>(android_native_window_t::ydpi) = dinfo.ydpi;
-    // FIXME: set real values here
-    const_cast<int&>(android_native_window_t::minSwapInterval) = 1;
-    const_cast<int&>(android_native_window_t::maxSwapInterval) = 1;
-    const_cast<uint32_t&>(android_native_window_t::flags) = 0;
-    // be default we request a hardware surface
-    mUsage = GRALLOC_USAGE_HW_RENDER;
-    mNeedFullUpdate = false;
-}
-
-Surface::~Surface()
-{
-    // this is a client-side operation, the surface is destroyed, unmap
-    // its buffers in this process.
-    for (int i=0 ; i<2 ; i++) {
-        if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) {
-            getBufferMapper().unregisterBuffer(mBuffers[i]->handle);
-        }
-    }
-
-    // clear all references and trigger an IPC now, to make sure things
-    // happen without delay, since these resources are quite heavy.
-    mClient.clear();
-    mSurface.clear();
-    delete mSharedBufferClient;
-    IPCThreadState::self()->flushCommands();
-}
-
-sp<SurfaceComposerClient> Surface::getClient() const {
-    return mClient;
-}
-
-sp<ISurface> Surface::getISurface() const {
-    return mSurface;
-}
-
-bool Surface::isValid() {
-    return mToken>=0 && mClient!=0;
-}
-
-status_t Surface::validate() const
-{
-    sp<SurfaceComposerClient> client(getClient());
-    if (mToken<0 || mClient==0) {
-        LOGE("invalid token (%d, identity=%u) or client (%p)", 
-                mToken, mIdentity, client.get());
-        return NO_INIT;
-    }
-    SharedClient const* cblk = mClient->mControl;
-    if (cblk == 0) {
-        LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
-        return NO_INIT;
-    }
-    status_t err = cblk->validate(mToken);
-    if (err != NO_ERROR) {
-        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
-                mToken, mIdentity, err, strerror(-err));
-        return err;
-    }
-    uint32_t identity = cblk->getIdentity(mToken);
-    if (mIdentity != identity) {
-        LOGE("using an invalid surface id=%d, identity=%u should be %d",
-                mToken, mIdentity, identity);
-        return NO_INIT;
-    }
-    return NO_ERROR;
-}
-
-
-bool Surface::isSameSurface(
-        const sp<Surface>& lhs, const sp<Surface>& rhs) 
-{
-    if (lhs == 0 || rhs == 0)
-        return false;
-
-    return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
-}
-
-// ----------------------------------------------------------------------------
-
-int Surface::setSwapInterval(android_native_window_t* window, int interval) {
-    return 0;
-}
-
-int Surface::dequeueBuffer(android_native_window_t* window, 
-        android_native_buffer_t** buffer) {
-    Surface* self = getSelf(window);
-    return self->dequeueBuffer(buffer);
-}
-
-int Surface::lockBuffer(android_native_window_t* window, 
-        android_native_buffer_t* buffer) {
-    Surface* self = getSelf(window);
-    return self->lockBuffer(buffer);
-}
-
-int Surface::queueBuffer(android_native_window_t* window, 
-        android_native_buffer_t* buffer) {
-    Surface* self = getSelf(window);
-    return self->queueBuffer(buffer);
-}
-
-int Surface::query(android_native_window_t* window, 
-        int what, int* value) {
-    Surface* self = getSelf(window);
-    return self->query(what, value);
-}
-
-int Surface::perform(android_native_window_t* window, 
-        int operation, ...) {
-    va_list args;
-    va_start(args, operation);
-    Surface* self = getSelf(window);
-    int res = self->perform(operation, args);
-    va_end(args);
-    return res;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t Surface::dequeueBuffer(sp<GraphicBuffer>* buffer) {
-    android_native_buffer_t* out;
-    status_t err = dequeueBuffer(&out);
-    if (err == NO_ERROR) {
-        *buffer = GraphicBuffer::getSelf(out);
-    }
-    return err;
-}
-
-// ----------------------------------------------------------------------------
-
-
-int Surface::dequeueBuffer(android_native_buffer_t** buffer)
-{
-    sp<SurfaceComposerClient> client(getClient());
-    status_t err = validate();
-    if (err != NO_ERROR)
-        return err;
-
-    ssize_t bufIdx = mSharedBufferClient->dequeue();
-    if (bufIdx < 0) {
-        LOGE("error dequeuing a buffer (%s)", strerror(bufIdx));
-        return bufIdx;
-    }
-
-    // below we make sure we AT LEAST have the usage flags we want
-    const uint32_t usage(getUsage());
-    const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
-    if (backBuffer == 0 || 
-        ((uint32_t(backBuffer->usage) & usage) != usage) ||
-        mSharedBufferClient->needNewBuffer(bufIdx)) 
-    {
-        err = getBufferLocked(bufIdx, usage);
-        LOGE_IF(err, "getBufferLocked(%ld, %08x) failed (%s)",
-                bufIdx, usage, strerror(-err));
-        if (err == NO_ERROR) {
-            // reset the width/height with the what we get from the buffer
-            mWidth  = uint32_t(backBuffer->width);
-            mHeight = uint32_t(backBuffer->height);
-        }
-    }
-
-    // if we still don't have a buffer here, we probably ran out of memory
-    if (!err && backBuffer==0) {
-        err = NO_MEMORY;
-    }
-
-    if (err == NO_ERROR) {
-        mDirtyRegion.set(backBuffer->width, backBuffer->height);
-        *buffer = backBuffer.get();
-    } else {
-        mSharedBufferClient->undoDequeue(bufIdx);
-    }
-
-    return err;
-}
-
-int Surface::lockBuffer(android_native_buffer_t* buffer)
-{
-    sp<SurfaceComposerClient> client(getClient());
-    status_t err = validate();
-    if (err != NO_ERROR)
-        return err;
-
-    int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
-    err = mSharedBufferClient->lock(bufIdx);
-    LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
-    return err;
-}
-
-int Surface::queueBuffer(android_native_buffer_t* buffer)
-{   
-    sp<SurfaceComposerClient> client(getClient());
-    status_t err = validate();
-    if (err != NO_ERROR)
-        return err;
-
-    if (mSwapRectangle.isValid()) {
-        mDirtyRegion.set(mSwapRectangle);
-    }
-    
-    int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
-    mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
-    err = mSharedBufferClient->queue(bufIdx);
-    LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
-
-    if (err == NO_ERROR) {
-        // FIXME: can we avoid this IPC if we know there is one pending?
-        client->signalServer();
-    }
-    return err;
-}
-
-int Surface::query(int what, int* value)
-{
-    switch (what) {
-    case NATIVE_WINDOW_WIDTH:
-        *value = int(mWidth);
-        return NO_ERROR;
-    case NATIVE_WINDOW_HEIGHT:
-        *value = int(mHeight);
-        return NO_ERROR;
-    case NATIVE_WINDOW_FORMAT:
-        *value = int(mFormat);
-        return NO_ERROR;
-    }
-    return BAD_VALUE;
-}
-
-int Surface::perform(int operation, va_list args)
-{
-    int res = NO_ERROR;
-    switch (operation) {
-        case NATIVE_WINDOW_SET_USAGE:
-            setUsage( va_arg(args, int) );
-            break;
-        default:
-            res = NAME_NOT_FOUND;
-            break;
-    }
-    return res;
-}
-
-void Surface::setUsage(uint32_t reqUsage)
-{
-    Mutex::Autolock _l(mSurfaceLock);
-    mUsage = reqUsage;
-}
-
-uint32_t Surface::getUsage() const
-{
-    Mutex::Autolock _l(mSurfaceLock);
-    return mUsage;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t Surface::lock(SurfaceInfo* info, bool blocking) {
-    return Surface::lock(info, NULL, blocking);
-}
-
-status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) 
-{
-    if (mApiLock.tryLock() != NO_ERROR) {
-        LOGE("calling Surface::lock from different threads!");
-        CallStack stack;
-        stack.update();
-        stack.dump("Surface::lock called from different threads");
-        return WOULD_BLOCK;
-    }
-
-    /* Here we're holding mApiLock */
-    
-    if (mLockedBuffer != 0) {
-        LOGE("Surface::lock failed, already locked");
-        mApiLock.unlock();
-        return INVALID_OPERATION;
-    }
-
-    // we're intending to do software rendering from this point
-    setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
-
-    sp<GraphicBuffer> backBuffer;
-    status_t err = dequeueBuffer(&backBuffer);
-    LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
-    if (err == NO_ERROR) {
-        err = lockBuffer(backBuffer.get());
-        LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
-                backBuffer->getIndex(), strerror(-err));
-        if (err == NO_ERROR) {
-            // we handle copy-back here...
-
-            const Rect bounds(backBuffer->width, backBuffer->height);
-            Region scratch(bounds);
-            Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
-
-            if (mNeedFullUpdate) {
-                // reset newDirtyRegion to bounds when a buffer is reallocated
-                // it would be better if this information was associated with
-                // the buffer and made available to outside of Surface.
-                // This will do for now though.
-                mNeedFullUpdate = false;
-                newDirtyRegion.set(bounds);
-            } else {
-                newDirtyRegion.andSelf(bounds);
-            }
-
-            const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
-            if (frontBuffer !=0 &&
-                backBuffer->width  == frontBuffer->width && 
-                backBuffer->height == frontBuffer->height &&
-                !(mFlags & ISurfaceComposer::eDestroyBackbuffer)) 
-            {
-                const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
-                if (!copyback.isEmpty() && frontBuffer!=0) {
-                    // copy front to back
-                    copyBlt(backBuffer, frontBuffer, copyback);
-                }
-            }
-
-            mDirtyRegion = newDirtyRegion;
-            mOldDirtyRegion = newDirtyRegion;
-
-            void* vaddr;
-            status_t res = backBuffer->lock(
-                    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
-                    newDirtyRegion.bounds(), &vaddr);
-            
-            LOGW_IF(res, "failed locking buffer (handle = %p)", 
-                    backBuffer->handle);
-
-            mLockedBuffer = backBuffer;
-            other->w      = backBuffer->width;
-            other->h      = backBuffer->height;
-            other->s      = backBuffer->stride;
-            other->usage  = backBuffer->usage;
-            other->format = backBuffer->format;
-            other->bits   = vaddr;
-        }
-    }
-    mApiLock.unlock();
-    return err;
-}
-    
-status_t Surface::unlockAndPost() 
-{
-    if (mLockedBuffer == 0) {
-        LOGE("Surface::unlockAndPost failed, no locked buffer");
-        return INVALID_OPERATION;
-    }
-
-    status_t err = mLockedBuffer->unlock();
-    LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
-    
-    err = queueBuffer(mLockedBuffer.get());
-    LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
-            mLockedBuffer->getIndex(), strerror(-err));
-
-    mPostedBuffer = mLockedBuffer;
-    mLockedBuffer = 0;
-    return err;
-}
-
-void Surface::setSwapRectangle(const Rect& r) {
-    Mutex::Autolock _l(mSurfaceLock);
-    mSwapRectangle = r;
-}
-
-status_t Surface::getBufferLocked(int index, int usage)
-{
-    sp<ISurface> s(mSurface);
-    if (s == 0) return NO_INIT;
-
-    status_t err = NO_MEMORY;
-
-    // free the current buffer
-    sp<GraphicBuffer>& currentBuffer(mBuffers[index]);
-    if (currentBuffer != 0) {
-        getBufferMapper().unregisterBuffer(currentBuffer->handle);
-        currentBuffer.clear();
-    }
-
-    sp<GraphicBuffer> buffer = s->requestBuffer(index, usage);
-    LOGE_IF(buffer==0,
-            "ISurface::getBuffer(%d, %08x) returned NULL",
-            index, usage);
-    if (buffer != 0) { // this should never happen by construction
-        LOGE_IF(buffer->handle == NULL, 
-                "Surface (identity=%d) requestBuffer(%d, %08x) returned"
-                "a buffer with a null handle", mIdentity, index, usage);
-        err = mSharedBufferClient->getStatus();
-        LOGE_IF(err,  "Surface (identity=%d) state = %d", mIdentity, err);
-        if (!err && buffer->handle != NULL) {
-            err = getBufferMapper().registerBuffer(buffer->handle);
-            LOGW_IF(err, "registerBuffer(...) failed %d (%s)",
-                    err, strerror(-err));
-            if (err == NO_ERROR) {
-                currentBuffer = buffer;
-                currentBuffer->setIndex(index);
-                mNeedFullUpdate = true;
-            }
-        } else {
-            err = err<0 ? err : NO_MEMORY;
-        }
-    }
-    return err; 
-}
-
-}; // namespace android
-
diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp
deleted file mode 100644
index eda84ef..0000000
--- a/libs/ui/SurfaceComposerClient.cpp
+++ /dev/null
@@ -1,620 +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 "SurfaceComposerClient"
-
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <cutils/memory.h>
-
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/threads.h>
-#include <utils/KeyedVector.h>
-#include <binder/IServiceManager.h>
-#include <binder/IMemory.h>
-#include <utils/Log.h>
-
-#include <ui/DisplayInfo.h>
-#include <ui/ISurfaceComposer.h>
-#include <ui/ISurfaceFlingerClient.h>
-#include <ui/ISurface.h>
-#include <ui/SurfaceComposerClient.h>
-#include <ui/Rect.h>
-
-#include <private/ui/LayerState.h>
-#include <private/ui/SharedBufferStack.h>
-
-#define VERBOSE(...)	((void)0)
-//#define VERBOSE			LOGD
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-// Must not be holding SurfaceComposerClient::mLock when acquiring gLock here.
-static Mutex                                                gLock;
-static sp<ISurfaceComposer>                                 gSurfaceManager;
-static DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections;
-static SortedVector<sp<SurfaceComposerClient> >             gOpenTransactions;
-static sp<IMemoryHeap>                                      gServerCblkMemory;
-static volatile surface_flinger_cblk_t*                     gServerCblk;
-
-static sp<ISurfaceComposer> getComposerService()
-{
-    sp<ISurfaceComposer> sc;
-    Mutex::Autolock _l(gLock);
-    if (gSurfaceManager != 0) {
-        sc = gSurfaceManager;
-    } else {
-        // release the lock while we're waiting...
-        gLock.unlock();
-
-        sp<IBinder> binder;
-        sp<IServiceManager> sm = defaultServiceManager();
-        do {
-            binder = sm->getService(String16("SurfaceFlinger"));
-            if (binder == 0) {
-                LOGW("SurfaceFlinger not published, waiting...");
-                usleep(500000); // 0.5 s
-            }
-        } while(binder == 0);
-
-        // grab the lock again for updating gSurfaceManager
-        gLock.lock();
-        if (gSurfaceManager == 0) {
-            sc = interface_cast<ISurfaceComposer>(binder);
-            gSurfaceManager = sc;
-        } else {
-            sc = gSurfaceManager;
-        }
-    }
-    return sc;
-}
-
-static volatile surface_flinger_cblk_t const * get_cblk()
-{
-    if (gServerCblk == 0) {
-        sp<ISurfaceComposer> sm(getComposerService());
-        Mutex::Autolock _l(gLock);
-        if (gServerCblk == 0) {
-            gServerCblkMemory = sm->getCblk();
-            LOGE_IF(gServerCblkMemory==0, "Can't get server control block");
-            gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->getBase();
-            LOGE_IF(gServerCblk==0, "Can't get server control block address");
-        }
-    }
-    return gServerCblk;
-}
-
-// ---------------------------------------------------------------------------
-
-static inline int compare_type( const layer_state_t& lhs,
-                                const layer_state_t& rhs) {
-    if (lhs.surface < rhs.surface)  return -1;
-    if (lhs.surface > rhs.surface)  return 1;
-    return 0;
-}
-
-SurfaceComposerClient::SurfaceComposerClient()
-{
-    sp<ISurfaceComposer> sm(getComposerService());
-    if (sm == 0) {
-        _init(0, 0);
-        return;
-    }
-
-    _init(sm, sm->createConnection());
-
-    if (mClient != 0) {
-        Mutex::Autolock _l(gLock);
-        VERBOSE("Adding client %p to map", this);
-        gActiveConnections.add(mClient->asBinder(), this);
-    }
-}
-
-SurfaceComposerClient::SurfaceComposerClient(
-        const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn)
-{
-    _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
-}
-
-
-status_t SurfaceComposerClient::linkToComposerDeath(
-        const sp<IBinder::DeathRecipient>& recipient,
-        void* cookie, uint32_t flags)
-{
-    sp<ISurfaceComposer> sm(getComposerService());
-    return sm->asBinder()->linkToDeath(recipient, cookie, flags);    
-}
-
-void SurfaceComposerClient::_init(
-        const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
-{
-    VERBOSE("Creating client %p, conn %p", this, conn.get());
-
-    mPrebuiltLayerState = 0;
-    mTransactionOpen = 0;
-    mStatus = NO_ERROR;
-    mControl = 0;
-
-    mClient = conn;
-    if (mClient == 0) {
-        mStatus = NO_INIT;
-        return;
-    }
-
-    mControlMemory = mClient->getControlBlock();
-    mSignalServer = sm;
-    mControl = static_cast<SharedClient *>(mControlMemory->getBase());
-}
-
-SurfaceComposerClient::~SurfaceComposerClient()
-{
-    VERBOSE("Destroying client %p, conn %p", this, mClient.get());
-    dispose();
-}
-
-status_t SurfaceComposerClient::initCheck() const
-{
-    return mStatus;
-}
-
-sp<IBinder> SurfaceComposerClient::connection() const
-{
-    return (mClient != 0) ? mClient->asBinder() : 0;
-}
-
-sp<SurfaceComposerClient>
-SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
-{
-    sp<SurfaceComposerClient> client;
-
-    { // scope for lock
-        Mutex::Autolock _l(gLock);
-        client = gActiveConnections.valueFor(conn);
-    }
-
-    if (client == 0) {
-        // Need to make a new client.
-        sp<ISurfaceComposer> sm(getComposerService());
-        client = new SurfaceComposerClient(sm, conn);
-        if (client != 0 && client->initCheck() == NO_ERROR) {
-            Mutex::Autolock _l(gLock);
-            gActiveConnections.add(conn, client);
-            //LOGD("we have %d connections", gActiveConnections.size());
-        } else {
-            client.clear();
-        }
-    }
-
-    return client;
-}
-
-void SurfaceComposerClient::dispose()
-{
-    // this can be called more than once.
-
-    sp<IMemoryHeap>             controlMemory;
-    sp<ISurfaceFlingerClient>   client;
-
-    {
-        Mutex::Autolock _lg(gLock);
-        Mutex::Autolock _lm(mLock);
-
-        mSignalServer = 0;
-
-        if (mClient != 0) {
-            client = mClient;
-            mClient.clear();
-
-            ssize_t i = gActiveConnections.indexOfKey(client->asBinder());
-            if (i >= 0 && gActiveConnections.valueAt(i) == this) {
-                VERBOSE("Removing client %p from map at %d", this, int(i));
-                gActiveConnections.removeItemsAt(i);
-            }
-        }
-
-        delete mPrebuiltLayerState;
-        mPrebuiltLayerState = 0;
-        controlMemory = mControlMemory;
-        mControlMemory.clear();
-        mControl = 0;
-        mStatus = NO_INIT;
-    }
-}
-
-status_t SurfaceComposerClient::getDisplayInfo(
-        DisplayID dpy, DisplayInfo* info)
-{
-    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
-        return BAD_VALUE;
-
-    volatile surface_flinger_cblk_t const * cblk = get_cblk();
-    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
-
-    info->w              = dcblk->w;
-    info->h              = dcblk->h;
-    info->orientation    = dcblk->orientation;
-    info->xdpi           = dcblk->xdpi;
-    info->ydpi           = dcblk->ydpi;
-    info->fps            = dcblk->fps;
-    info->density        = dcblk->density;
-    return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
-}
-
-ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
-{
-    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
-        return BAD_VALUE;
-    volatile surface_flinger_cblk_t const * cblk = get_cblk();
-    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
-    return dcblk->w;
-}
-
-ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
-{
-    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
-        return BAD_VALUE;
-    volatile surface_flinger_cblk_t const * cblk = get_cblk();
-    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
-    return dcblk->h;
-}
-
-ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
-{
-    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
-        return BAD_VALUE;
-    volatile surface_flinger_cblk_t const * cblk = get_cblk();
-    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
-    return dcblk->orientation;
-}
-
-ssize_t SurfaceComposerClient::getNumberOfDisplays()
-{
-    volatile surface_flinger_cblk_t const * cblk = get_cblk();
-    uint32_t connected = cblk->connected;
-    int n = 0;
-    while (connected) {
-        if (connected&1) n++;
-        connected >>= 1;
-    }
-    return n;
-}
-
-
-void SurfaceComposerClient::signalServer()
-{
-    mSignalServer->signal();
-}
-
-sp<SurfaceControl> SurfaceComposerClient::createSurface(
-        int pid,
-        DisplayID display,
-        uint32_t w,
-        uint32_t h,
-        PixelFormat format,
-        uint32_t flags)
-{
-    sp<SurfaceControl> result;
-    if (mStatus == NO_ERROR) {
-        ISurfaceFlingerClient::surface_data_t data;
-        sp<ISurface> surface = mClient->createSurface(&data, pid,
-                display, w, h, format, flags);
-        if (surface != 0) {
-            if (uint32_t(data.token) < NUM_LAYERS_MAX) {
-                result = new SurfaceControl(this, surface, data, w, h, format, flags);
-            }
-        }
-    }
-    return result;
-}
-
-status_t SurfaceComposerClient::destroySurface(SurfaceID sid)
-{
-    if (mStatus != NO_ERROR)
-        return mStatus;
-
-    // it's okay to destroy a surface while a transaction is open,
-    // (transactions really are a client-side concept)
-    // however, this indicates probably a misuse of the API or a bug
-    // in the client code.
-    LOGW_IF(mTransactionOpen,
-         "Destroying surface while a transaction is open. "
-         "Client %p: destroying surface %d, mTransactionOpen=%d",
-         this, sid, mTransactionOpen);
-
-    status_t err = mClient->destroySurface(sid);
-    return err;
-}
-
-void SurfaceComposerClient::openGlobalTransaction()
-{
-    Mutex::Autolock _l(gLock);
-
-    if (gOpenTransactions.size()) {
-        LOGE("openGlobalTransaction() called more than once. skipping.");
-        return;
-    }
-
-    const size_t N = gActiveConnections.size();
-    VERBOSE("openGlobalTransaction (%ld clients)", N);
-    for (size_t i=0; i<N; i++) {
-        sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i));
-        if (gOpenTransactions.indexOf(client) < 0) {
-            if (client->openTransaction() == NO_ERROR) {
-                if (gOpenTransactions.add(client) < 0) {
-                    // Ooops!
-                    LOGE(   "Unable to add a SurfaceComposerClient "
-                            "to the global transaction set (out of memory?)");
-                    client->closeTransaction();
-                    // let it go, it'll fail later when the user
-                    // tries to do something with the transaction
-                }
-            } else {
-                LOGE("openTransaction on client %p failed", client.get());
-                // let it go, it'll fail later when the user
-                // tries to do something with the transaction
-            }
-        }
-    }
-}
-
-void SurfaceComposerClient::closeGlobalTransaction()
-{
-    gLock.lock();
-        SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions);
-        gOpenTransactions.clear();
-    gLock.unlock();
-
-    const size_t N = clients.size();
-    VERBOSE("closeGlobalTransaction (%ld clients)", N);
-
-    sp<ISurfaceComposer> sm(getComposerService());
-    sm->openGlobalTransaction();
-    for (size_t i=0; i<N; i++) {
-        clients[i]->closeTransaction();
-    }
-    sm->closeGlobalTransaction();
-
-}
-
-
-status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
-{
-    sp<ISurfaceComposer> sm(getComposerService());
-    return sm->freezeDisplay(dpy, flags);
-}
-
-status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
-{
-    sp<ISurfaceComposer> sm(getComposerService());
-    return sm->unfreezeDisplay(dpy, flags);
-}
-
-int SurfaceComposerClient::setOrientation(DisplayID dpy, 
-        int orientation, uint32_t flags)
-{
-    sp<ISurfaceComposer> sm(getComposerService());
-    return sm->setOrientation(dpy, orientation, flags);
-}
-
-status_t SurfaceComposerClient::openTransaction()
-{
-    if (mStatus != NO_ERROR)
-        return mStatus;
-    Mutex::Autolock _l(mLock);
-    VERBOSE(   "openTransaction (client %p, mTransactionOpen=%d)",
-            this, mTransactionOpen);
-    mTransactionOpen++;
-    if (mPrebuiltLayerState == 0) {
-        mPrebuiltLayerState = new layer_state_t;
-    }
-    return NO_ERROR;
-}
-
-
-status_t SurfaceComposerClient::closeTransaction()
-{
-    if (mStatus != NO_ERROR)
-        return mStatus;
-
-    Mutex::Autolock _l(mLock);
-
-    VERBOSE(   "closeTransaction (client %p, mTransactionOpen=%d)",
-            this, mTransactionOpen);
-
-    if (mTransactionOpen <= 0) {
-        LOGE(   "closeTransaction (client %p, mTransactionOpen=%d) "
-                "called more times than openTransaction()",
-                this, mTransactionOpen);
-        return INVALID_OPERATION;
-    }
-
-    if (mTransactionOpen >= 2) {
-        mTransactionOpen--;
-        return NO_ERROR;
-    }
-
-    mTransactionOpen = 0;
-    const ssize_t count = mStates.size();
-    if (count) {
-        mClient->setState(count, mStates.array());
-        mStates.clear();
-    }
-    return NO_ERROR;
-}
-
-layer_state_t* SurfaceComposerClient::_get_state_l(SurfaceID index)
-{
-    // API usage error, do nothing.
-    if (mTransactionOpen<=0) {
-        LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
-                this, int(index), mTransactionOpen);
-        return 0;
-    }
-
-    // use mPrebuiltLayerState just to find out if we already have it
-    layer_state_t& dummy = *mPrebuiltLayerState;
-    dummy.surface = index;
-    ssize_t i = mStates.indexOf(dummy);
-    if (i < 0) {
-        // we don't have it, add an initialized layer_state to our list
-        i = mStates.add(dummy);
-    }
-    return mStates.editArray() + i;
-}
-
-layer_state_t* SurfaceComposerClient::_lockLayerState(SurfaceID id)
-{
-    layer_state_t* s;
-    mLock.lock();
-    s = _get_state_l(id);
-    if (!s) mLock.unlock();
-    return s;
-}
-
-void SurfaceComposerClient::_unlockLayerState()
-{
-    mLock.unlock();
-}
-
-status_t SurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y)
-{
-    layer_state_t* s = _lockLayerState(id);
-    if (!s) return BAD_INDEX;
-    s->what |= ISurfaceComposer::ePositionChanged;
-    s->x = x;
-    s->y = y;
-    _unlockLayerState();
-    return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h)
-{
-    layer_state_t* s = _lockLayerState(id);
-    if (!s) return BAD_INDEX;
-    s->what |= ISurfaceComposer::eSizeChanged;
-    s->w = w;
-    s->h = h;
-    _unlockLayerState();
-    return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z)
-{
-    layer_state_t* s = _lockLayerState(id);
-    if (!s) return BAD_INDEX;
-    s->what |= ISurfaceComposer::eLayerChanged;
-    s->z = z;
-    _unlockLayerState();
-    return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::hide(SurfaceID id)
-{
-    return setFlags(id, ISurfaceComposer::eLayerHidden,
-            ISurfaceComposer::eLayerHidden);
-}
-
-status_t SurfaceComposerClient::show(SurfaceID id, int32_t)
-{
-    return setFlags(id, 0, ISurfaceComposer::eLayerHidden);
-}
-
-status_t SurfaceComposerClient::freeze(SurfaceID id)
-{
-    return setFlags(id, ISurfaceComposer::eLayerFrozen,
-            ISurfaceComposer::eLayerFrozen);
-}
-
-status_t SurfaceComposerClient::unfreeze(SurfaceID id)
-{
-    return setFlags(id, 0, ISurfaceComposer::eLayerFrozen);
-}
-
-status_t SurfaceComposerClient::setFlags(SurfaceID id,
-        uint32_t flags, uint32_t mask)
-{
-    layer_state_t* s = _lockLayerState(id);
-    if (!s) return BAD_INDEX;
-    s->what |= ISurfaceComposer::eVisibilityChanged;
-    s->flags &= ~mask;
-    s->flags |= (flags & mask);
-    s->mask |= mask;
-    _unlockLayerState();
-    return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setTransparentRegionHint(
-        SurfaceID id, const Region& transparentRegion)
-{
-    layer_state_t* s = _lockLayerState(id);
-    if (!s) return BAD_INDEX;
-    s->what |= ISurfaceComposer::eTransparentRegionChanged;
-    s->transparentRegion = transparentRegion;
-    _unlockLayerState();
-    return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha)
-{
-    layer_state_t* s = _lockLayerState(id);
-    if (!s) return BAD_INDEX;
-    s->what |= ISurfaceComposer::eAlphaChanged;
-    s->alpha = alpha;
-    _unlockLayerState();
-    return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setMatrix(
-        SurfaceID id,
-        float dsdx, float dtdx,
-        float dsdy, float dtdy )
-{
-    layer_state_t* s = _lockLayerState(id);
-    if (!s) return BAD_INDEX;
-    s->what |= ISurfaceComposer::eMatrixChanged;
-    layer_state_t::matrix22_t matrix;
-    matrix.dsdx = dsdx;
-    matrix.dtdx = dtdx;
-    matrix.dsdy = dsdy;
-    matrix.dtdy = dtdy;
-    s->matrix = matrix;
-    _unlockLayerState();
-    return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint)
-{
-    layer_state_t* s = _lockLayerState(id);
-    if (!s) return BAD_INDEX;
-    s->what |= ISurfaceComposer::eFreezeTintChanged;
-    s->tint = tint;
-    _unlockLayerState();
-    return NO_ERROR;
-}
-
-}; // namespace android
-
