diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
index 848c5a1..fc260c4 100644
--- a/include/ui/PixelFormat.h
+++ b/include/ui/PixelFormat.h
@@ -21,7 +21,6 @@
 // skia or SurfaceFlinger are not required to support all of these formats
 // (either as source or destination)
 
-// XXX: we should consolidate these formats and skia's
 
 #ifndef UI_PIXELFORMAT_H
 #define UI_PIXELFORMAT_H
@@ -29,7 +28,6 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <utils/Errors.h>
-#include <pixelflinger/format.h>
 #include <hardware/hardware.h>
 
 namespace android {
@@ -65,10 +63,7 @@
     PIXEL_FORMAT_BGRA_8888   = HAL_PIXEL_FORMAT_BGRA_8888,  // 4x8-bit BGRA
     PIXEL_FORMAT_RGBA_5551   = HAL_PIXEL_FORMAT_RGBA_5551,  // 16-bit ARGB
     PIXEL_FORMAT_RGBA_4444   = HAL_PIXEL_FORMAT_RGBA_4444,  // 16-bit ARGB
-    PIXEL_FORMAT_A_8         = GGL_PIXEL_FORMAT_A_8,        // 8-bit A
-    PIXEL_FORMAT_L_8         = GGL_PIXEL_FORMAT_L_8,        // 8-bit L (R=G=B=L)
-    PIXEL_FORMAT_LA_88       = GGL_PIXEL_FORMAT_LA_88,      // 16-bit LA
-    PIXEL_FORMAT_RGB_332     = GGL_PIXEL_FORMAT_RGB_332,    // 8-bit RGB
+    PIXEL_FORMAT_A_8         = 8,                           // 8-bit A
 
     // New formats can be added if they're also defined in
     // pixelflinger/format.h
@@ -76,8 +71,7 @@
 
 typedef int32_t PixelFormat;
 
-struct PixelFormatInfo
-{
+struct PixelFormatInfo {
     enum {
         INDEX_ALPHA   = 0,
         INDEX_RED     = 1,
@@ -89,8 +83,6 @@
         ALPHA               = 1,
         RGB                 = 2,
         RGBA                = 3,
-        LUMINANCE           = 4,
-        LUMINANCE_ALPHA     = 5,
         OTHER               = 0xFF
     };
 
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index f8b4452..c029291 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -13,41 +13,14 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
-
-# libui is partially built for the host (used by build time keymap validation tool)
-# These files are common to host and target builds.
-commonSources:= \
-	Input.cpp \
-	Keyboard.cpp \
-	KeyLayoutMap.cpp \
-	KeyCharacterMap.cpp \
-	VirtualKeyMap.cpp
-
-# For the host
-# =====================================================
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= $(commonSources)
-
-LOCAL_MODULE:= libui
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-
-# For the device
-# =====================================================
-
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-	$(commonSources) \
 	EGLUtils.cpp \
 	FramebufferNativeWindow.cpp \
 	GraphicBuffer.cpp \
 	GraphicBufferAllocator.cpp \
 	GraphicBufferMapper.cpp \
-	InputTransport.cpp \
 	PixelFormat.cpp \
 	Rect.cpp \
 	Region.cpp
@@ -56,14 +29,11 @@
 	libcutils \
 	libutils \
 	libEGL \
-	libpixelflinger \
-	libhardware \
-	libhardware_legacy \
-	libskia \
-	libbinder
+	libhardware
 
-LOCAL_C_INCLUDES := \
-    external/skia/include/core
+ifneq ($(BOARD_FRAMEBUFFER_FORCE_FORMAT),)
+LOCAL_CFLAGS += -DFRAMEBUFFER_FORCE_FORMAT=$(BOARD_FRAMEBUFFER_FORCE_FORMAT)
+endif
 
 LOCAL_MODULE:= libui
 
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index d1dca0c..26d4823 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -100,6 +100,18 @@
         mNumFreeBuffers = NUM_FRAME_BUFFERS;
         mBufferHead = mNumBuffers-1;
 
+        /*
+         * This does not actually change the framebuffer format. It merely
+         * fakes this format to surfaceflinger so that when it creates
+         * framebuffer surfaces it will use this format. It's really a giant
+         * HACK to allow interworking with buggy gralloc+GPU driver
+         * implementations. You should *NEVER* need to set this for shipping
+         * devices.
+         */
+#ifdef FRAMEBUFFER_FORCE_FORMAT
+        *((uint32_t *)&fbDev->format) = FRAMEBUFFER_FORCE_FORMAT;
+#endif
+
         for (i = 0; i < mNumBuffers; i++)
         {
                 buffers[i] = new NativeBuffer(
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
deleted file mode 100644
index ca09caf..0000000
--- a/libs/ui/Input.cpp
+++ /dev/null
@@ -1,1223 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-// Provides a pipe-based transport for native events in the NDK.
-//
-#define LOG_TAG "Input"
-
-//#define LOG_NDEBUG 0
-
-// Log debug messages about keymap probing.
-#define DEBUG_PROBE 0
-
-// Log debug messages about velocity tracking.
-#define DEBUG_VELOCITY 0
-
-// Log debug messages about least squares fitting.
-#define DEBUG_LEAST_SQUARES 0
-
-// Log debug messages about acceleration.
-#define DEBUG_ACCELERATION 0
-
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-
-#include <androidfw/Input.h>
-
-#include <math.h>
-#include <limits.h>
-
-#ifdef HAVE_ANDROID_OS
-#include <binder/Parcel.h>
-
-#include "SkPoint.h"
-#include "SkMatrix.h"
-#include "SkScalar.h"
-#endif
-
-namespace android {
-
-static const char* CONFIGURATION_FILE_DIR[] = {
-        "idc/",
-        "keylayout/",
-        "keychars/",
-};
-
-static const char* CONFIGURATION_FILE_EXTENSION[] = {
-        ".idc",
-        ".kl",
-        ".kcm",
-};
-
-static bool isValidNameChar(char ch) {
-    return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_');
-}
-
-static void appendInputDeviceConfigurationFileRelativePath(String8& path,
-        const String8& name, InputDeviceConfigurationFileType type) {
-    path.append(CONFIGURATION_FILE_DIR[type]);
-    for (size_t i = 0; i < name.length(); i++) {
-        char ch = name[i];
-        if (!isValidNameChar(ch)) {
-            ch = '_';
-        }
-        path.append(&ch, 1);
-    }
-    path.append(CONFIGURATION_FILE_EXTENSION[type]);
-}
-
-String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
-        const InputDeviceIdentifier& deviceIdentifier,
-        InputDeviceConfigurationFileType type) {
-    if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
-        if (deviceIdentifier.version != 0) {
-            // Try vendor product version.
-            String8 versionPath(getInputDeviceConfigurationFilePathByName(
-                    String8::format("Vendor_%04x_Product_%04x_Version_%04x",
-                            deviceIdentifier.vendor, deviceIdentifier.product,
-                            deviceIdentifier.version),
-                    type));
-            if (!versionPath.isEmpty()) {
-                return versionPath;
-            }
-        }
-
-        // Try vendor product.
-        String8 productPath(getInputDeviceConfigurationFilePathByName(
-                String8::format("Vendor_%04x_Product_%04x",
-                        deviceIdentifier.vendor, deviceIdentifier.product),
-                type));
-        if (!productPath.isEmpty()) {
-            return productPath;
-        }
-    }
-
-    // Try device name.
-    return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
-}
-
-String8 getInputDeviceConfigurationFilePathByName(
-        const String8& name, InputDeviceConfigurationFileType type) {
-    // Search system repository.
-    String8 path;
-    path.setTo(getenv("ANDROID_ROOT"));
-    path.append("/usr/");
-    appendInputDeviceConfigurationFileRelativePath(path, name, type);
-#if DEBUG_PROBE
-    ALOGD("Probing for system provided input device configuration file: path='%s'", path.string());
-#endif
-    if (!access(path.string(), R_OK)) {
-#if DEBUG_PROBE
-        ALOGD("Found");
-#endif
-        return path;
-    }
-
-    // Search user repository.
-    // TODO Should only look here if not in safe mode.
-    path.setTo(getenv("ANDROID_DATA"));
-    path.append("/system/devices/");
-    appendInputDeviceConfigurationFileRelativePath(path, name, type);
-#if DEBUG_PROBE
-    ALOGD("Probing for system user input device configuration file: path='%s'", path.string());
-#endif
-    if (!access(path.string(), R_OK)) {
-#if DEBUG_PROBE
-        ALOGD("Found");
-#endif
-        return path;
-    }
-
-    // Not found.
-#if DEBUG_PROBE
-    ALOGD("Probe failed to find input device configuration file: name='%s', type=%d",
-            name.string(), type);
-#endif
-    return String8();
-}
-
-
-// --- InputEvent ---
-
-void InputEvent::initialize(int32_t deviceId, int32_t source) {
-    mDeviceId = deviceId;
-    mSource = source;
-}
-
-void InputEvent::initialize(const InputEvent& from) {
-    mDeviceId = from.mDeviceId;
-    mSource = from.mSource;
-}
-
-// --- KeyEvent ---
-
-bool KeyEvent::hasDefaultAction(int32_t keyCode) {
-    switch (keyCode) {
-        case AKEYCODE_HOME:
-        case AKEYCODE_BACK:
-        case AKEYCODE_CALL:
-        case AKEYCODE_ENDCALL:
-        case AKEYCODE_VOLUME_UP:
-        case AKEYCODE_VOLUME_DOWN:
-        case AKEYCODE_VOLUME_MUTE:
-        case AKEYCODE_POWER:
-        case AKEYCODE_CAMERA:
-        case AKEYCODE_HEADSETHOOK:
-        case AKEYCODE_MENU:
-        case AKEYCODE_NOTIFICATION:
-        case AKEYCODE_FOCUS:
-        case AKEYCODE_SEARCH:
-        case AKEYCODE_MEDIA_PLAY:
-        case AKEYCODE_MEDIA_PAUSE:
-        case AKEYCODE_MEDIA_PLAY_PAUSE:
-        case AKEYCODE_MEDIA_STOP:
-        case AKEYCODE_MEDIA_NEXT:
-        case AKEYCODE_MEDIA_PREVIOUS:
-        case AKEYCODE_MEDIA_REWIND:
-        case AKEYCODE_MEDIA_RECORD:
-        case AKEYCODE_MEDIA_FAST_FORWARD:
-        case AKEYCODE_MUTE:
-            return true;
-    }
-    
-    return false;
-}
-
-bool KeyEvent::hasDefaultAction() const {
-    return hasDefaultAction(getKeyCode());
-}
-
-bool KeyEvent::isSystemKey(int32_t keyCode) {
-    switch (keyCode) {
-        case AKEYCODE_MENU:
-        case AKEYCODE_SOFT_RIGHT:
-        case AKEYCODE_HOME:
-        case AKEYCODE_BACK:
-        case AKEYCODE_CALL:
-        case AKEYCODE_ENDCALL:
-        case AKEYCODE_VOLUME_UP:
-        case AKEYCODE_VOLUME_DOWN:
-        case AKEYCODE_VOLUME_MUTE:
-        case AKEYCODE_MUTE:
-        case AKEYCODE_POWER:
-        case AKEYCODE_HEADSETHOOK:
-        case AKEYCODE_MEDIA_PLAY:
-        case AKEYCODE_MEDIA_PAUSE:
-        case AKEYCODE_MEDIA_PLAY_PAUSE:
-        case AKEYCODE_MEDIA_STOP:
-        case AKEYCODE_MEDIA_NEXT:
-        case AKEYCODE_MEDIA_PREVIOUS:
-        case AKEYCODE_MEDIA_REWIND:
-        case AKEYCODE_MEDIA_RECORD:
-        case AKEYCODE_MEDIA_FAST_FORWARD:
-        case AKEYCODE_CAMERA:
-        case AKEYCODE_FOCUS:
-        case AKEYCODE_SEARCH:
-            return true;
-    }
-    
-    return false;
-}
-
-bool KeyEvent::isSystemKey() const {
-    return isSystemKey(getKeyCode());
-}
-
-void KeyEvent::initialize(
-        int32_t deviceId,
-        int32_t source,
-        int32_t action,
-        int32_t flags,
-        int32_t keyCode,
-        int32_t scanCode,
-        int32_t metaState,
-        int32_t repeatCount,
-        nsecs_t downTime,
-        nsecs_t eventTime) {
-    InputEvent::initialize(deviceId, source);
-    mAction = action;
-    mFlags = flags;
-    mKeyCode = keyCode;
-    mScanCode = scanCode;
-    mMetaState = metaState;
-    mRepeatCount = repeatCount;
-    mDownTime = downTime;
-    mEventTime = eventTime;
-}
-
-void KeyEvent::initialize(const KeyEvent& from) {
-    InputEvent::initialize(from);
-    mAction = from.mAction;
-    mFlags = from.mFlags;
-    mKeyCode = from.mKeyCode;
-    mScanCode = from.mScanCode;
-    mMetaState = from.mMetaState;
-    mRepeatCount = from.mRepeatCount;
-    mDownTime = from.mDownTime;
-    mEventTime = from.mEventTime;
-}
-
-
-// --- PointerCoords ---
-
-float PointerCoords::getAxisValue(int32_t axis) const {
-    if (axis < 0 || axis > 63) {
-        return 0;
-    }
-
-    uint64_t axisBit = 1LL << axis;
-    if (!(bits & axisBit)) {
-        return 0;
-    }
-    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
-    return values[index];
-}
-
-status_t PointerCoords::setAxisValue(int32_t axis, float value) {
-    if (axis < 0 || axis > 63) {
-        return NAME_NOT_FOUND;
-    }
-
-    uint64_t axisBit = 1LL << axis;
-    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
-    if (!(bits & axisBit)) {
-        if (value == 0) {
-            return OK; // axes with value 0 do not need to be stored
-        }
-        uint32_t count = __builtin_popcountll(bits);
-        if (count >= MAX_AXES) {
-            tooManyAxes(axis);
-            return NO_MEMORY;
-        }
-        bits |= axisBit;
-        for (uint32_t i = count; i > index; i--) {
-            values[i] = values[i - 1];
-        }
-    }
-    values[index] = value;
-    return OK;
-}
-
-static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
-    float value = c.getAxisValue(axis);
-    if (value != 0) {
-        c.setAxisValue(axis, value * scaleFactor);
-    }
-}
-
-void PointerCoords::scale(float scaleFactor) {
-    // No need to scale pressure or size since they are normalized.
-    // No need to scale orientation since it is meaningless to do so.
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
-}
-
-#ifdef HAVE_ANDROID_OS
-status_t PointerCoords::readFromParcel(Parcel* parcel) {
-    bits = parcel->readInt64();
-
-    uint32_t count = __builtin_popcountll(bits);
-    if (count > MAX_AXES) {
-        return BAD_VALUE;
-    }
-
-    for (uint32_t i = 0; i < count; i++) {
-        values[i] = parcel->readInt32();
-    }
-    return OK;
-}
-
-status_t PointerCoords::writeToParcel(Parcel* parcel) const {
-    parcel->writeInt64(bits);
-
-    uint32_t count = __builtin_popcountll(bits);
-    for (uint32_t i = 0; i < count; i++) {
-        parcel->writeInt32(values[i]);
-    }
-    return OK;
-}
-#endif
-
-void PointerCoords::tooManyAxes(int axis) {
-    ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
-            "cannot contain more than %d axis values.", axis, int(MAX_AXES));
-}
-
-bool PointerCoords::operator==(const PointerCoords& other) const {
-    if (bits != other.bits) {
-        return false;
-    }
-    uint32_t count = __builtin_popcountll(bits);
-    for (uint32_t i = 0; i < count; i++) {
-        if (values[i] != other.values[i]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-void PointerCoords::copyFrom(const PointerCoords& other) {
-    bits = other.bits;
-    uint32_t count = __builtin_popcountll(bits);
-    for (uint32_t i = 0; i < count; i++) {
-        values[i] = other.values[i];
-    }
-}
-
-
-// --- PointerProperties ---
-
-bool PointerProperties::operator==(const PointerProperties& other) const {
-    return id == other.id
-            && toolType == other.toolType;
-}
-
-void PointerProperties::copyFrom(const PointerProperties& other) {
-    id = other.id;
-    toolType = other.toolType;
-}
-
-
-// --- MotionEvent ---
-
-void MotionEvent::initialize(
-        int32_t deviceId,
-        int32_t source,
-        int32_t action,
-        int32_t flags,
-        int32_t edgeFlags,
-        int32_t metaState,
-        int32_t buttonState,
-        float xOffset,
-        float yOffset,
-        float xPrecision,
-        float yPrecision,
-        nsecs_t downTime,
-        nsecs_t eventTime,
-        size_t pointerCount,
-        const PointerProperties* pointerProperties,
-        const PointerCoords* pointerCoords) {
-    InputEvent::initialize(deviceId, source);
-    mAction = action;
-    mFlags = flags;
-    mEdgeFlags = edgeFlags;
-    mMetaState = metaState;
-    mButtonState = buttonState;
-    mXOffset = xOffset;
-    mYOffset = yOffset;
-    mXPrecision = xPrecision;
-    mYPrecision = yPrecision;
-    mDownTime = downTime;
-    mPointerProperties.clear();
-    mPointerProperties.appendArray(pointerProperties, pointerCount);
-    mSampleEventTimes.clear();
-    mSamplePointerCoords.clear();
-    addSample(eventTime, pointerCoords);
-}
-
-void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
-    InputEvent::initialize(other->mDeviceId, other->mSource);
-    mAction = other->mAction;
-    mFlags = other->mFlags;
-    mEdgeFlags = other->mEdgeFlags;
-    mMetaState = other->mMetaState;
-    mButtonState = other->mButtonState;
-    mXOffset = other->mXOffset;
-    mYOffset = other->mYOffset;
-    mXPrecision = other->mXPrecision;
-    mYPrecision = other->mYPrecision;
-    mDownTime = other->mDownTime;
-    mPointerProperties = other->mPointerProperties;
-
-    if (keepHistory) {
-        mSampleEventTimes = other->mSampleEventTimes;
-        mSamplePointerCoords = other->mSamplePointerCoords;
-    } else {
-        mSampleEventTimes.clear();
-        mSampleEventTimes.push(other->getEventTime());
-        mSamplePointerCoords.clear();
-        size_t pointerCount = other->getPointerCount();
-        size_t historySize = other->getHistorySize();
-        mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
-                + (historySize * pointerCount), pointerCount);
-    }
-}
-
-void MotionEvent::addSample(
-        int64_t eventTime,
-        const PointerCoords* pointerCoords) {
-    mSampleEventTimes.push(eventTime);
-    mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
-}
-
-const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
-    return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
-}
-
-float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
-    return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
-}
-
-float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
-    float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
-    switch (axis) {
-    case AMOTION_EVENT_AXIS_X:
-        return value + mXOffset;
-    case AMOTION_EVENT_AXIS_Y:
-        return value + mYOffset;
-    }
-    return value;
-}
-
-const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
-        size_t pointerIndex, size_t historicalIndex) const {
-    return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
-}
-
-float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
-        size_t historicalIndex) const {
-    return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
-}
-
-float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
-        size_t historicalIndex) const {
-    float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
-    switch (axis) {
-    case AMOTION_EVENT_AXIS_X:
-        return value + mXOffset;
-    case AMOTION_EVENT_AXIS_Y:
-        return value + mYOffset;
-    }
-    return value;
-}
-
-ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
-    size_t pointerCount = mPointerProperties.size();
-    for (size_t i = 0; i < pointerCount; i++) {
-        if (mPointerProperties.itemAt(i).id == pointerId) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-void MotionEvent::offsetLocation(float xOffset, float yOffset) {
-    mXOffset += xOffset;
-    mYOffset += yOffset;
-}
-
-void MotionEvent::scale(float scaleFactor) {
-    mXOffset *= scaleFactor;
-    mYOffset *= scaleFactor;
-    mXPrecision *= scaleFactor;
-    mYPrecision *= scaleFactor;
-
-    size_t numSamples = mSamplePointerCoords.size();
-    for (size_t i = 0; i < numSamples; i++) {
-        mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
-    }
-}
-
-#ifdef HAVE_ANDROID_OS
-static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
-    // Construct and transform a vector oriented at the specified clockwise angle from vertical.
-    // Coordinate system: down is increasing Y, right is increasing X.
-    SkPoint vector;
-    vector.fX = SkFloatToScalar(sinf(angleRadians));
-    vector.fY = SkFloatToScalar(-cosf(angleRadians));
-    matrix->mapVectors(& vector, 1);
-
-    // Derive the transformed vector's clockwise angle from vertical.
-    float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
-    if (result < - M_PI_2) {
-        result += M_PI;
-    } else if (result > M_PI_2) {
-        result -= M_PI;
-    }
-    return result;
-}
-
-void MotionEvent::transform(const SkMatrix* matrix) {
-    float oldXOffset = mXOffset;
-    float oldYOffset = mYOffset;
-
-    // The tricky part of this implementation is to preserve the value of
-    // rawX and rawY.  So we apply the transformation to the first point
-    // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
-    SkPoint point;
-    float rawX = getRawX(0);
-    float rawY = getRawY(0);
-    matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
-            & point);
-    float newX = SkScalarToFloat(point.fX);
-    float newY = SkScalarToFloat(point.fY);
-    float newXOffset = newX - rawX;
-    float newYOffset = newY - rawY;
-
-    mXOffset = newXOffset;
-    mYOffset = newYOffset;
-
-    // Apply the transformation to all samples.
-    size_t numSamples = mSamplePointerCoords.size();
-    for (size_t i = 0; i < numSamples; i++) {
-        PointerCoords& c = mSamplePointerCoords.editItemAt(i);
-        float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
-        float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
-        matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
-        c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
-        c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
-
-        float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
-        c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
-    }
-}
-
-status_t MotionEvent::readFromParcel(Parcel* parcel) {
-    size_t pointerCount = parcel->readInt32();
-    size_t sampleCount = parcel->readInt32();
-    if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
-        return BAD_VALUE;
-    }
-
-    mDeviceId = parcel->readInt32();
-    mSource = parcel->readInt32();
-    mAction = parcel->readInt32();
-    mFlags = parcel->readInt32();
-    mEdgeFlags = parcel->readInt32();
-    mMetaState = parcel->readInt32();
-    mButtonState = parcel->readInt32();
-    mXOffset = parcel->readFloat();
-    mYOffset = parcel->readFloat();
-    mXPrecision = parcel->readFloat();
-    mYPrecision = parcel->readFloat();
-    mDownTime = parcel->readInt64();
-
-    mPointerProperties.clear();
-    mPointerProperties.setCapacity(pointerCount);
-    mSampleEventTimes.clear();
-    mSampleEventTimes.setCapacity(sampleCount);
-    mSamplePointerCoords.clear();
-    mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
-
-    for (size_t i = 0; i < pointerCount; i++) {
-        mPointerProperties.push();
-        PointerProperties& properties = mPointerProperties.editTop();
-        properties.id = parcel->readInt32();
-        properties.toolType = parcel->readInt32();
-    }
-
-    while (sampleCount-- > 0) {
-        mSampleEventTimes.push(parcel->readInt64());
-        for (size_t i = 0; i < pointerCount; i++) {
-            mSamplePointerCoords.push();
-            status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
-            if (status) {
-                return status;
-            }
-        }
-    }
-    return OK;
-}
-
-status_t MotionEvent::writeToParcel(Parcel* parcel) const {
-    size_t pointerCount = mPointerProperties.size();
-    size_t sampleCount = mSampleEventTimes.size();
-
-    parcel->writeInt32(pointerCount);
-    parcel->writeInt32(sampleCount);
-
-    parcel->writeInt32(mDeviceId);
-    parcel->writeInt32(mSource);
-    parcel->writeInt32(mAction);
-    parcel->writeInt32(mFlags);
-    parcel->writeInt32(mEdgeFlags);
-    parcel->writeInt32(mMetaState);
-    parcel->writeInt32(mButtonState);
-    parcel->writeFloat(mXOffset);
-    parcel->writeFloat(mYOffset);
-    parcel->writeFloat(mXPrecision);
-    parcel->writeFloat(mYPrecision);
-    parcel->writeInt64(mDownTime);
-
-    for (size_t i = 0; i < pointerCount; i++) {
-        const PointerProperties& properties = mPointerProperties.itemAt(i);
-        parcel->writeInt32(properties.id);
-        parcel->writeInt32(properties.toolType);
-    }
-
-    const PointerCoords* pc = mSamplePointerCoords.array();
-    for (size_t h = 0; h < sampleCount; h++) {
-        parcel->writeInt64(mSampleEventTimes.itemAt(h));
-        for (size_t i = 0; i < pointerCount; i++) {
-            status_t status = (pc++)->writeToParcel(parcel);
-            if (status) {
-                return status;
-            }
-        }
-    }
-    return OK;
-}
-#endif
-
-bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
-    if (source & AINPUT_SOURCE_CLASS_POINTER) {
-        // Specifically excludes HOVER_MOVE and SCROLL.
-        switch (action & AMOTION_EVENT_ACTION_MASK) {
-        case AMOTION_EVENT_ACTION_DOWN:
-        case AMOTION_EVENT_ACTION_MOVE:
-        case AMOTION_EVENT_ACTION_UP:
-        case AMOTION_EVENT_ACTION_POINTER_DOWN:
-        case AMOTION_EVENT_ACTION_POINTER_UP:
-        case AMOTION_EVENT_ACTION_CANCEL:
-        case AMOTION_EVENT_ACTION_OUTSIDE:
-            return true;
-        }
-    }
-    return false;
-}
-
-
-// --- VelocityTracker ---
-
-const uint32_t VelocityTracker::DEFAULT_DEGREE;
-const nsecs_t VelocityTracker::DEFAULT_HORIZON;
-const uint32_t VelocityTracker::HISTORY_SIZE;
-
-static inline float vectorDot(const float* a, const float* b, uint32_t m) {
-    float r = 0;
-    while (m--) {
-        r += *(a++) * *(b++);
-    }
-    return r;
-}
-
-static inline float vectorNorm(const float* a, uint32_t m) {
-    float r = 0;
-    while (m--) {
-        float t = *(a++);
-        r += t * t;
-    }
-    return sqrtf(r);
-}
-
-#if DEBUG_LEAST_SQUARES || DEBUG_VELOCITY
-static String8 vectorToString(const float* a, uint32_t m) {
-    String8 str;
-    str.append("[");
-    while (m--) {
-        str.appendFormat(" %f", *(a++));
-        if (m) {
-            str.append(",");
-        }
-    }
-    str.append(" ]");
-    return str;
-}
-
-static String8 matrixToString(const float* a, uint32_t m, uint32_t n, bool rowMajor) {
-    String8 str;
-    str.append("[");
-    for (size_t i = 0; i < m; i++) {
-        if (i) {
-            str.append(",");
-        }
-        str.append(" [");
-        for (size_t j = 0; j < n; j++) {
-            if (j) {
-                str.append(",");
-            }
-            str.appendFormat(" %f", a[rowMajor ? i * n + j : j * m + i]);
-        }
-        str.append(" ]");
-    }
-    str.append(" ]");
-    return str;
-}
-#endif
-
-VelocityTracker::VelocityTracker() {
-    clear();
-}
-
-void VelocityTracker::clear() {
-    mIndex = 0;
-    mMovements[0].idBits.clear();
-    mActivePointerId = -1;
-}
-
-void VelocityTracker::clearPointers(BitSet32 idBits) {
-    BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
-    mMovements[mIndex].idBits = remainingIdBits;
-
-    if (mActivePointerId >= 0 && idBits.hasBit(mActivePointerId)) {
-        mActivePointerId = !remainingIdBits.isEmpty() ? remainingIdBits.firstMarkedBit() : -1;
-    }
-}
-
-void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions) {
-    if (++mIndex == HISTORY_SIZE) {
-        mIndex = 0;
-    }
-
-    while (idBits.count() > MAX_POINTERS) {
-        idBits.clearLastMarkedBit();
-    }
-
-    Movement& movement = mMovements[mIndex];
-    movement.eventTime = eventTime;
-    movement.idBits = idBits;
-    uint32_t count = idBits.count();
-    for (uint32_t i = 0; i < count; i++) {
-        movement.positions[i] = positions[i];
-    }
-
-    if (mActivePointerId < 0 || !idBits.hasBit(mActivePointerId)) {
-        mActivePointerId = count != 0 ? idBits.firstMarkedBit() : -1;
-    }
-
-#if DEBUG_VELOCITY
-    ALOGD("VelocityTracker: addMovement eventTime=%lld, idBits=0x%08x, activePointerId=%d",
-            eventTime, idBits.value, mActivePointerId);
-    for (BitSet32 iterBits(idBits); !iterBits.isEmpty(); ) {
-        uint32_t id = iterBits.firstMarkedBit();
-        uint32_t index = idBits.getIndexOfBit(id);
-        iterBits.clearBit(id);
-        Estimator estimator;
-        getEstimator(id, DEFAULT_DEGREE, DEFAULT_HORIZON, &estimator);
-        ALOGD("  %d: position (%0.3f, %0.3f), "
-                "estimator (degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f)",
-                id, positions[index].x, positions[index].y,
-                int(estimator.degree),
-                vectorToString(estimator.xCoeff, estimator.degree).string(),
-                vectorToString(estimator.yCoeff, estimator.degree).string(),
-                estimator.confidence);
-    }
-#endif
-}
-
-void VelocityTracker::addMovement(const MotionEvent* event) {
-    int32_t actionMasked = event->getActionMasked();
-
-    switch (actionMasked) {
-    case AMOTION_EVENT_ACTION_DOWN:
-    case AMOTION_EVENT_ACTION_HOVER_ENTER:
-        // Clear all pointers on down before adding the new movement.
-        clear();
-        break;
-    case AMOTION_EVENT_ACTION_POINTER_DOWN: {
-        // Start a new movement trace for a pointer that just went down.
-        // We do this on down instead of on up because the client may want to query the
-        // final velocity for a pointer that just went up.
-        BitSet32 downIdBits;
-        downIdBits.markBit(event->getPointerId(event->getActionIndex()));
-        clearPointers(downIdBits);
-        break;
-    }
-    case AMOTION_EVENT_ACTION_MOVE:
-    case AMOTION_EVENT_ACTION_HOVER_MOVE:
-        break;
-    default:
-        // Ignore all other actions because they do not convey any new information about
-        // pointer movement.  We also want to preserve the last known velocity of the pointers.
-        // Note that ACTION_UP and ACTION_POINTER_UP always report the last known position
-        // of the pointers that went up.  ACTION_POINTER_UP does include the new position of
-        // pointers that remained down but we will also receive an ACTION_MOVE with this
-        // information if any of them actually moved.  Since we don't know how many pointers
-        // will be going up at once it makes sense to just wait for the following ACTION_MOVE
-        // before adding the movement.
-        return;
-    }
-
-    size_t pointerCount = event->getPointerCount();
-    if (pointerCount > MAX_POINTERS) {
-        pointerCount = MAX_POINTERS;
-    }
-
-    BitSet32 idBits;
-    for (size_t i = 0; i < pointerCount; i++) {
-        idBits.markBit(event->getPointerId(i));
-    }
-
-    nsecs_t eventTime;
-    Position positions[pointerCount];
-
-    size_t historySize = event->getHistorySize();
-    for (size_t h = 0; h < historySize; h++) {
-        eventTime = event->getHistoricalEventTime(h);
-        for (size_t i = 0; i < pointerCount; i++) {
-            positions[i].x = event->getHistoricalX(i, h);
-            positions[i].y = event->getHistoricalY(i, h);
-        }
-        addMovement(eventTime, idBits, positions);
-    }
-
-    eventTime = event->getEventTime();
-    for (size_t i = 0; i < pointerCount; i++) {
-        positions[i].x = event->getX(i);
-        positions[i].y = event->getY(i);
-    }
-    addMovement(eventTime, idBits, positions);
-}
-
-/**
- * Solves a linear least squares problem to obtain a N degree polynomial that fits
- * the specified input data as nearly as possible.
- *
- * Returns true if a solution is found, false otherwise.
- *
- * The input consists of two vectors of data points X and Y with indices 0..m-1.
- * The output is a vector B with indices 0..n-1 that describes a polynomial
- * that fits the data, such the sum of abs(Y[i] - (B[0] + B[1] X[i] + B[2] X[i]^2 ... B[n] X[i]^n))
- * for all i between 0 and m-1 is minimized.
- *
- * That is to say, the function that generated the input data can be approximated
- * by y(x) ~= B[0] + B[1] x + B[2] x^2 + ... + B[n] x^n.
- *
- * The coefficient of determination (R^2) is also returned to describe the goodness
- * of fit of the model for the given data.  It is a value between 0 and 1, where 1
- * indicates perfect correspondence.
- *
- * This function first expands the X vector to a m by n matrix A such that
- * A[i][0] = 1, A[i][1] = X[i], A[i][2] = X[i]^2, ..., A[i][n] = X[i]^n.
- *
- * Then it calculates the QR decomposition of A yielding an m by m orthonormal matrix Q
- * and an m by n upper triangular matrix R.  Because R is upper triangular (lower
- * part is all zeroes), we can simplify the decomposition into an m by n matrix
- * Q1 and a n by n matrix R1 such that A = Q1 R1.
- *
- * Finally we solve the system of linear equations given by R1 B = (Qtranspose Y)
- * to find B.
- *
- * For efficiency, we lay out A and Q column-wise in memory because we frequently
- * operate on the column vectors.  Conversely, we lay out R row-wise.
- *
- * http://en.wikipedia.org/wiki/Numerical_methods_for_linear_least_squares
- * http://en.wikipedia.org/wiki/Gram-Schmidt
- */
-static bool solveLeastSquares(const float* x, const float* y, uint32_t m, uint32_t n,
-        float* outB, float* outDet) {
-#if DEBUG_LEAST_SQUARES
-    ALOGD("solveLeastSquares: m=%d, n=%d, x=%s, y=%s", int(m), int(n),
-            vectorToString(x, m).string(), vectorToString(y, m).string());
-#endif
-
-    // Expand the X vector to a matrix A.
-    float a[n][m]; // column-major order
-    for (uint32_t h = 0; h < m; h++) {
-        a[0][h] = 1;
-        for (uint32_t i = 1; i < n; i++) {
-            a[i][h] = a[i - 1][h] * x[h];
-        }
-    }
-#if DEBUG_LEAST_SQUARES
-    ALOGD("  - a=%s", matrixToString(&a[0][0], m, n, false /*rowMajor*/).string());
-#endif
-
-    // Apply the Gram-Schmidt process to A to obtain its QR decomposition.
-    float q[n][m]; // orthonormal basis, column-major order
-    float r[n][n]; // upper triangular matrix, row-major order
-    for (uint32_t j = 0; j < n; j++) {
-        for (uint32_t h = 0; h < m; h++) {
-            q[j][h] = a[j][h];
-        }
-        for (uint32_t i = 0; i < j; i++) {
-            float dot = vectorDot(&q[j][0], &q[i][0], m);
-            for (uint32_t h = 0; h < m; h++) {
-                q[j][h] -= dot * q[i][h];
-            }
-        }
-
-        float norm = vectorNorm(&q[j][0], m);
-        if (norm < 0.000001f) {
-            // vectors are linearly dependent or zero so no solution
-#if DEBUG_LEAST_SQUARES
-            ALOGD("  - no solution, norm=%f", norm);
-#endif
-            return false;
-        }
-
-        float invNorm = 1.0f / norm;
-        for (uint32_t h = 0; h < m; h++) {
-            q[j][h] *= invNorm;
-        }
-        for (uint32_t i = 0; i < n; i++) {
-            r[j][i] = i < j ? 0 : vectorDot(&q[j][0], &a[i][0], m);
-        }
-    }
-#if DEBUG_LEAST_SQUARES
-    ALOGD("  - q=%s", matrixToString(&q[0][0], m, n, false /*rowMajor*/).string());
-    ALOGD("  - r=%s", matrixToString(&r[0][0], n, n, true /*rowMajor*/).string());
-
-    // calculate QR, if we factored A correctly then QR should equal A
-    float qr[n][m];
-    for (uint32_t h = 0; h < m; h++) {
-        for (uint32_t i = 0; i < n; i++) {
-            qr[i][h] = 0;
-            for (uint32_t j = 0; j < n; j++) {
-                qr[i][h] += q[j][h] * r[j][i];
-            }
-        }
-    }
-    ALOGD("  - qr=%s", matrixToString(&qr[0][0], m, n, false /*rowMajor*/).string());
-#endif
-
-    // Solve R B = Qt Y to find B.  This is easy because R is upper triangular.
-    // We just work from bottom-right to top-left calculating B's coefficients.
-    for (uint32_t i = n; i-- != 0; ) {
-        outB[i] = vectorDot(&q[i][0], y, m);
-        for (uint32_t j = n - 1; j > i; j--) {
-            outB[i] -= r[i][j] * outB[j];
-        }
-        outB[i] /= r[i][i];
-    }
-#if DEBUG_LEAST_SQUARES
-    ALOGD("  - b=%s", vectorToString(outB, n).string());
-#endif
-
-    // Calculate the coefficient of determination as 1 - (SSerr / SStot) where
-    // SSerr is the residual sum of squares (squared variance of the error),
-    // and SStot is the total sum of squares (squared variance of the data).
-    float ymean = 0;
-    for (uint32_t h = 0; h < m; h++) {
-        ymean += y[h];
-    }
-    ymean /= m;
-
-    float sserr = 0;
-    float sstot = 0;
-    for (uint32_t h = 0; h < m; h++) {
-        float err = y[h] - outB[0];
-        float term = 1;
-        for (uint32_t i = 1; i < n; i++) {
-            term *= x[h];
-            err -= term * outB[i];
-        }
-        sserr += err * err;
-        float var = y[h] - ymean;
-        sstot += var * var;
-    }
-    *outDet = sstot > 0.000001f ? 1.0f - (sserr / sstot) : 1;
-#if DEBUG_LEAST_SQUARES
-    ALOGD("  - sserr=%f", sserr);
-    ALOGD("  - sstot=%f", sstot);
-    ALOGD("  - det=%f", *outDet);
-#endif
-    return true;
-}
-
-bool VelocityTracker::getVelocity(uint32_t id, float* outVx, float* outVy) const {
-    Estimator estimator;
-    if (getEstimator(id, DEFAULT_DEGREE, DEFAULT_HORIZON, &estimator)) {
-        if (estimator.degree >= 1) {
-            *outVx = estimator.xCoeff[1];
-            *outVy = estimator.yCoeff[1];
-            return true;
-        }
-    }
-    *outVx = 0;
-    *outVy = 0;
-    return false;
-}
-
-bool VelocityTracker::getEstimator(uint32_t id, uint32_t degree, nsecs_t horizon,
-        Estimator* outEstimator) const {
-    outEstimator->clear();
-
-    // Iterate over movement samples in reverse time order and collect samples.
-    float x[HISTORY_SIZE];
-    float y[HISTORY_SIZE];
-    float time[HISTORY_SIZE];
-    uint32_t m = 0;
-    uint32_t index = mIndex;
-    const Movement& newestMovement = mMovements[mIndex];
-    do {
-        const Movement& movement = mMovements[index];
-        if (!movement.idBits.hasBit(id)) {
-            break;
-        }
-
-        nsecs_t age = newestMovement.eventTime - movement.eventTime;
-        if (age > horizon) {
-            break;
-        }
-
-        const Position& position = movement.getPosition(id);
-        x[m] = position.x;
-        y[m] = position.y;
-        time[m] = -age * 0.000000001f;
-        index = (index == 0 ? HISTORY_SIZE : index) - 1;
-    } while (++m < HISTORY_SIZE);
-
-    if (m == 0) {
-        return false; // no data
-    }
-
-    // Calculate a least squares polynomial fit.
-    if (degree > Estimator::MAX_DEGREE) {
-        degree = Estimator::MAX_DEGREE;
-    }
-    if (degree > m - 1) {
-        degree = m - 1;
-    }
-    if (degree >= 1) {
-        float xdet, ydet;
-        uint32_t n = degree + 1;
-        if (solveLeastSquares(time, x, m, n, outEstimator->xCoeff, &xdet)
-                && solveLeastSquares(time, y, m, n, outEstimator->yCoeff, &ydet)) {
-            outEstimator->degree = degree;
-            outEstimator->confidence = xdet * ydet;
-#if DEBUG_LEAST_SQUARES
-            ALOGD("estimate: degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f",
-                    int(outEstimator->degree),
-                    vectorToString(outEstimator->xCoeff, n).string(),
-                    vectorToString(outEstimator->yCoeff, n).string(),
-                    outEstimator->confidence);
-#endif
-            return true;
-        }
-    }
-
-    // No velocity data available for this pointer, but we do have its current position.
-    outEstimator->xCoeff[0] = x[0];
-    outEstimator->yCoeff[0] = y[0];
-    outEstimator->degree = 0;
-    outEstimator->confidence = 1;
-    return true;
-}
-
-
-// --- VelocityControl ---
-
-const nsecs_t VelocityControl::STOP_TIME;
-
-VelocityControl::VelocityControl() {
-    reset();
-}
-
-void VelocityControl::setParameters(const VelocityControlParameters& parameters) {
-    mParameters = parameters;
-    reset();
-}
-
-void VelocityControl::reset() {
-    mLastMovementTime = LLONG_MIN;
-    mRawPosition.x = 0;
-    mRawPosition.y = 0;
-    mVelocityTracker.clear();
-}
-
-void VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) {
-    if ((deltaX && *deltaX) || (deltaY && *deltaY)) {
-        if (eventTime >= mLastMovementTime + STOP_TIME) {
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl: stopped, last movement was %0.3fms ago",
-                    (eventTime - mLastMovementTime) * 0.000001f);
-#endif
-            reset();
-        }
-
-        mLastMovementTime = eventTime;
-        if (deltaX) {
-            mRawPosition.x += *deltaX;
-        }
-        if (deltaY) {
-            mRawPosition.y += *deltaY;
-        }
-        mVelocityTracker.addMovement(eventTime, BitSet32(BitSet32::valueForBit(0)), &mRawPosition);
-
-        float vx, vy;
-        float scale = mParameters.scale;
-        if (mVelocityTracker.getVelocity(0, &vx, &vy)) {
-            float speed = hypotf(vx, vy) * scale;
-            if (speed >= mParameters.highThreshold) {
-                // Apply full acceleration above the high speed threshold.
-                scale *= mParameters.acceleration;
-            } else if (speed > mParameters.lowThreshold) {
-                // Linearly interpolate the acceleration to apply between the low and high
-                // speed thresholds.
-                scale *= 1 + (speed - mParameters.lowThreshold)
-                        / (mParameters.highThreshold - mParameters.lowThreshold)
-                        * (mParameters.acceleration - 1);
-            }
-
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): "
-                    "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f",
-                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
-                    mParameters.acceleration,
-                    vx, vy, speed, scale / mParameters.scale);
-#endif
-        } else {
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity",
-                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
-                    mParameters.acceleration);
-#endif
-        }
-
-        if (deltaX) {
-            *deltaX *= scale;
-        }
-        if (deltaY) {
-            *deltaY *= scale;
-        }
-    }
-}
-
-
-// --- InputDeviceInfo ---
-
-InputDeviceInfo::InputDeviceInfo() {
-    initialize(-1, String8("uninitialized device info"));
-}
-
-InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) :
-        mId(other.mId), mName(other.mName), mSources(other.mSources),
-        mKeyboardType(other.mKeyboardType),
-        mMotionRanges(other.mMotionRanges) {
-}
-
-InputDeviceInfo::~InputDeviceInfo() {
-}
-
-void InputDeviceInfo::initialize(int32_t id, const String8& name) {
-    mId = id;
-    mName = name;
-    mSources = 0;
-    mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
-    mMotionRanges.clear();
-}
-
-const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(
-        int32_t axis, uint32_t source) const {
-    size_t numRanges = mMotionRanges.size();
-    for (size_t i = 0; i < numRanges; i++) {
-        const MotionRange& range = mMotionRanges.itemAt(i);
-        if (range.axis == axis && range.source == source) {
-            return &range;
-        }
-    }
-    return NULL;
-}
-
-void InputDeviceInfo::addSource(uint32_t source) {
-    mSources |= source;
-}
-
-void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max,
-        float flat, float fuzz) {
-    MotionRange range = { axis, source, min, max, flat, fuzz };
-    mMotionRanges.add(range);
-}
-
-void InputDeviceInfo::addMotionRange(const MotionRange& range) {
-    mMotionRanges.add(range);
-}
-
-} // namespace android
diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp
deleted file mode 100644
index 1ebd75c..0000000
--- a/libs/ui/InputTransport.cpp
+++ /dev/null
@@ -1,611 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-// Provides a shared memory transport for input events.
-//
-#define LOG_TAG "InputTransport"
-
-//#define LOG_NDEBUG 0
-
-// Log debug messages about channel messages (send message, receive message)
-#define DEBUG_CHANNEL_MESSAGES 0
-
-// Log debug messages whenever InputChannel objects are created/destroyed
-#define DEBUG_CHANNEL_LIFECYCLE 0
-
-// Log debug messages about transport actions
-#define DEBUG_TRANSPORT_ACTIONS 0
-
-
-#include <cutils/log.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <androidfw/InputTransport.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-
-namespace android {
-
-// Socket buffer size.  The default is typically about 128KB, which is much larger than
-// we really need.  So we make it smaller.  It just needs to be big enough to hold
-// a few dozen large multi-finger motion events in the case where an application gets
-// behind processing touches.
-static const size_t SOCKET_BUFFER_SIZE = 32 * 1024;
-
-
-// --- InputMessage ---
-
-bool InputMessage::isValid(size_t actualSize) const {
-    if (size() == actualSize) {
-        switch (header.type) {
-        case TYPE_KEY:
-            return true;
-        case TYPE_MOTION:
-            return body.motion.pointerCount > 0
-                    && body.motion.pointerCount <= MAX_POINTERS;
-        case TYPE_FINISHED:
-            return true;
-        }
-    }
-    return false;
-}
-
-size_t InputMessage::size() const {
-    switch (header.type) {
-    case TYPE_KEY:
-        return sizeof(Header) + body.key.size();
-    case TYPE_MOTION:
-        return sizeof(Header) + body.motion.size();
-    case TYPE_FINISHED:
-        return sizeof(Header) + body.finished.size();
-    }
-    return sizeof(Header);
-}
-
-
-// --- InputChannel ---
-
-InputChannel::InputChannel(const String8& name, int fd) :
-        mName(name), mFd(fd) {
-#if DEBUG_CHANNEL_LIFECYCLE
-    ALOGD("Input channel constructed: name='%s', fd=%d",
-            mName.string(), fd);
-#endif
-
-    int result = fcntl(mFd, F_SETFL, O_NONBLOCK);
-    LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket "
-            "non-blocking.  errno=%d", mName.string(), errno);
-}
-
-InputChannel::~InputChannel() {
-#if DEBUG_CHANNEL_LIFECYCLE
-    ALOGD("Input channel destroyed: name='%s', fd=%d",
-            mName.string(), mFd);
-#endif
-
-    ::close(mFd);
-}
-
-status_t InputChannel::openInputChannelPair(const String8& name,
-        sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
-    int sockets[2];
-    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
-        status_t result = -errno;
-        ALOGE("channel '%s' ~ Could not create socket pair.  errno=%d",
-                name.string(), errno);
-        outServerChannel.clear();
-        outClientChannel.clear();
-        return result;
-    }
-
-    int bufferSize = SOCKET_BUFFER_SIZE;
-    setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
-    setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
-    setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
-    setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
-
-    String8 serverChannelName = name;
-    serverChannelName.append(" (server)");
-    outServerChannel = new InputChannel(serverChannelName, sockets[0]);
-
-    String8 clientChannelName = name;
-    clientChannelName.append(" (client)");
-    outClientChannel = new InputChannel(clientChannelName, sockets[1]);
-    return OK;
-}
-
-status_t InputChannel::sendMessage(const InputMessage* msg) {
-    size_t msgLength = msg->size();
-    ssize_t nWrite;
-    do {
-        nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
-    } while (nWrite == -1 && errno == EINTR);
-
-    if (nWrite < 0) {
-        int error = errno;
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.string(),
-                msg->header.type, error);
-#endif
-        if (error == EAGAIN || error == EWOULDBLOCK) {
-            return WOULD_BLOCK;
-        }
-        if (error == EPIPE || error == ENOTCONN) {
-            return DEAD_OBJECT;
-        }
-        return -error;
-    }
-
-    if (size_t(nWrite) != msgLength) {
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ error sending message type %d, send was incomplete",
-                mName.string(), msg->header.type);
-#endif
-        return DEAD_OBJECT;
-    }
-
-#if DEBUG_CHANNEL_MESSAGES
-    ALOGD("channel '%s' ~ sent message of type %d", mName.string(), msg->header.type);
-#endif
-    return OK;
-}
-
-status_t InputChannel::receiveMessage(InputMessage* msg) {
-    ssize_t nRead;
-    do {
-        nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
-    } while (nRead == -1 && errno == EINTR);
-
-    if (nRead < 0) {
-        int error = errno;
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.string(), errno);
-#endif
-        if (error == EAGAIN || error == EWOULDBLOCK) {
-            return WOULD_BLOCK;
-        }
-        if (error == EPIPE || error == ENOTCONN) {
-            return DEAD_OBJECT;
-        }
-        return -error;
-    }
-
-    if (nRead == 0) { // check for EOF
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.string());
-#endif
-        return DEAD_OBJECT;
-    }
-
-    if (!msg->isValid(nRead)) {
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ received invalid message", mName.string());
-#endif
-        return BAD_VALUE;
-    }
-
-#if DEBUG_CHANNEL_MESSAGES
-    ALOGD("channel '%s' ~ received message of type %d", mName.string(), msg->header.type);
-#endif
-    return OK;
-}
-
-
-// --- InputPublisher ---
-
-InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
-        mChannel(channel) {
-}
-
-InputPublisher::~InputPublisher() {
-}
-
-status_t InputPublisher::publishKeyEvent(
-        uint32_t seq,
-        int32_t deviceId,
-        int32_t source,
-        int32_t action,
-        int32_t flags,
-        int32_t keyCode,
-        int32_t scanCode,
-        int32_t metaState,
-        int32_t repeatCount,
-        nsecs_t downTime,
-        nsecs_t eventTime) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
-            "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
-            "downTime=%lld, eventTime=%lld",
-            mChannel->getName().string(), seq,
-            deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
-            downTime, eventTime);
-#endif
-
-    if (!seq) {
-        ALOGE("Attempted to publish a key event with sequence number 0.");
-        return BAD_VALUE;
-    }
-
-    InputMessage msg;
-    msg.header.type = InputMessage::TYPE_KEY;
-    msg.body.key.seq = seq;
-    msg.body.key.deviceId = deviceId;
-    msg.body.key.source = source;
-    msg.body.key.action = action;
-    msg.body.key.flags = flags;
-    msg.body.key.keyCode = keyCode;
-    msg.body.key.scanCode = scanCode;
-    msg.body.key.metaState = metaState;
-    msg.body.key.repeatCount = repeatCount;
-    msg.body.key.downTime = downTime;
-    msg.body.key.eventTime = eventTime;
-    return mChannel->sendMessage(&msg);
-}
-
-status_t InputPublisher::publishMotionEvent(
-        uint32_t seq,
-        int32_t deviceId,
-        int32_t source,
-        int32_t action,
-        int32_t flags,
-        int32_t edgeFlags,
-        int32_t metaState,
-        int32_t buttonState,
-        float xOffset,
-        float yOffset,
-        float xPrecision,
-        float yPrecision,
-        nsecs_t downTime,
-        nsecs_t eventTime,
-        size_t pointerCount,
-        const PointerProperties* pointerProperties,
-        const PointerCoords* pointerCoords) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
-            "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, "
-            "xOffset=%f, yOffset=%f, "
-            "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
-            "pointerCount=%d",
-            mChannel->getName().string(), seq,
-            deviceId, source, action, flags, edgeFlags, metaState, buttonState,
-            xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
-#endif
-
-    if (!seq) {
-        ALOGE("Attempted to publish a motion event with sequence number 0.");
-        return BAD_VALUE;
-    }
-
-    if (pointerCount > MAX_POINTERS || pointerCount < 1) {
-        ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.",
-                mChannel->getName().string(), pointerCount);
-        return BAD_VALUE;
-    }
-
-    InputMessage msg;
-    msg.header.type = InputMessage::TYPE_MOTION;
-    msg.body.motion.seq = seq;
-    msg.body.motion.deviceId = deviceId;
-    msg.body.motion.source = source;
-    msg.body.motion.action = action;
-    msg.body.motion.flags = flags;
-    msg.body.motion.edgeFlags = edgeFlags;
-    msg.body.motion.metaState = metaState;
-    msg.body.motion.buttonState = buttonState;
-    msg.body.motion.xOffset = xOffset;
-    msg.body.motion.yOffset = yOffset;
-    msg.body.motion.xPrecision = xPrecision;
-    msg.body.motion.yPrecision = yPrecision;
-    msg.body.motion.downTime = downTime;
-    msg.body.motion.eventTime = eventTime;
-    msg.body.motion.pointerCount = pointerCount;
-    for (size_t i = 0; i < pointerCount; i++) {
-        msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
-        msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
-    }
-    return mChannel->sendMessage(&msg);
-}
-
-status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
-            mChannel->getName().string());
-#endif
-
-    InputMessage msg;
-    status_t result = mChannel->receiveMessage(&msg);
-    if (result) {
-        *outSeq = 0;
-        *outHandled = false;
-        return result;
-    }
-    if (msg.header.type != InputMessage::TYPE_FINISHED) {
-        ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
-                mChannel->getName().string(), msg.header.type);
-        return UNKNOWN_ERROR;
-    }
-    *outSeq = msg.body.finished.seq;
-    *outHandled = msg.body.finished.handled;
-    return OK;
-}
-
-// --- InputConsumer ---
-
-InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
-        mChannel(channel), mMsgDeferred(false) {
-}
-
-InputConsumer::~InputConsumer() {
-}
-
-status_t InputConsumer::consume(InputEventFactoryInterface* factory,
-        bool consumeBatches, uint32_t* outSeq, InputEvent** outEvent) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s",
-            mChannel->getName().string(), consumeBatches ? "true" : "false");
-#endif
-
-    *outSeq = 0;
-    *outEvent = NULL;
-
-    // Fetch the next input message.
-    // Loop until an event can be returned or no additional events are received.
-    while (!*outEvent) {
-        if (mMsgDeferred) {
-            // mMsg contains a valid input message from the previous call to consume
-            // that has not yet been processed.
-            mMsgDeferred = false;
-        } else {
-            // Receive a fresh message.
-            status_t result = mChannel->receiveMessage(&mMsg);
-            if (result) {
-                // Consume the next batched event unless batches are being held for later.
-                if (!mBatches.isEmpty() && (consumeBatches || result != WOULD_BLOCK)) {
-                    MotionEvent* motionEvent = factory->createMotionEvent();
-                    if (! motionEvent) return NO_MEMORY;
-
-                    const Batch& batch = mBatches.top();
-                    motionEvent->copyFrom(&batch.event, true /*keepHistory*/);
-                    *outSeq = batch.seq;
-                    *outEvent = motionEvent;
-                    mBatches.pop();
-#if DEBUG_TRANSPORT_ACTIONS
-                    ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
-                            mChannel->getName().string(), *outSeq);
-#endif
-                    break;
-                }
-                return result;
-            }
-        }
-
-        switch (mMsg.header.type) {
-        case InputMessage::TYPE_KEY: {
-            KeyEvent* keyEvent = factory->createKeyEvent();
-            if (!keyEvent) return NO_MEMORY;
-
-            initializeKeyEvent(keyEvent, &mMsg);
-            *outSeq = mMsg.body.key.seq;
-            *outEvent = keyEvent;
-#if DEBUG_TRANSPORT_ACTIONS
-            ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
-                    mChannel->getName().string(), *outSeq);
-#endif
-            break;
-        }
-
-        case AINPUT_EVENT_TYPE_MOTION: {
-            ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
-            if (batchIndex >= 0) {
-                Batch& batch = mBatches.editItemAt(batchIndex);
-                if (canAppendSamples(&batch.event, &mMsg)) {
-                    // Append to the batch and save the new sequence number for the tail end.
-                    uint32_t chain = batch.seq;
-                    appendSamples(&batch.event, &mMsg);
-                    batch.seq = mMsg.body.motion.seq;
-
-                    // Update the sequence number chain.
-                    SeqChain seqChain;
-                    seqChain.seq = batch.seq;
-                    seqChain.chain = chain;
-                    mSeqChains.push(seqChain);
-#if DEBUG_TRANSPORT_ACTIONS
-                    ALOGD("channel '%s' consumer ~ appended to batch event",
-                            mChannel->getName().string());
-#endif
-                    break;
-                } else {
-                    MotionEvent* motionEvent = factory->createMotionEvent();
-                    if (! motionEvent) return NO_MEMORY;
-
-                    // We cannot append to the batch in progress, so we need to consume
-                    // the previous batch right now and defer the new message until later.
-                    mMsgDeferred = true;
-
-                    // Return the end of the previous batch.
-                    motionEvent->copyFrom(&batch.event, true /*keepHistory*/);
-                    *outSeq = batch.seq;
-                    *outEvent = motionEvent;
-                    mBatches.removeAt(batchIndex);
-#if DEBUG_TRANSPORT_ACTIONS
-                    ALOGD("channel '%s' consumer ~ consumed batch event and "
-                            "deferred current event, seq=%u",
-                            mChannel->getName().string(), *outSeq);
-#endif
-                    break;
-                }
-            }
-
-            // Start a new batch if needed.
-            if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
-                    || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
-                mBatches.push();
-                Batch& batch = mBatches.editTop();
-                batch.seq = mMsg.body.motion.seq;
-                initializeMotionEvent(&batch.event, &mMsg);
-#if DEBUG_TRANSPORT_ACTIONS
-                ALOGD("channel '%s' consumer ~ started batch event",
-                        mChannel->getName().string());
-#endif
-                break;
-            }
-
-            MotionEvent* motionEvent = factory->createMotionEvent();
-            if (! motionEvent) return NO_MEMORY;
-
-            initializeMotionEvent(motionEvent, &mMsg);
-            *outSeq = mMsg.body.motion.seq;
-            *outEvent = motionEvent;
-#if DEBUG_TRANSPORT_ACTIONS
-            ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
-                    mChannel->getName().string(), *outSeq);
-#endif
-            break;
-        }
-
-        default:
-            ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
-                    mChannel->getName().string(), mMsg.header.type);
-            return UNKNOWN_ERROR;
-        }
-    }
-    return OK;
-}
-
-status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
-            mChannel->getName().string(), seq, handled ? "true" : "false");
-#endif
-
-    if (!seq) {
-        ALOGE("Attempted to send a finished signal with sequence number 0.");
-        return BAD_VALUE;
-    }
-
-    // Send finished signals for the batch sequence chain first.
-    size_t seqChainCount = mSeqChains.size();
-    if (seqChainCount) {
-        uint32_t currentSeq = seq;
-        uint32_t chainSeqs[seqChainCount];
-        size_t chainIndex = 0;
-        for (size_t i = seqChainCount; i-- > 0; ) {
-             const SeqChain& seqChain = mSeqChains.itemAt(i);
-             if (seqChain.seq == currentSeq) {
-                 currentSeq = seqChain.chain;
-                 chainSeqs[chainIndex++] = currentSeq;
-                 mSeqChains.removeAt(i);
-             }
-        }
-        status_t status = OK;
-        while (!status && chainIndex-- > 0) {
-            status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
-        }
-        if (status) {
-            // An error occurred so at least one signal was not sent, reconstruct the chain.
-            do {
-                SeqChain seqChain;
-                seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
-                seqChain.chain = chainSeqs[chainIndex];
-                mSeqChains.push(seqChain);
-            } while (chainIndex-- > 0);
-            return status;
-        }
-    }
-
-    // Send finished signal for the last message in the batch.
-    return sendUnchainedFinishedSignal(seq, handled);
-}
-
-status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
-    InputMessage msg;
-    msg.header.type = InputMessage::TYPE_FINISHED;
-    msg.body.finished.seq = seq;
-    msg.body.finished.handled = handled;
-    return mChannel->sendMessage(&msg);
-}
-
-bool InputConsumer::hasPendingBatch() const {
-    return !mBatches.isEmpty();
-}
-
-ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
-    for (size_t i = 0; i < mBatches.size(); i++) {
-        const Batch& batch = mBatches.itemAt(i);
-        if (batch.event.getDeviceId() == deviceId && batch.event.getSource() == source) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
-    event->initialize(
-            msg->body.key.deviceId,
-            msg->body.key.source,
-            msg->body.key.action,
-            msg->body.key.flags,
-            msg->body.key.keyCode,
-            msg->body.key.scanCode,
-            msg->body.key.metaState,
-            msg->body.key.repeatCount,
-            msg->body.key.downTime,
-            msg->body.key.eventTime);
-}
-
-void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
-    size_t pointerCount = msg->body.motion.pointerCount;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
-        pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
-    }
-
-    event->initialize(
-            msg->body.motion.deviceId,
-            msg->body.motion.source,
-            msg->body.motion.action,
-            msg->body.motion.flags,
-            msg->body.motion.edgeFlags,
-            msg->body.motion.metaState,
-            msg->body.motion.buttonState,
-            msg->body.motion.xOffset,
-            msg->body.motion.yOffset,
-            msg->body.motion.xPrecision,
-            msg->body.motion.yPrecision,
-            msg->body.motion.downTime,
-            msg->body.motion.eventTime,
-            pointerCount,
-            pointerProperties,
-            pointerCoords);
-}
-
-bool InputConsumer::canAppendSamples(const MotionEvent* event, const InputMessage *msg) {
-    size_t pointerCount = msg->body.motion.pointerCount;
-    if (event->getPointerCount() != pointerCount
-            || event->getAction() != msg->body.motion.action) {
-        return false;
-    }
-    for (size_t i = 0; i < pointerCount; i++) {
-        if (*event->getPointerProperties(i) != msg->body.motion.pointers[i].properties) {
-            return false;
-        }
-    }
-    return true;
-}
-
-void InputConsumer::appendSamples(MotionEvent* event, const InputMessage* msg) {
-    size_t pointerCount = msg->body.motion.pointerCount;
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
-    }
-
-    event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
-    event->addSample(msg->body.motion.eventTime, pointerCoords);
-}
-
-} // namespace android
diff --git a/libs/ui/KeyCharacterMap.cpp b/libs/ui/KeyCharacterMap.cpp
deleted file mode 100644
index 6984084..0000000
--- a/libs/ui/KeyCharacterMap.cpp
+++ /dev/null
@@ -1,838 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "KeyCharacterMap"
-
-#include <stdlib.h>
-#include <string.h>
-#include <android/keycodes.h>
-#include <androidfw/Keyboard.h>
-#include <androidfw/KeyCharacterMap.h>
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/Tokenizer.h>
-#include <utils/Timers.h>
-
-// Enables debug output for the parser.
-#define DEBUG_PARSER 0
-
-// Enables debug output for parser performance.
-#define DEBUG_PARSER_PERFORMANCE 0
-
-// Enables debug output for mapping.
-#define DEBUG_MAPPING 0
-
-
-namespace android {
-
-static const char* WHITESPACE = " \t\r";
-static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r,:";
-
-struct Modifier {
-    const char* label;
-    int32_t metaState;
-};
-static const Modifier modifiers[] = {
-        { "shift", AMETA_SHIFT_ON },
-        { "lshift", AMETA_SHIFT_LEFT_ON },
-        { "rshift", AMETA_SHIFT_RIGHT_ON },
-        { "alt", AMETA_ALT_ON },
-        { "lalt", AMETA_ALT_LEFT_ON },
-        { "ralt", AMETA_ALT_RIGHT_ON },
-        { "ctrl", AMETA_CTRL_ON },
-        { "lctrl", AMETA_CTRL_LEFT_ON },
-        { "rctrl", AMETA_CTRL_RIGHT_ON },
-        { "meta", AMETA_META_ON },
-        { "lmeta", AMETA_META_LEFT_ON },
-        { "rmeta", AMETA_META_RIGHT_ON },
-        { "sym", AMETA_SYM_ON },
-        { "fn", AMETA_FUNCTION_ON },
-        { "capslock", AMETA_CAPS_LOCK_ON },
-        { "numlock", AMETA_NUM_LOCK_ON },
-        { "scrolllock", AMETA_SCROLL_LOCK_ON },
-};
-
-#if DEBUG_MAPPING
-static String8 toString(const char16_t* chars, size_t numChars) {
-    String8 result;
-    for (size_t i = 0; i < numChars; i++) {
-        result.appendFormat(i == 0 ? "%d" : ", %d", chars[i]);
-    }
-    return result;
-}
-#endif
-
-
-// --- KeyCharacterMap ---
-
-KeyCharacterMap::KeyCharacterMap() :
-    mType(KEYBOARD_TYPE_UNKNOWN) {
-}
-
-KeyCharacterMap::~KeyCharacterMap() {
-    for (size_t i = 0; i < mKeys.size(); i++) {
-        Key* key = mKeys.editValueAt(i);
-        delete key;
-    }
-}
-
-status_t KeyCharacterMap::load(const String8& filename, KeyCharacterMap** outMap) {
-    *outMap = NULL;
-
-    Tokenizer* tokenizer;
-    status_t status = Tokenizer::open(filename, &tokenizer);
-    if (status) {
-        ALOGE("Error %d opening key character map file %s.", status, filename.string());
-    } else {
-        KeyCharacterMap* map = new KeyCharacterMap();
-        if (!map) {
-            ALOGE("Error allocating key character map.");
-            status = NO_MEMORY;
-        } else {
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
-            Parser parser(map, tokenizer);
-            status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
-            ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
-                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),
-                    elapsedTime / 1000000.0);
-#endif
-            if (status) {
-                delete map;
-            } else {
-                *outMap = map;
-            }
-        }
-        delete tokenizer;
-    }
-    return status;
-}
-
-int32_t KeyCharacterMap::getKeyboardType() const {
-    return mType;
-}
-
-char16_t KeyCharacterMap::getDisplayLabel(int32_t keyCode) const {
-    char16_t result = 0;
-    const Key* key;
-    if (getKey(keyCode, &key)) {
-        result = key->label;
-    }
-#if DEBUG_MAPPING
-    ALOGD("getDisplayLabel: keyCode=%d ~ Result %d.", keyCode, result);
-#endif
-    return result;
-}
-
-char16_t KeyCharacterMap::getNumber(int32_t keyCode) const {
-    char16_t result = 0;
-    const Key* key;
-    if (getKey(keyCode, &key)) {
-        result = key->number;
-    }
-#if DEBUG_MAPPING
-    ALOGD("getNumber: keyCode=%d ~ Result %d.", keyCode, result);
-#endif
-    return result;
-}
-
-char16_t KeyCharacterMap::getCharacter(int32_t keyCode, int32_t metaState) const {
-    char16_t result = 0;
-    const Key* key;
-    const Behavior* behavior;
-    if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
-        result = behavior->character;
-    }
-#if DEBUG_MAPPING
-    ALOGD("getCharacter: keyCode=%d, metaState=0x%08x ~ Result %d.", keyCode, metaState, result);
-#endif
-    return result;
-}
-
-bool KeyCharacterMap::getFallbackAction(int32_t keyCode, int32_t metaState,
-        FallbackAction* outFallbackAction) const {
-    outFallbackAction->keyCode = 0;
-    outFallbackAction->metaState = 0;
-
-    bool result = false;
-    const Key* key;
-    const Behavior* behavior;
-    if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
-        if (behavior->fallbackKeyCode) {
-            outFallbackAction->keyCode = behavior->fallbackKeyCode;
-            outFallbackAction->metaState = metaState & ~behavior->metaState;
-            result = true;
-        }
-    }
-#if DEBUG_MAPPING
-    ALOGD("getFallbackKeyCode: keyCode=%d, metaState=0x%08x ~ Result %s, "
-            "fallback keyCode=%d, fallback metaState=0x%08x.",
-            keyCode, metaState, result ? "true" : "false",
-            outFallbackAction->keyCode, outFallbackAction->metaState);
-#endif
-    return result;
-}
-
-char16_t KeyCharacterMap::getMatch(int32_t keyCode, const char16_t* chars, size_t numChars,
-        int32_t metaState) const {
-    char16_t result = 0;
-    const Key* key;
-    if (getKey(keyCode, &key)) {
-        // Try to find the most general behavior that maps to this character.
-        // For example, the base key behavior will usually be last in the list.
-        // However, if we find a perfect meta state match for one behavior then use that one.
-        for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
-            if (behavior->character) {
-                for (size_t i = 0; i < numChars; i++) {
-                    if (behavior->character == chars[i]) {
-                        result = behavior->character;
-                        if ((behavior->metaState & metaState) == behavior->metaState) {
-                            goto ExactMatch;
-                        }
-                        break;
-                    }
-                }
-            }
-        }
-    ExactMatch: ;
-    }
-#if DEBUG_MAPPING
-    ALOGD("getMatch: keyCode=%d, chars=[%s], metaState=0x%08x ~ Result %d.",
-            keyCode, toString(chars, numChars).string(), metaState, result);
-#endif
-    return result;
-}
-
-bool KeyCharacterMap::getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
-        Vector<KeyEvent>& outEvents) const {
-    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-
-    for (size_t i = 0; i < numChars; i++) {
-        int32_t keyCode, metaState;
-        char16_t ch = chars[i];
-        if (!findKey(ch, &keyCode, &metaState)) {
-#if DEBUG_MAPPING
-            ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Failed to find mapping for character %d.",
-                    deviceId, toString(chars, numChars).string(), ch);
-#endif
-            return false;
-        }
-
-        int32_t currentMetaState = 0;
-        addMetaKeys(outEvents, deviceId, metaState, true, now, &currentMetaState);
-        addKey(outEvents, deviceId, keyCode, currentMetaState, true, now);
-        addKey(outEvents, deviceId, keyCode, currentMetaState, false, now);
-        addMetaKeys(outEvents, deviceId, metaState, false, now, &currentMetaState);
-    }
-#if DEBUG_MAPPING
-    ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Generated %d events.",
-            deviceId, toString(chars, numChars).string(), int32_t(outEvents.size()));
-    for (size_t i = 0; i < outEvents.size(); i++) {
-        ALOGD("  Key: keyCode=%d, metaState=0x%08x, %s.",
-                outEvents[i].getKeyCode(), outEvents[i].getMetaState(),
-                outEvents[i].getAction() == AKEY_EVENT_ACTION_DOWN ? "down" : "up");
-    }
-#endif
-    return true;
-}
-
-bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const {
-    ssize_t index = mKeys.indexOfKey(keyCode);
-    if (index >= 0) {
-        *outKey = mKeys.valueAt(index);
-        return true;
-    }
-    return false;
-}
-
-bool KeyCharacterMap::getKeyBehavior(int32_t keyCode, int32_t metaState,
-        const Key** outKey, const Behavior** outBehavior) const {
-    const Key* key;
-    if (getKey(keyCode, &key)) {
-        const Behavior* behavior = key->firstBehavior;
-        while (behavior) {
-            if ((behavior->metaState & metaState) == behavior->metaState) {
-                *outKey = key;
-                *outBehavior = behavior;
-                return true;
-            }
-            behavior = behavior->next;
-        }
-    }
-    return false;
-}
-
-bool KeyCharacterMap::findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const {
-    if (!ch) {
-        return false;
-    }
-
-    for (size_t i = 0; i < mKeys.size(); i++) {
-        const Key* key = mKeys.valueAt(i);
-
-        // Try to find the most general behavior that maps to this character.
-        // For example, the base key behavior will usually be last in the list.
-        const Behavior* found = NULL;
-        for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
-            if (behavior->character == ch) {
-                found = behavior;
-            }
-        }
-        if (found) {
-            *outKeyCode = mKeys.keyAt(i);
-            *outMetaState = found->metaState;
-            return true;
-        }
-    }
-    return false;
-}
-
-void KeyCharacterMap::addKey(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time) {
-    outEvents.push();
-    KeyEvent& event = outEvents.editTop();
-    event.initialize(deviceId, AINPUT_SOURCE_KEYBOARD,
-            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
-            0, keyCode, 0, metaState, 0, time, time);
-}
-
-void KeyCharacterMap::addMetaKeys(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-        int32_t* currentMetaState) {
-    // Add and remove meta keys symmetrically.
-    if (down) {
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
-
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
-                AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
-                AMETA_SHIFT_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
-                AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
-                AMETA_ALT_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
-                AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
-                AMETA_CTRL_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
-                AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
-                AMETA_META_ON, currentMetaState);
-
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
-    } else {
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
-
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
-                AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
-                AMETA_META_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
-                AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
-                AMETA_CTRL_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
-                AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
-                AMETA_ALT_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
-                AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
-                AMETA_SHIFT_ON, currentMetaState);
-
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
-    }
-}
-
-bool KeyCharacterMap::addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-        int32_t keyCode, int32_t keyMetaState,
-        int32_t* currentMetaState) {
-    if ((metaState & keyMetaState) == keyMetaState) {
-        *currentMetaState = updateMetaState(keyCode, down, *currentMetaState);
-        addKey(outEvents, deviceId, keyCode, *currentMetaState, down, time);
-        return true;
-    }
-    return false;
-}
-
-void KeyCharacterMap::addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-        int32_t leftKeyCode, int32_t leftKeyMetaState,
-        int32_t rightKeyCode, int32_t rightKeyMetaState,
-        int32_t eitherKeyMetaState,
-        int32_t* currentMetaState) {
-    bool specific = false;
-    specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
-            leftKeyCode, leftKeyMetaState, currentMetaState);
-    specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
-            rightKeyCode, rightKeyMetaState, currentMetaState);
-
-    if (!specific) {
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
-                leftKeyCode, eitherKeyMetaState, currentMetaState);
-    }
-}
-
-void KeyCharacterMap::addLockedMetaKey(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t metaState, nsecs_t time,
-        int32_t keyCode, int32_t keyMetaState,
-        int32_t* currentMetaState) {
-    if ((metaState & keyMetaState) == keyMetaState) {
-        *currentMetaState = updateMetaState(keyCode, true, *currentMetaState);
-        addKey(outEvents, deviceId, keyCode, *currentMetaState, true, time);
-        *currentMetaState = updateMetaState(keyCode, false, *currentMetaState);
-        addKey(outEvents, deviceId, keyCode, *currentMetaState, false, time);
-    }
-}
-
-
-// --- KeyCharacterMap::Key ---
-
-KeyCharacterMap::Key::Key() :
-        label(0), number(0), firstBehavior(NULL) {
-}
-
-KeyCharacterMap::Key::~Key() {
-    Behavior* behavior = firstBehavior;
-    while (behavior) {
-        Behavior* next = behavior->next;
-        delete behavior;
-        behavior = next;
-    }
-}
-
-
-// --- KeyCharacterMap::Behavior ---
-
-KeyCharacterMap::Behavior::Behavior() :
-        next(NULL), metaState(0), character(0), fallbackKeyCode(0) {
-}
-
-
-// --- KeyCharacterMap::Parser ---
-
-KeyCharacterMap::Parser::Parser(KeyCharacterMap* map, Tokenizer* tokenizer) :
-        mMap(map), mTokenizer(tokenizer), mState(STATE_TOP) {
-}
-
-KeyCharacterMap::Parser::~Parser() {
-}
-
-status_t KeyCharacterMap::Parser::parse() {
-    while (!mTokenizer->isEof()) {
-#if DEBUG_PARSER
-        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
-                mTokenizer->peekRemainderOfLine().string());
-#endif
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-
-        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
-            switch (mState) {
-            case STATE_TOP: {
-                String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
-                if (keywordToken == "type") {
-                    mTokenizer->skipDelimiters(WHITESPACE);
-                    status_t status = parseType();
-                    if (status) return status;
-                } else if (keywordToken == "key") {
-                    mTokenizer->skipDelimiters(WHITESPACE);
-                    status_t status = parseKey();
-                    if (status) return status;
-                } else {
-                    ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
-                            keywordToken.string());
-                    return BAD_VALUE;
-                }
-                break;
-            }
-
-            case STATE_KEY: {
-                status_t status = parseKeyProperty();
-                if (status) return status;
-                break;
-            }
-            }
-
-            mTokenizer->skipDelimiters(WHITESPACE);
-            if (!mTokenizer->isEol()) {
-                ALOGE("%s: Expected end of line, got '%s'.",
-                        mTokenizer->getLocation().string(),
-                        mTokenizer->peekRemainderOfLine().string());
-                return BAD_VALUE;
-            }
-        }
-
-        mTokenizer->nextLine();
-    }
-
-    if (mState != STATE_TOP) {
-        ALOGE("%s: Unterminated key description at end of file.",
-                mTokenizer->getLocation().string());
-        return BAD_VALUE;
-    }
-
-    if (mMap->mType == KEYBOARD_TYPE_UNKNOWN) {
-        ALOGE("%s: Missing required keyboard 'type' declaration.",
-                mTokenizer->getLocation().string());
-        return BAD_VALUE;
-    }
-
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseType() {
-    if (mMap->mType != KEYBOARD_TYPE_UNKNOWN) {
-        ALOGE("%s: Duplicate keyboard 'type' declaration.",
-                mTokenizer->getLocation().string());
-        return BAD_VALUE;
-    }
-
-    KeyboardType type;
-    String8 typeToken = mTokenizer->nextToken(WHITESPACE);
-    if (typeToken == "NUMERIC") {
-        type = KEYBOARD_TYPE_NUMERIC;
-    } else if (typeToken == "PREDICTIVE") {
-        type = KEYBOARD_TYPE_PREDICTIVE;
-    } else if (typeToken == "ALPHA") {
-        type = KEYBOARD_TYPE_ALPHA;
-    } else if (typeToken == "FULL") {
-        type = KEYBOARD_TYPE_FULL;
-    } else if (typeToken == "SPECIAL_FUNCTION") {
-        type = KEYBOARD_TYPE_SPECIAL_FUNCTION;
-    } else {
-        ALOGE("%s: Expected keyboard type label, got '%s'.", mTokenizer->getLocation().string(),
-                typeToken.string());
-        return BAD_VALUE;
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed type: type=%d.", type);
-#endif
-    mMap->mType = type;
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseKey() {
-    String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
-    int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
-    if (!keyCode) {
-        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
-        return BAD_VALUE;
-    }
-    if (mMap->mKeys.indexOfKey(keyCode) >= 0) {
-        ALOGE("%s: Duplicate entry for key code '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
-        return BAD_VALUE;
-    }
-
-    mTokenizer->skipDelimiters(WHITESPACE);
-    String8 openBraceToken = mTokenizer->nextToken(WHITESPACE);
-    if (openBraceToken != "{") {
-        ALOGE("%s: Expected '{' after key code label, got '%s'.",
-                mTokenizer->getLocation().string(), openBraceToken.string());
-        return BAD_VALUE;
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed beginning of key: keyCode=%d.", keyCode);
-#endif
-    mKeyCode = keyCode;
-    mMap->mKeys.add(keyCode, new Key());
-    mState = STATE_KEY;
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseKeyProperty() {
-    String8 token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
-    if (token == "}") {
-        mState = STATE_TOP;
-        return NO_ERROR;
-    }
-
-    Vector<Property> properties;
-
-    // Parse all comma-delimited property names up to the first colon.
-    for (;;) {
-        if (token == "label") {
-            properties.add(Property(PROPERTY_LABEL));
-        } else if (token == "number") {
-            properties.add(Property(PROPERTY_NUMBER));
-        } else {
-            int32_t metaState;
-            status_t status = parseModifier(token, &metaState);
-            if (status) {
-                ALOGE("%s: Expected a property name or modifier, got '%s'.",
-                        mTokenizer->getLocation().string(), token.string());
-                return status;
-            }
-            properties.add(Property(PROPERTY_META, metaState));
-        }
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        if (!mTokenizer->isEol()) {
-            char ch = mTokenizer->nextChar();
-            if (ch == ':') {
-                break;
-            } else if (ch == ',') {
-                mTokenizer->skipDelimiters(WHITESPACE);
-                token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
-                continue;
-            }
-        }
-
-        ALOGE("%s: Expected ',' or ':' after property name.",
-                mTokenizer->getLocation().string());
-        return BAD_VALUE;
-    }
-
-    // Parse behavior after the colon.
-    mTokenizer->skipDelimiters(WHITESPACE);
-
-    Behavior behavior;
-    bool haveCharacter = false;
-    bool haveFallback = false;
-
-    do {
-        char ch = mTokenizer->peekChar();
-        if (ch == '\'') {
-            char16_t character;
-            status_t status = parseCharacterLiteral(&character);
-            if (status || !character) {
-                ALOGE("%s: Invalid character literal for key.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-            if (haveCharacter) {
-                ALOGE("%s: Cannot combine multiple character literals or 'none'.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-            behavior.character = character;
-            haveCharacter = true;
-        } else {
-            token = mTokenizer->nextToken(WHITESPACE);
-            if (token == "none") {
-                if (haveCharacter) {
-                    ALOGE("%s: Cannot combine multiple character literals or 'none'.",
-                            mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-                haveCharacter = true;
-            } else if (token == "fallback") {
-                mTokenizer->skipDelimiters(WHITESPACE);
-                token = mTokenizer->nextToken(WHITESPACE);
-                int32_t keyCode = getKeyCodeByLabel(token.string());
-                if (!keyCode) {
-                    ALOGE("%s: Invalid key code label for fallback behavior, got '%s'.",
-                            mTokenizer->getLocation().string(),
-                            token.string());
-                    return BAD_VALUE;
-                }
-                if (haveFallback) {
-                    ALOGE("%s: Cannot combine multiple fallback key codes.",
-                            mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-                behavior.fallbackKeyCode = keyCode;
-                haveFallback = true;
-            } else {
-                ALOGE("%s: Expected a key behavior after ':'.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-        }
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-    } while (!mTokenizer->isEol());
-
-    // Add the behavior.
-    Key* key = mMap->mKeys.valueFor(mKeyCode);
-    for (size_t i = 0; i < properties.size(); i++) {
-        const Property& property = properties.itemAt(i);
-        switch (property.property) {
-        case PROPERTY_LABEL:
-            if (key->label) {
-                ALOGE("%s: Duplicate label for key.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-            key->label = behavior.character;
-#if DEBUG_PARSER
-            ALOGD("Parsed key label: keyCode=%d, label=%d.", mKeyCode, key->label);
-#endif
-            break;
-        case PROPERTY_NUMBER:
-            if (key->number) {
-                ALOGE("%s: Duplicate number for key.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-            key->number = behavior.character;
-#if DEBUG_PARSER
-            ALOGD("Parsed key number: keyCode=%d, number=%d.", mKeyCode, key->number);
-#endif
-            break;
-        case PROPERTY_META: {
-            for (Behavior* b = key->firstBehavior; b; b = b->next) {
-                if (b->metaState == property.metaState) {
-                    ALOGE("%s: Duplicate key behavior for modifier.",
-                            mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-            }
-            Behavior* newBehavior = new Behavior(behavior);
-            newBehavior->metaState = property.metaState;
-            newBehavior->next = key->firstBehavior;
-            key->firstBehavior = newBehavior;
-#if DEBUG_PARSER
-            ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d.", mKeyCode,
-                    newBehavior->metaState, newBehavior->character, newBehavior->fallbackKeyCode);
-#endif
-            break;
-        }
-        }
-    }
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseModifier(const String8& token, int32_t* outMetaState) {
-    if (token == "base") {
-        *outMetaState = 0;
-        return NO_ERROR;
-    }
-
-    int32_t combinedMeta = 0;
-
-    const char* str = token.string();
-    const char* start = str;
-    for (const char* cur = str; ; cur++) {
-        char ch = *cur;
-        if (ch == '+' || ch == '\0') {
-            size_t len = cur - start;
-            int32_t metaState = 0;
-            for (size_t i = 0; i < sizeof(modifiers) / sizeof(Modifier); i++) {
-                if (strlen(modifiers[i].label) == len
-                        && strncmp(modifiers[i].label, start, len) == 0) {
-                    metaState = modifiers[i].metaState;
-                    break;
-                }
-            }
-            if (!metaState) {
-                return BAD_VALUE;
-            }
-            if (combinedMeta & metaState) {
-                ALOGE("%s: Duplicate modifier combination '%s'.",
-                        mTokenizer->getLocation().string(), token.string());
-                return BAD_VALUE;
-            }
-
-            combinedMeta |= metaState;
-            start = cur + 1;
-
-            if (ch == '\0') {
-                break;
-            }
-        }
-    }
-    *outMetaState = combinedMeta;
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseCharacterLiteral(char16_t* outCharacter) {
-    char ch = mTokenizer->nextChar();
-    if (ch != '\'') {
-        goto Error;
-    }
-
-    ch = mTokenizer->nextChar();
-    if (ch == '\\') {
-        // Escape sequence.
-        ch = mTokenizer->nextChar();
-        if (ch == 'n') {
-            *outCharacter = '\n';
-        } else if (ch == 't') {
-            *outCharacter = '\t';
-        } else if (ch == '\\') {
-            *outCharacter = '\\';
-        } else if (ch == '\'') {
-            *outCharacter = '\'';
-        } else if (ch == '"') {
-            *outCharacter = '"';
-        } else if (ch == 'u') {
-            *outCharacter = 0;
-            for (int i = 0; i < 4; i++) {
-                ch = mTokenizer->nextChar();
-                int digit;
-                if (ch >= '0' && ch <= '9') {
-                    digit = ch - '0';
-                } else if (ch >= 'A' && ch <= 'F') {
-                    digit = ch - 'A' + 10;
-                } else if (ch >= 'a' && ch <= 'f') {
-                    digit = ch - 'a' + 10;
-                } else {
-                    goto Error;
-                }
-                *outCharacter = (*outCharacter << 4) | digit;
-            }
-        } else {
-            goto Error;
-        }
-    } else if (ch >= 32 && ch <= 126 && ch != '\'') {
-        // ASCII literal character.
-        *outCharacter = ch;
-    } else {
-        goto Error;
-    }
-
-    ch = mTokenizer->nextChar();
-    if (ch != '\'') {
-        goto Error;
-    }
-
-    // Ensure that we consumed the entire token.
-    if (mTokenizer->nextToken(WHITESPACE).isEmpty()) {
-        return NO_ERROR;
-    }
-
-Error:
-    ALOGE("%s: Malformed character literal.", mTokenizer->getLocation().string());
-    return BAD_VALUE;
-}
-
-} // namespace android
diff --git a/libs/ui/KeyLayoutMap.cpp b/libs/ui/KeyLayoutMap.cpp
deleted file mode 100644
index 15d81ee..0000000
--- a/libs/ui/KeyLayoutMap.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "KeyLayoutMap"
-
-#include <stdlib.h>
-#include <android/keycodes.h>
-#include <androidfw/Keyboard.h>
-#include <androidfw/KeyLayoutMap.h>
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/Tokenizer.h>
-#include <utils/Timers.h>
-
-// Enables debug output for the parser.
-#define DEBUG_PARSER 0
-
-// Enables debug output for parser performance.
-#define DEBUG_PARSER_PERFORMANCE 0
-
-// Enables debug output for mapping.
-#define DEBUG_MAPPING 0
-
-
-namespace android {
-
-static const char* WHITESPACE = " \t\r";
-
-// --- KeyLayoutMap ---
-
-KeyLayoutMap::KeyLayoutMap() {
-}
-
-KeyLayoutMap::~KeyLayoutMap() {
-}
-
-status_t KeyLayoutMap::load(const String8& filename, KeyLayoutMap** outMap) {
-    *outMap = NULL;
-
-    Tokenizer* tokenizer;
-    status_t status = Tokenizer::open(filename, &tokenizer);
-    if (status) {
-        ALOGE("Error %d opening key layout map file %s.", status, filename.string());
-    } else {
-        KeyLayoutMap* map = new KeyLayoutMap();
-        if (!map) {
-            ALOGE("Error allocating key layout map.");
-            status = NO_MEMORY;
-        } else {
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
-            Parser parser(map, tokenizer);
-            status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
-            ALOGD("Parsed key layout map file '%s' %d lines in %0.3fms.",
-                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),
-                    elapsedTime / 1000000.0);
-#endif
-            if (status) {
-                delete map;
-            } else {
-                *outMap = map;
-            }
-        }
-        delete tokenizer;
-    }
-    return status;
-}
-
-status_t KeyLayoutMap::mapKey(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const {
-    ssize_t index = mKeys.indexOfKey(scanCode);
-    if (index < 0) {
-#if DEBUG_MAPPING
-        ALOGD("mapKey: scanCode=%d ~ Failed.", scanCode);
-#endif
-        *keyCode = AKEYCODE_UNKNOWN;
-        *flags = 0;
-        return NAME_NOT_FOUND;
-    }
-
-    const Key& k = mKeys.valueAt(index);
-    *keyCode = k.keyCode;
-    *flags = k.flags;
-
-#if DEBUG_MAPPING
-    ALOGD("mapKey: scanCode=%d ~ Result keyCode=%d, flags=0x%08x.", scanCode, *keyCode, *flags);
-#endif
-    return NO_ERROR;
-}
-
-status_t KeyLayoutMap::findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const {
-    const size_t N = mKeys.size();
-    for (size_t i=0; i<N; i++) {
-        if (mKeys.valueAt(i).keyCode == keyCode) {
-            outScanCodes->add(mKeys.keyAt(i));
-        }
-    }
-    return NO_ERROR;
-}
-
-status_t KeyLayoutMap::mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const {
-    ssize_t index = mAxes.indexOfKey(scanCode);
-    if (index < 0) {
-#if DEBUG_MAPPING
-        ALOGD("mapAxis: scanCode=%d ~ Failed.", scanCode);
-#endif
-        return NAME_NOT_FOUND;
-    }
-
-    *outAxisInfo = mAxes.valueAt(index);
-
-#if DEBUG_MAPPING
-    ALOGD("mapAxis: scanCode=%d ~ Result mode=%d, axis=%d, highAxis=%d, "
-            "splitValue=%d, flatOverride=%d.",
-            scanCode,
-            outAxisInfo->mode, outAxisInfo->axis, outAxisInfo->highAxis,
-            outAxisInfo->splitValue, outAxisInfo->flatOverride);
-#endif
-    return NO_ERROR;
-}
-
-
-// --- KeyLayoutMap::Parser ---
-
-KeyLayoutMap::Parser::Parser(KeyLayoutMap* map, Tokenizer* tokenizer) :
-        mMap(map), mTokenizer(tokenizer) {
-}
-
-KeyLayoutMap::Parser::~Parser() {
-}
-
-status_t KeyLayoutMap::Parser::parse() {
-    while (!mTokenizer->isEof()) {
-#if DEBUG_PARSER
-        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
-                mTokenizer->peekRemainderOfLine().string());
-#endif
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-
-        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
-            String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
-            if (keywordToken == "key") {
-                mTokenizer->skipDelimiters(WHITESPACE);
-                status_t status = parseKey();
-                if (status) return status;
-            } else if (keywordToken == "axis") {
-                mTokenizer->skipDelimiters(WHITESPACE);
-                status_t status = parseAxis();
-                if (status) return status;
-            } else {
-                ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
-                        keywordToken.string());
-                return BAD_VALUE;
-            }
-
-            mTokenizer->skipDelimiters(WHITESPACE);
-            if (!mTokenizer->isEol()) {
-                ALOGE("%s: Expected end of line, got '%s'.",
-                        mTokenizer->getLocation().string(),
-                        mTokenizer->peekRemainderOfLine().string());
-                return BAD_VALUE;
-            }
-        }
-
-        mTokenizer->nextLine();
-    }
-    return NO_ERROR;
-}
-
-status_t KeyLayoutMap::Parser::parseKey() {
-    String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
-    char* end;
-    int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
-    if (*end) {
-        ALOGE("%s: Expected key scan code number, got '%s'.", mTokenizer->getLocation().string(),
-                scanCodeToken.string());
-        return BAD_VALUE;
-    }
-    if (mMap->mKeys.indexOfKey(scanCode) >= 0) {
-        ALOGE("%s: Duplicate entry for key scan code '%s'.", mTokenizer->getLocation().string(),
-                scanCodeToken.string());
-        return BAD_VALUE;
-    }
-
-    mTokenizer->skipDelimiters(WHITESPACE);
-    String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
-    int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
-    if (!keyCode) {
-        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
-        return BAD_VALUE;
-    }
-
-    uint32_t flags = 0;
-    for (;;) {
-        mTokenizer->skipDelimiters(WHITESPACE);
-        if (mTokenizer->isEol()) break;
-
-        String8 flagToken = mTokenizer->nextToken(WHITESPACE);
-        uint32_t flag = getKeyFlagByLabel(flagToken.string());
-        if (!flag) {
-            ALOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().string(),
-                    flagToken.string());
-            return BAD_VALUE;
-        }
-        if (flags & flag) {
-            ALOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().string(),
-                    flagToken.string());
-            return BAD_VALUE;
-        }
-        flags |= flag;
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed key: scanCode=%d, keyCode=%d, flags=0x%08x.", scanCode, keyCode, flags);
-#endif
-    Key key;
-    key.keyCode = keyCode;
-    key.flags = flags;
-    mMap->mKeys.add(scanCode, key);
-    return NO_ERROR;
-}
-
-status_t KeyLayoutMap::Parser::parseAxis() {
-    String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
-    char* end;
-    int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
-    if (*end) {
-        ALOGE("%s: Expected axis scan code number, got '%s'.", mTokenizer->getLocation().string(),
-                scanCodeToken.string());
-        return BAD_VALUE;
-    }
-    if (mMap->mAxes.indexOfKey(scanCode) >= 0) {
-        ALOGE("%s: Duplicate entry for axis scan code '%s'.", mTokenizer->getLocation().string(),
-                scanCodeToken.string());
-        return BAD_VALUE;
-    }
-
-    AxisInfo axisInfo;
-
-    mTokenizer->skipDelimiters(WHITESPACE);
-    String8 token = mTokenizer->nextToken(WHITESPACE);
-    if (token == "invert") {
-        axisInfo.mode = AxisInfo::MODE_INVERT;
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        String8 axisToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.axis = getAxisByLabel(axisToken.string());
-        if (axisInfo.axis < 0) {
-            ALOGE("%s: Expected inverted axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), axisToken.string());
-            return BAD_VALUE;
-        }
-    } else if (token == "split") {
-        axisInfo.mode = AxisInfo::MODE_SPLIT;
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        String8 splitToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.splitValue = int32_t(strtol(splitToken.string(), &end, 0));
-        if (*end) {
-            ALOGE("%s: Expected split value, got '%s'.",
-                    mTokenizer->getLocation().string(), splitToken.string());
-            return BAD_VALUE;
-        }
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        String8 lowAxisToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.axis = getAxisByLabel(lowAxisToken.string());
-        if (axisInfo.axis < 0) {
-            ALOGE("%s: Expected low axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), lowAxisToken.string());
-            return BAD_VALUE;
-        }
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        String8 highAxisToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.highAxis = getAxisByLabel(highAxisToken.string());
-        if (axisInfo.highAxis < 0) {
-            ALOGE("%s: Expected high axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), highAxisToken.string());
-            return BAD_VALUE;
-        }
-    } else {
-        axisInfo.axis = getAxisByLabel(token.string());
-        if (axisInfo.axis < 0) {
-            ALOGE("%s: Expected axis label, 'split' or 'invert', got '%s'.",
-                    mTokenizer->getLocation().string(), token.string());
-            return BAD_VALUE;
-        }
-    }
-
-    for (;;) {
-        mTokenizer->skipDelimiters(WHITESPACE);
-        if (mTokenizer->isEol()) {
-            break;
-        }
-        String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
-        if (keywordToken == "flat") {
-            mTokenizer->skipDelimiters(WHITESPACE);
-            String8 flatToken = mTokenizer->nextToken(WHITESPACE);
-            axisInfo.flatOverride = int32_t(strtol(flatToken.string(), &end, 0));
-            if (*end) {
-                ALOGE("%s: Expected flat value, got '%s'.",
-                        mTokenizer->getLocation().string(), flatToken.string());
-                return BAD_VALUE;
-            }
-        } else {
-            ALOGE("%s: Expected keyword 'flat', got '%s'.",
-                    mTokenizer->getLocation().string(), keywordToken.string());
-            return BAD_VALUE;
-        }
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed axis: scanCode=%d, mode=%d, axis=%d, highAxis=%d, "
-            "splitValue=%d, flatOverride=%d.",
-            scanCode,
-            axisInfo.mode, axisInfo.axis, axisInfo.highAxis,
-            axisInfo.splitValue, axisInfo.flatOverride);
-#endif
-    mMap->mAxes.add(scanCode, axisInfo);
-    return NO_ERROR;
-}
-
-};
diff --git a/libs/ui/Keyboard.cpp b/libs/ui/Keyboard.cpp
deleted file mode 100644
index e97a5eb..0000000
--- a/libs/ui/Keyboard.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (C) 2010 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 "Keyboard"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <limits.h>
-
-#include <androidfw/Keyboard.h>
-#include <androidfw/KeycodeLabels.h>
-#include <androidfw/KeyLayoutMap.h>
-#include <androidfw/KeyCharacterMap.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <cutils/properties.h>
-
-namespace android {
-
-// --- KeyMap ---
-
-KeyMap::KeyMap() :
-        keyLayoutMap(NULL), keyCharacterMap(NULL) {
-}
-
-KeyMap::~KeyMap() {
-    delete keyLayoutMap;
-    delete keyCharacterMap;
-}
-
-status_t KeyMap::load(const InputDeviceIdentifier& deviceIdenfifier,
-        const PropertyMap* deviceConfiguration) {
-    // Use the configured key layout if available.
-    if (deviceConfiguration) {
-        String8 keyLayoutName;
-        if (deviceConfiguration->tryGetProperty(String8("keyboard.layout"),
-                keyLayoutName)) {
-            status_t status = loadKeyLayout(deviceIdenfifier, keyLayoutName);
-            if (status == NAME_NOT_FOUND) {
-                ALOGE("Configuration for keyboard device '%s' requested keyboard layout '%s' but "
-                        "it was not found.",
-                        deviceIdenfifier.name.string(), keyLayoutName.string());
-            }
-        }
-
-        String8 keyCharacterMapName;
-        if (deviceConfiguration->tryGetProperty(String8("keyboard.characterMap"),
-                keyCharacterMapName)) {
-            status_t status = loadKeyCharacterMap(deviceIdenfifier, keyCharacterMapName);
-            if (status == NAME_NOT_FOUND) {
-                ALOGE("Configuration for keyboard device '%s' requested keyboard character "
-                        "map '%s' but it was not found.",
-                        deviceIdenfifier.name.string(), keyLayoutName.string());
-            }
-        }
-
-        if (isComplete()) {
-            return OK;
-        }
-    }
-
-    // Try searching by device identifier.
-    if (probeKeyMap(deviceIdenfifier, String8::empty())) {
-        return OK;
-    }
-
-    // Fall back on the Generic key map.
-    // TODO Apply some additional heuristics here to figure out what kind of
-    //      generic key map to use (US English, etc.) for typical external keyboards.
-    if (probeKeyMap(deviceIdenfifier, String8("Generic"))) {
-        return OK;
-    }
-
-    // Try the Virtual key map as a last resort.
-    if (probeKeyMap(deviceIdenfifier, String8("Virtual"))) {
-        return OK;
-    }
-
-    // Give up!
-    ALOGE("Could not determine key map for device '%s' and no default key maps were found!",
-            deviceIdenfifier.name.string());
-    return NAME_NOT_FOUND;
-}
-
-bool KeyMap::probeKeyMap(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& keyMapName) {
-    if (!haveKeyLayout()) {
-        loadKeyLayout(deviceIdentifier, keyMapName);
-    }
-    if (!haveKeyCharacterMap()) {
-        loadKeyCharacterMap(deviceIdentifier, keyMapName);
-    }
-    return isComplete();
-}
-
-status_t KeyMap::loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& name) {
-    String8 path(getPath(deviceIdentifier, name,
-            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT));
-    if (path.isEmpty()) {
-        return NAME_NOT_FOUND;
-    }
-
-    KeyLayoutMap* map;
-    status_t status = KeyLayoutMap::load(path, &map);
-    if (status) {
-        return status;
-    }
-
-    keyLayoutFile.setTo(path);
-    keyLayoutMap = map;
-    return OK;
-}
-
-status_t KeyMap::loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& name) {
-    String8 path(getPath(deviceIdentifier, name,
-            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP));
-    if (path.isEmpty()) {
-        return NAME_NOT_FOUND;
-    }
-
-    KeyCharacterMap* map;
-    status_t status = KeyCharacterMap::load(path, &map);
-    if (status) {
-        return status;
-    }
-
-    keyCharacterMapFile.setTo(path);
-    keyCharacterMap = map;
-    return OK;
-}
-
-String8 KeyMap::getPath(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& name, InputDeviceConfigurationFileType type) {
-    return name.isEmpty()
-            ? getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier, type)
-            : getInputDeviceConfigurationFilePathByName(name, type);
-}
-
-
-// --- Global functions ---
-
-bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,
-        const PropertyMap* deviceConfiguration, const KeyMap* keyMap) {
-    if (!keyMap->haveKeyCharacterMap()
-            || keyMap->keyCharacterMap->getKeyboardType()
-                    == KeyCharacterMap::KEYBOARD_TYPE_SPECIAL_FUNCTION) {
-        return false;
-    }
-
-    if (deviceConfiguration) {
-        bool builtIn = false;
-        if (deviceConfiguration->tryGetProperty(String8("keyboard.builtIn"), builtIn)
-                && builtIn) {
-            return true;
-        }
-    }
-
-    return strstr(deviceIdentifier.name.string(), "-keypad");
-}
-
-static int lookupValueByLabel(const char* literal, const KeycodeLabel *list) {
-    while (list->literal) {
-        if (strcmp(literal, list->literal) == 0) {
-            return list->value;
-        }
-        list++;
-    }
-    return list->value;
-}
-
-static const char* lookupLabelByValue(int value, const KeycodeLabel *list) {
-    while (list->literal) {
-        if (list->value == value) {
-            return list->literal;
-        }
-        list++;
-    }
-    return NULL;
-}
-
-int32_t getKeyCodeByLabel(const char* label) {
-    return int32_t(lookupValueByLabel(label, KEYCODES));
-}
-
-uint32_t getKeyFlagByLabel(const char* label) {
-    return uint32_t(lookupValueByLabel(label, FLAGS));
-}
-
-int32_t getAxisByLabel(const char* label) {
-    return int32_t(lookupValueByLabel(label, AXES));
-}
-
-const char* getAxisLabel(int32_t axisId) {
-    return lookupLabelByValue(axisId, AXES);
-}
-
-static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaState) {
-    int32_t newMetaState;
-    if (down) {
-        newMetaState = oldMetaState | mask;
-    } else {
-        newMetaState = oldMetaState &
-                ~(mask | AMETA_ALT_ON | AMETA_SHIFT_ON | AMETA_CTRL_ON | AMETA_META_ON);
-    }
-
-    if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
-        newMetaState |= AMETA_ALT_ON;
-    }
-
-    if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
-        newMetaState |= AMETA_SHIFT_ON;
-    }
-
-    if (newMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
-        newMetaState |= AMETA_CTRL_ON;
-    }
-
-    if (newMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
-        newMetaState |= AMETA_META_ON;
-    }
-    return newMetaState;
-}
-
-static int32_t toggleLockedMetaState(int32_t mask, bool down, int32_t oldMetaState) {
-    if (down) {
-        return oldMetaState;
-    } else {
-        return oldMetaState ^ mask;
-    }
-}
-
-int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
-    int32_t mask;
-    switch (keyCode) {
-    case AKEYCODE_ALT_LEFT:
-        return setEphemeralMetaState(AMETA_ALT_LEFT_ON, down, oldMetaState);
-    case AKEYCODE_ALT_RIGHT:
-        return setEphemeralMetaState(AMETA_ALT_RIGHT_ON, down, oldMetaState);
-    case AKEYCODE_SHIFT_LEFT:
-        return setEphemeralMetaState(AMETA_SHIFT_LEFT_ON, down, oldMetaState);
-    case AKEYCODE_SHIFT_RIGHT:
-        return setEphemeralMetaState(AMETA_SHIFT_RIGHT_ON, down, oldMetaState);
-    case AKEYCODE_SYM:
-        return setEphemeralMetaState(AMETA_SYM_ON, down, oldMetaState);
-    case AKEYCODE_FUNCTION:
-        return setEphemeralMetaState(AMETA_FUNCTION_ON, down, oldMetaState);
-    case AKEYCODE_CTRL_LEFT:
-        return setEphemeralMetaState(AMETA_CTRL_LEFT_ON, down, oldMetaState);
-    case AKEYCODE_CTRL_RIGHT:
-        return setEphemeralMetaState(AMETA_CTRL_RIGHT_ON, down, oldMetaState);
-    case AKEYCODE_META_LEFT:
-        return setEphemeralMetaState(AMETA_META_LEFT_ON, down, oldMetaState);
-    case AKEYCODE_META_RIGHT:
-        return setEphemeralMetaState(AMETA_META_RIGHT_ON, down, oldMetaState);
-    case AKEYCODE_CAPS_LOCK:
-        return toggleLockedMetaState(AMETA_CAPS_LOCK_ON, down, oldMetaState);
-    case AKEYCODE_NUM_LOCK:
-        return toggleLockedMetaState(AMETA_NUM_LOCK_ON, down, oldMetaState);
-    case AKEYCODE_SCROLL_LOCK:
-        return toggleLockedMetaState(AMETA_SCROLL_LOCK_ON, down, oldMetaState);
-    default:
-        return oldMetaState;
-    }
-}
-
-bool isMetaKey(int32_t keyCode) {
-    switch (keyCode) {
-    case AKEYCODE_ALT_LEFT:
-    case AKEYCODE_ALT_RIGHT:
-    case AKEYCODE_SHIFT_LEFT:
-    case AKEYCODE_SHIFT_RIGHT:
-    case AKEYCODE_SYM:
-    case AKEYCODE_FUNCTION:
-    case AKEYCODE_CTRL_LEFT:
-    case AKEYCODE_CTRL_RIGHT:
-    case AKEYCODE_META_LEFT:
-    case AKEYCODE_META_RIGHT:
-    case AKEYCODE_CAPS_LOCK:
-    case AKEYCODE_NUM_LOCK:
-    case AKEYCODE_SCROLL_LOCK:
-        return true;
-    default:
-        return false;
-    }
-}
-
-
-} // namespace android
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
index ee186c8..6993dac 100644
--- a/libs/ui/PixelFormat.cpp
+++ b/libs/ui/PixelFormat.cpp
@@ -15,13 +15,51 @@
  */
 
 #include <ui/PixelFormat.h>
-#include <pixelflinger/format.h>
 #include <hardware/hardware.h>
 
+// ----------------------------------------------------------------------------
 namespace android {
+// ----------------------------------------------------------------------------
 
 static const int COMPONENT_YUV = 0xFF;
 
+struct Info {
+    size_t      size;
+    size_t      bitsPerPixel;
+    struct {
+        uint8_t     ah;
+        uint8_t     al;
+        uint8_t     rh;
+        uint8_t     rl;
+        uint8_t     gh;
+        uint8_t     gl;
+        uint8_t     bh;
+        uint8_t     bl;
+    };
+    uint8_t     components;
+};
+
+static Info const sPixelFormatInfos[] = {
+        { 0,  0, { 0, 0,   0, 0,   0, 0,   0, 0 }, 0 },
+        { 4, 32, {32,24,   8, 0,  16, 8,  24,16 }, PixelFormatInfo::RGBA },
+        { 4, 24, { 0, 0,   8, 0,  16, 8,  24,16 }, PixelFormatInfo::RGB  },
+        { 3, 24, { 0, 0,   8, 0,  16, 8,  24,16 }, PixelFormatInfo::RGB  },
+        { 2, 16, { 0, 0,  16,11,  11, 5,   5, 0 }, PixelFormatInfo::RGB  },
+        { 4, 32, {32,24,  24,16,  16, 8,   8, 0 }, PixelFormatInfo::RGBA },
+        { 2, 16, { 1, 0,  16,11,  11, 6,   6, 1 }, PixelFormatInfo::RGBA },
+        { 2, 16, { 4, 0,  16,12,  12, 8,   8, 4 }, PixelFormatInfo::RGBA },
+        { 1,  8, { 8, 0,   0, 0,   0, 0,   0, 0 }, PixelFormatInfo::ALPHA}
+};
+
+static const Info* gGetPixelFormatTable(size_t* numEntries) {
+    if (numEntries) {
+        *numEntries = sizeof(sPixelFormatInfos)/sizeof(Info);
+    }
+    return sPixelFormatInfos;
+}
+
+// ----------------------------------------------------------------------------
+
 size_t PixelFormatInfo::getScanlineSize(unsigned int width) const
 {
     size_t size;
@@ -77,27 +115,12 @@
     }
 
     size_t numEntries;
-    const GGLFormat *i = gglGetPixelFormatTable(&numEntries) + format;
+    const Info *i = gGetPixelFormatTable(&numEntries) + format;
     bool valid = uint32_t(format) < numEntries;
     if (!valid) {
         return BAD_INDEX;
     }
 
-    #define COMPONENT(name) \
-        case GGL_##name: info->components = PixelFormatInfo::name; break;
-    
-    switch (i->components) {
-        COMPONENT(ALPHA)
-        COMPONENT(RGB)
-        COMPONENT(RGBA)
-        COMPONENT(LUMINANCE)
-        COMPONENT(LUMINANCE_ALPHA)
-        default:
-            return BAD_INDEX;
-    }
-    
-    #undef COMPONENT
-    
     info->format = format;
     info->bytesPerPixel = i->size;
     info->bitsPerPixel  = i->bitsPerPixel;
@@ -109,9 +132,12 @@
     info->l_green       = i->gl;
     info->h_blue        = i->bh;
     info->l_blue        = i->bl;
+    info->components    = i->components;
 
     return NO_ERROR;
 }
 
+// ----------------------------------------------------------------------------
 }; // namespace android
+// ----------------------------------------------------------------------------
 
diff --git a/libs/ui/VirtualKeyMap.cpp b/libs/ui/VirtualKeyMap.cpp
deleted file mode 100644
index 2ba1673..0000000
--- a/libs/ui/VirtualKeyMap.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2010 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 "VirtualKeyMap"
-
-#include <stdlib.h>
-#include <string.h>
-#include <androidfw/VirtualKeyMap.h>
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/Tokenizer.h>
-#include <utils/Timers.h>
-
-// Enables debug output for the parser.
-#define DEBUG_PARSER 0
-
-// Enables debug output for parser performance.
-#define DEBUG_PARSER_PERFORMANCE 0
-
-
-namespace android {
-
-static const char* WHITESPACE = " \t\r";
-static const char* WHITESPACE_OR_FIELD_DELIMITER = " \t\r:";
-
-
-// --- VirtualKeyMap ---
-
-VirtualKeyMap::VirtualKeyMap() {
-}
-
-VirtualKeyMap::~VirtualKeyMap() {
-}
-
-status_t VirtualKeyMap::load(const String8& filename, VirtualKeyMap** outMap) {
-    *outMap = NULL;
-
-    Tokenizer* tokenizer;
-    status_t status = Tokenizer::open(filename, &tokenizer);
-    if (status) {
-        ALOGE("Error %d opening virtual key map file %s.", status, filename.string());
-    } else {
-        VirtualKeyMap* map = new VirtualKeyMap();
-        if (!map) {
-            ALOGE("Error allocating virtual key map.");
-            status = NO_MEMORY;
-        } else {
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
-            Parser parser(map, tokenizer);
-            status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
-            ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
-                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),
-                    elapsedTime / 1000000.0);
-#endif
-            if (status) {
-                delete map;
-            } else {
-                *outMap = map;
-            }
-        }
-        delete tokenizer;
-    }
-    return status;
-}
-
-
-// --- VirtualKeyMap::Parser ---
-
-VirtualKeyMap::Parser::Parser(VirtualKeyMap* map, Tokenizer* tokenizer) :
-        mMap(map), mTokenizer(tokenizer) {
-}
-
-VirtualKeyMap::Parser::~Parser() {
-}
-
-status_t VirtualKeyMap::Parser::parse() {
-    while (!mTokenizer->isEof()) {
-#if DEBUG_PARSER
-        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
-                mTokenizer->peekRemainderOfLine().string());
-#endif
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-
-        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
-            // Multiple keys can appear on one line or they can be broken up across multiple lines.
-            do {
-                String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
-                if (token != "0x01") {
-                    ALOGE("%s: Unknown virtual key type, expected 0x01.",
-                          mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-
-                VirtualKeyDefinition defn;
-                bool success = parseNextIntField(&defn.scanCode)
-                        && parseNextIntField(&defn.centerX)
-                        && parseNextIntField(&defn.centerY)
-                        && parseNextIntField(&defn.width)
-                        && parseNextIntField(&defn.height);
-                if (!success) {
-                    ALOGE("%s: Expected 5 colon-delimited integers in virtual key definition.",
-                          mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-
-#if DEBUG_PARSER
-                ALOGD("Parsed virtual key: scanCode=%d, centerX=%d, centerY=%d, "
-                        "width=%d, height=%d",
-                        defn.scanCode, defn.centerX, defn.centerY, defn.width, defn.height);
-#endif
-                mMap->mVirtualKeys.push(defn);
-            } while (consumeFieldDelimiterAndSkipWhitespace());
-
-            if (!mTokenizer->isEol()) {
-                ALOGE("%s: Expected end of line, got '%s'.",
-                        mTokenizer->getLocation().string(),
-                        mTokenizer->peekRemainderOfLine().string());
-                return BAD_VALUE;
-            }
-        }
-
-        mTokenizer->nextLine();
-    }
-
-    return NO_ERROR;
-}
-
-bool VirtualKeyMap::Parser::consumeFieldDelimiterAndSkipWhitespace() {
-    mTokenizer->skipDelimiters(WHITESPACE);
-    if (mTokenizer->peekChar() == ':') {
-        mTokenizer->nextChar();
-        mTokenizer->skipDelimiters(WHITESPACE);
-        return true;
-    }
-    return false;
-}
-
-bool VirtualKeyMap::Parser::parseNextIntField(int32_t* outValue) {
-    if (!consumeFieldDelimiterAndSkipWhitespace()) {
-        return false;
-    }
-
-    String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
-    char* end;
-    *outValue = strtol(token.string(), &end, 0);
-    if (token.isEmpty() || *end != '\0') {
-        ALOGE("Expected an integer, got '%s'.", token.string());
-        return false;
-    }
-    return true;
-}
-
-} // namespace android
diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk
index 700b604..50cad36 100644
--- a/libs/ui/tests/Android.mk
+++ b/libs/ui/tests/Android.mk
@@ -2,47 +2,5 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-# Build the unit tests.
-test_src_files := \
-    InputChannel_test.cpp \
-    InputEvent_test.cpp \
-    InputPublisherAndConsumer_test.cpp
-
-shared_libraries := \
-	libcutils \
-	libutils \
-	libEGL \
-	libbinder \
-	libpixelflinger \
-	libhardware \
-	libhardware_legacy \
-	libui \
-	libstlport \
-	libskia
-
-static_libraries := \
-	libgtest \
-	libgtest_main
-
-c_includes := \
-    bionic \
-    bionic/libstdc++/include \
-    external/gtest/include \
-    external/stlport/stlport \
-    external/skia/include/core
-
-module_tags := eng tests
-
-$(foreach file,$(test_src_files), \
-    $(eval include $(CLEAR_VARS)) \
-    $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
-    $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
-    $(eval LOCAL_C_INCLUDES := $(c_includes)) \
-    $(eval LOCAL_SRC_FILES := $(file)) \
-    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
-    $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
-    $(eval include $(BUILD_EXECUTABLE)) \
-)
-
 # Build the manual test programs.
 include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/libs/ui/tests/InputChannel_test.cpp b/libs/ui/tests/InputChannel_test.cpp
deleted file mode 100644
index 0e5d19d..0000000
--- a/libs/ui/tests/InputChannel_test.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2010 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 <androidfw/InputTransport.h>
-#include <utils/Timers.h>
-#include <utils/StopWatch.h>
-#include <utils/StrongPointer.h>
-#include <gtest/gtest.h>
-#include <unistd.h>
-#include <time.h>
-#include <errno.h>
-
-#include "../../utils/tests/TestHelpers.h"
-
-namespace android {
-
-class InputChannelTest : public testing::Test {
-protected:
-    virtual void SetUp() { }
-    virtual void TearDown() { }
-};
-
-
-TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptors) {
-    // Our purpose here is to verify that the input channel destructor closes the
-    // file descriptor provided to it.  One easy way is to provide it with one end
-    // of a pipe and to check for EPIPE on the other end after the channel is destroyed.
-    Pipe pipe;
-
-    sp<InputChannel> inputChannel = new InputChannel(String8("channel name"), pipe.sendFd);
-
-    EXPECT_STREQ("channel name", inputChannel->getName().string())
-            << "channel should have provided name";
-    EXPECT_EQ(pipe.sendFd, inputChannel->getFd())
-            << "channel should have provided fd";
-
-    inputChannel.clear(); // destroys input channel
-
-    EXPECT_EQ(-EPIPE, pipe.readSignal())
-            << "channel should have closed fd when destroyed";
-
-    // clean up fds of Pipe endpoints that were closed so we don't try to close them again
-    pipe.sendFd = -1;
-}
-
-TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
-    sp<InputChannel> serverChannel, clientChannel;
-
-    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-            serverChannel, clientChannel);
-
-    ASSERT_EQ(OK, result)
-            << "should have successfully opened a channel pair";
-
-    // Name
-    EXPECT_STREQ("channel name (server)", serverChannel->getName().string())
-            << "server channel should have suffixed name";
-    EXPECT_STREQ("channel name (client)", clientChannel->getName().string())
-            << "client channel should have suffixed name";
-
-    // Server->Client communication
-    InputMessage serverMsg;
-    memset(&serverMsg, 0, sizeof(InputMessage));
-    serverMsg.header.type = InputMessage::TYPE_KEY;
-    serverMsg.body.key.action = AKEY_EVENT_ACTION_DOWN;
-    EXPECT_EQ(OK, serverChannel->sendMessage(&serverMsg))
-            << "server channel should be able to send message to client channel";
-
-    InputMessage clientMsg;
-    EXPECT_EQ(OK, clientChannel->receiveMessage(&clientMsg))
-            << "client channel should be able to receive message from server channel";
-    EXPECT_EQ(serverMsg.header.type, clientMsg.header.type)
-            << "client channel should receive the correct message from server channel";
-    EXPECT_EQ(serverMsg.body.key.action, clientMsg.body.key.action)
-            << "client channel should receive the correct message from server channel";
-
-    // Client->Server communication
-    InputMessage clientReply;
-    memset(&clientReply, 0, sizeof(InputMessage));
-    clientReply.header.type = InputMessage::TYPE_FINISHED;
-    clientReply.body.finished.seq = 0x11223344;
-    clientReply.body.finished.handled = true;
-    EXPECT_EQ(OK, clientChannel->sendMessage(&clientReply))
-            << "client channel should be able to send message to server channel";
-
-    InputMessage serverReply;
-    EXPECT_EQ(OK, serverChannel->receiveMessage(&serverReply))
-            << "server channel should be able to receive message from client channel";
-    EXPECT_EQ(clientReply.header.type, serverReply.header.type)
-            << "server channel should receive the correct message from client channel";
-    EXPECT_EQ(clientReply.body.finished.seq, serverReply.body.finished.seq)
-            << "server channel should receive the correct message from client channel";
-    EXPECT_EQ(clientReply.body.finished.handled, serverReply.body.finished.handled)
-            << "server channel should receive the correct message from client channel";
-}
-
-TEST_F(InputChannelTest, ReceiveSignal_WhenNoSignalPresent_ReturnsAnError) {
-    sp<InputChannel> serverChannel, clientChannel;
-
-    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-            serverChannel, clientChannel);
-
-    ASSERT_EQ(OK, result)
-            << "should have successfully opened a channel pair";
-
-    InputMessage msg;
-    EXPECT_EQ(WOULD_BLOCK, clientChannel->receiveMessage(&msg))
-            << "receiveMessage should have returned WOULD_BLOCK";
-}
-
-TEST_F(InputChannelTest, ReceiveSignal_WhenPeerClosed_ReturnsAnError) {
-    sp<InputChannel> serverChannel, clientChannel;
-
-    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-            serverChannel, clientChannel);
-
-    ASSERT_EQ(OK, result)
-            << "should have successfully opened a channel pair";
-
-    serverChannel.clear(); // close server channel
-
-    InputMessage msg;
-    EXPECT_EQ(DEAD_OBJECT, clientChannel->receiveMessage(&msg))
-            << "receiveMessage should have returned DEAD_OBJECT";
-}
-
-TEST_F(InputChannelTest, SendSignal_WhenPeerClosed_ReturnsAnError) {
-    sp<InputChannel> serverChannel, clientChannel;
-
-    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-            serverChannel, clientChannel);
-
-    ASSERT_EQ(OK, result)
-            << "should have successfully opened a channel pair";
-
-    serverChannel.clear(); // close server channel
-
-    InputMessage msg;
-    msg.header.type = InputMessage::TYPE_KEY;
-    EXPECT_EQ(DEAD_OBJECT, clientChannel->sendMessage(&msg))
-            << "sendMessage should have returned DEAD_OBJECT";
-}
-
-
-} // namespace android
diff --git a/libs/ui/tests/InputEvent_test.cpp b/libs/ui/tests/InputEvent_test.cpp
deleted file mode 100644
index ac5549c..0000000
--- a/libs/ui/tests/InputEvent_test.cpp
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Copyright (C) 2011 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 <androidfw/Input.h>
-#include <gtest/gtest.h>
-#include <binder/Parcel.h>
-
-#include <math.h>
-#include <SkMatrix.h>
-
-namespace android {
-
-class BaseTest : public testing::Test {
-protected:
-    virtual void SetUp() { }
-    virtual void TearDown() { }
-};
-
-// --- PointerCoordsTest ---
-
-class PointerCoordsTest : public BaseTest {
-};
-
-TEST_F(PointerCoordsTest, ClearSetsBitsToZero) {
-    PointerCoords coords;
-    coords.clear();
-
-    ASSERT_EQ(0ULL, coords.bits);
-}
-
-TEST_F(PointerCoordsTest, AxisValues) {
-    float* valuePtr;
-    PointerCoords coords;
-    coords.clear();
-
-    // Check invariants when no axes are present.
-    ASSERT_EQ(0, coords.getAxisValue(0))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(0, coords.getAxisValue(1))
-            << "getAxisValue should return zero because axis is not present";
-
-    // Set first axis.
-    ASSERT_EQ(OK, coords.setAxisValue(1, 5));
-    ASSERT_EQ(0x00000002ULL, coords.bits);
-    ASSERT_EQ(5, coords.values[0]);
-
-    ASSERT_EQ(0, coords.getAxisValue(0))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(5, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-
-    // Set an axis with a higher id than all others.  (appending value at the end)
-    ASSERT_EQ(OK, coords.setAxisValue(3, 2));
-    ASSERT_EQ(0x0000000aULL, coords.bits);
-    ASSERT_EQ(5, coords.values[0]);
-    ASSERT_EQ(2, coords.values[1]);
-
-    ASSERT_EQ(0, coords.getAxisValue(0))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(5, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(0, coords.getAxisValue(2))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(2, coords.getAxisValue(3))
-            << "getAxisValue should return value of axis";
-
-    // Set an axis with an id lower than all others.  (prepending value at beginning)
-    ASSERT_EQ(OK, coords.setAxisValue(0, 4));
-    ASSERT_EQ(0x0000000bULL, coords.bits);
-    ASSERT_EQ(4, coords.values[0]);
-    ASSERT_EQ(5, coords.values[1]);
-    ASSERT_EQ(2, coords.values[2]);
-
-    ASSERT_EQ(4, coords.getAxisValue(0))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(5, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(0, coords.getAxisValue(2))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(2, coords.getAxisValue(3))
-            << "getAxisValue should return value of axis";
-
-    // Set an axis with an id between the others.  (inserting value in the middle)
-    ASSERT_EQ(OK, coords.setAxisValue(2, 1));
-    ASSERT_EQ(0x0000000fULL, coords.bits);
-    ASSERT_EQ(4, coords.values[0]);
-    ASSERT_EQ(5, coords.values[1]);
-    ASSERT_EQ(1, coords.values[2]);
-    ASSERT_EQ(2, coords.values[3]);
-
-    ASSERT_EQ(4, coords.getAxisValue(0))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(5, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(1, coords.getAxisValue(2))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(2, coords.getAxisValue(3))
-            << "getAxisValue should return value of axis";
-
-    // Set an existing axis value in place.
-    ASSERT_EQ(OK, coords.setAxisValue(1, 6));
-    ASSERT_EQ(0x0000000fULL, coords.bits);
-    ASSERT_EQ(4, coords.values[0]);
-    ASSERT_EQ(6, coords.values[1]);
-    ASSERT_EQ(1, coords.values[2]);
-    ASSERT_EQ(2, coords.values[3]);
-
-    ASSERT_EQ(4, coords.getAxisValue(0))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(6, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(1, coords.getAxisValue(2))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(2, coords.getAxisValue(3))
-            << "getAxisValue should return value of axis";
-
-    // Set maximum number of axes.
-    for (size_t axis = 4; axis < PointerCoords::MAX_AXES; axis++) {
-        ASSERT_EQ(OK, coords.setAxisValue(axis, axis));
-    }
-    ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
-
-    // Try to set one more axis beyond maximum number.
-    // Ensure bits are unchanged.
-    ASSERT_EQ(NO_MEMORY, coords.setAxisValue(PointerCoords::MAX_AXES, 100));
-    ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
-}
-
-TEST_F(PointerCoordsTest, Parcel) {
-    Parcel parcel;
-
-    PointerCoords inCoords;
-    inCoords.clear();
-    PointerCoords outCoords;
-
-    // Round trip with empty coords.
-    inCoords.writeToParcel(&parcel);
-    parcel.setDataPosition(0);
-    outCoords.readFromParcel(&parcel);
-
-    ASSERT_EQ(0ULL, outCoords.bits);
-
-    // Round trip with some values.
-    parcel.freeData();
-    inCoords.setAxisValue(2, 5);
-    inCoords.setAxisValue(5, 8);
-
-    inCoords.writeToParcel(&parcel);
-    parcel.setDataPosition(0);
-    outCoords.readFromParcel(&parcel);
-
-    ASSERT_EQ(outCoords.bits, inCoords.bits);
-    ASSERT_EQ(outCoords.values[0], inCoords.values[0]);
-    ASSERT_EQ(outCoords.values[1], inCoords.values[1]);
-}
-
-
-// --- KeyEventTest ---
-
-class KeyEventTest : public BaseTest {
-};
-
-TEST_F(KeyEventTest, Properties) {
-    KeyEvent event;
-
-    // Initialize and get properties.
-    const nsecs_t ARBITRARY_DOWN_TIME = 1;
-    const nsecs_t ARBITRARY_EVENT_TIME = 2;
-    event.initialize(2, AINPUT_SOURCE_GAMEPAD, AKEY_EVENT_ACTION_DOWN,
-            AKEY_EVENT_FLAG_FROM_SYSTEM, AKEYCODE_BUTTON_X, 121,
-            AMETA_ALT_ON, 1, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME);
-
-    ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event.getType());
-    ASSERT_EQ(2, event.getDeviceId());
-    ASSERT_EQ(AINPUT_SOURCE_GAMEPAD, event.getSource());
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, event.getAction());
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, event.getFlags());
-    ASSERT_EQ(AKEYCODE_BUTTON_X, event.getKeyCode());
-    ASSERT_EQ(121, event.getScanCode());
-    ASSERT_EQ(AMETA_ALT_ON, event.getMetaState());
-    ASSERT_EQ(1, event.getRepeatCount());
-    ASSERT_EQ(ARBITRARY_DOWN_TIME, event.getDownTime());
-    ASSERT_EQ(ARBITRARY_EVENT_TIME, event.getEventTime());
-
-    // Set source.
-    event.setSource(AINPUT_SOURCE_JOYSTICK);
-    ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
-}
-
-
-// --- MotionEventTest ---
-
-class MotionEventTest : public BaseTest {
-protected:
-    static const nsecs_t ARBITRARY_DOWN_TIME;
-    static const nsecs_t ARBITRARY_EVENT_TIME;
-    static const float X_OFFSET;
-    static const float Y_OFFSET;
-
-    void initializeEventWithHistory(MotionEvent* event);
-    void assertEqualsEventWithHistory(const MotionEvent* event);
-};
-
-const nsecs_t MotionEventTest::ARBITRARY_DOWN_TIME = 1;
-const nsecs_t MotionEventTest::ARBITRARY_EVENT_TIME = 2;
-const float MotionEventTest::X_OFFSET = 1.0f;
-const float MotionEventTest::Y_OFFSET = 1.1f;
-
-void MotionEventTest::initializeEventWithHistory(MotionEvent* event) {
-    PointerProperties pointerProperties[2];
-    pointerProperties[0].clear();
-    pointerProperties[0].id = 1;
-    pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
-    pointerProperties[1].clear();
-    pointerProperties[1].id = 2;
-    pointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
-
-    PointerCoords pointerCoords[2];
-    pointerCoords[0].clear();
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 10);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 11);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 12);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 13);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 14);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 15);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 16);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 17);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 18);
-    pointerCoords[1].clear();
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 20);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 21);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 22);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 23);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 24);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 25);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 26);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 27);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 28);
-    event->initialize(2, AINPUT_SOURCE_TOUCHSCREEN, AMOTION_EVENT_ACTION_MOVE,
-            AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED,
-            AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY,
-            X_OFFSET, Y_OFFSET, 2.0f, 2.1f,
-            ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME,
-            2, pointerProperties, pointerCoords);
-
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 112);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 113);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 114);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 115);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 116);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 117);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 118);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 120);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 121);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 122);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 123);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 124);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 125);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 126);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 127);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 128);
-    event->addSample(ARBITRARY_EVENT_TIME + 1, pointerCoords);
-
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 210);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 211);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 212);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 213);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 214);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 215);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 216);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 217);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 218);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 220);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 221);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 222);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 223);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 224);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 225);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 226);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 227);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 228);
-    event->addSample(ARBITRARY_EVENT_TIME + 2, pointerCoords);
-}
-
-void MotionEventTest::assertEqualsEventWithHistory(const MotionEvent* event) {
-    // Check properties.
-    ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType());
-    ASSERT_EQ(2, event->getDeviceId());
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, event->getSource());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, event->getAction());
-    ASSERT_EQ(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED, event->getFlags());
-    ASSERT_EQ(AMOTION_EVENT_EDGE_FLAG_TOP, event->getEdgeFlags());
-    ASSERT_EQ(AMETA_ALT_ON, event->getMetaState());
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, event->getButtonState());
-    ASSERT_EQ(X_OFFSET, event->getXOffset());
-    ASSERT_EQ(Y_OFFSET, event->getYOffset());
-    ASSERT_EQ(2.0f, event->getXPrecision());
-    ASSERT_EQ(2.1f, event->getYPrecision());
-    ASSERT_EQ(ARBITRARY_DOWN_TIME, event->getDownTime());
-
-    ASSERT_EQ(2U, event->getPointerCount());
-    ASSERT_EQ(1, event->getPointerId(0));
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, event->getToolType(0));
-    ASSERT_EQ(2, event->getPointerId(1));
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, event->getToolType(1));
-
-    ASSERT_EQ(2U, event->getHistorySize());
-
-    // Check data.
-    ASSERT_EQ(ARBITRARY_EVENT_TIME, event->getHistoricalEventTime(0));
-    ASSERT_EQ(ARBITRARY_EVENT_TIME + 1, event->getHistoricalEventTime(1));
-    ASSERT_EQ(ARBITRARY_EVENT_TIME + 2, event->getEventTime());
-
-    ASSERT_EQ(11, event->getHistoricalRawPointerCoords(0, 0)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(21, event->getHistoricalRawPointerCoords(1, 0)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(111, event->getHistoricalRawPointerCoords(0, 1)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(121, event->getHistoricalRawPointerCoords(1, 1)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(211, event->getRawPointerCoords(0)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(221, event->getRawPointerCoords(1)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-
-    ASSERT_EQ(11, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 0));
-    ASSERT_EQ(21, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 0));
-    ASSERT_EQ(111, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 1));
-    ASSERT_EQ(121, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 1));
-    ASSERT_EQ(211, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 0));
-    ASSERT_EQ(221, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 1));
-
-    ASSERT_EQ(10, event->getHistoricalRawX(0, 0));
-    ASSERT_EQ(20, event->getHistoricalRawX(1, 0));
-    ASSERT_EQ(110, event->getHistoricalRawX(0, 1));
-    ASSERT_EQ(120, event->getHistoricalRawX(1, 1));
-    ASSERT_EQ(210, event->getRawX(0));
-    ASSERT_EQ(220, event->getRawX(1));
-
-    ASSERT_EQ(11, event->getHistoricalRawY(0, 0));
-    ASSERT_EQ(21, event->getHistoricalRawY(1, 0));
-    ASSERT_EQ(111, event->getHistoricalRawY(0, 1));
-    ASSERT_EQ(121, event->getHistoricalRawY(1, 1));
-    ASSERT_EQ(211, event->getRawY(0));
-    ASSERT_EQ(221, event->getRawY(1));
-
-    ASSERT_EQ(X_OFFSET + 10, event->getHistoricalX(0, 0));
-    ASSERT_EQ(X_OFFSET + 20, event->getHistoricalX(1, 0));
-    ASSERT_EQ(X_OFFSET + 110, event->getHistoricalX(0, 1));
-    ASSERT_EQ(X_OFFSET + 120, event->getHistoricalX(1, 1));
-    ASSERT_EQ(X_OFFSET + 210, event->getX(0));
-    ASSERT_EQ(X_OFFSET + 220, event->getX(1));
-
-    ASSERT_EQ(Y_OFFSET + 11, event->getHistoricalY(0, 0));
-    ASSERT_EQ(Y_OFFSET + 21, event->getHistoricalY(1, 0));
-    ASSERT_EQ(Y_OFFSET + 111, event->getHistoricalY(0, 1));
-    ASSERT_EQ(Y_OFFSET + 121, event->getHistoricalY(1, 1));
-    ASSERT_EQ(Y_OFFSET + 211, event->getY(0));
-    ASSERT_EQ(Y_OFFSET + 221, event->getY(1));
-
-    ASSERT_EQ(12, event->getHistoricalPressure(0, 0));
-    ASSERT_EQ(22, event->getHistoricalPressure(1, 0));
-    ASSERT_EQ(112, event->getHistoricalPressure(0, 1));
-    ASSERT_EQ(122, event->getHistoricalPressure(1, 1));
-    ASSERT_EQ(212, event->getPressure(0));
-    ASSERT_EQ(222, event->getPressure(1));
-
-    ASSERT_EQ(13, event->getHistoricalSize(0, 0));
-    ASSERT_EQ(23, event->getHistoricalSize(1, 0));
-    ASSERT_EQ(113, event->getHistoricalSize(0, 1));
-    ASSERT_EQ(123, event->getHistoricalSize(1, 1));
-    ASSERT_EQ(213, event->getSize(0));
-    ASSERT_EQ(223, event->getSize(1));
-
-    ASSERT_EQ(14, event->getHistoricalTouchMajor(0, 0));
-    ASSERT_EQ(24, event->getHistoricalTouchMajor(1, 0));
-    ASSERT_EQ(114, event->getHistoricalTouchMajor(0, 1));
-    ASSERT_EQ(124, event->getHistoricalTouchMajor(1, 1));
-    ASSERT_EQ(214, event->getTouchMajor(0));
-    ASSERT_EQ(224, event->getTouchMajor(1));
-
-    ASSERT_EQ(15, event->getHistoricalTouchMinor(0, 0));
-    ASSERT_EQ(25, event->getHistoricalTouchMinor(1, 0));
-    ASSERT_EQ(115, event->getHistoricalTouchMinor(0, 1));
-    ASSERT_EQ(125, event->getHistoricalTouchMinor(1, 1));
-    ASSERT_EQ(215, event->getTouchMinor(0));
-    ASSERT_EQ(225, event->getTouchMinor(1));
-
-    ASSERT_EQ(16, event->getHistoricalToolMajor(0, 0));
-    ASSERT_EQ(26, event->getHistoricalToolMajor(1, 0));
-    ASSERT_EQ(116, event->getHistoricalToolMajor(0, 1));
-    ASSERT_EQ(126, event->getHistoricalToolMajor(1, 1));
-    ASSERT_EQ(216, event->getToolMajor(0));
-    ASSERT_EQ(226, event->getToolMajor(1));
-
-    ASSERT_EQ(17, event->getHistoricalToolMinor(0, 0));
-    ASSERT_EQ(27, event->getHistoricalToolMinor(1, 0));
-    ASSERT_EQ(117, event->getHistoricalToolMinor(0, 1));
-    ASSERT_EQ(127, event->getHistoricalToolMinor(1, 1));
-    ASSERT_EQ(217, event->getToolMinor(0));
-    ASSERT_EQ(227, event->getToolMinor(1));
-
-    ASSERT_EQ(18, event->getHistoricalOrientation(0, 0));
-    ASSERT_EQ(28, event->getHistoricalOrientation(1, 0));
-    ASSERT_EQ(118, event->getHistoricalOrientation(0, 1));
-    ASSERT_EQ(128, event->getHistoricalOrientation(1, 1));
-    ASSERT_EQ(218, event->getOrientation(0));
-    ASSERT_EQ(228, event->getOrientation(1));
-}
-
-TEST_F(MotionEventTest, Properties) {
-    MotionEvent event;
-
-    // Initialize, add samples and check properties.
-    initializeEventWithHistory(&event);
-    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
-
-    // Set source.
-    event.setSource(AINPUT_SOURCE_JOYSTICK);
-    ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
-
-    // Set action.
-    event.setAction(AMOTION_EVENT_ACTION_CANCEL);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, event.getAction());
-
-    // Set meta state.
-    event.setMetaState(AMETA_CTRL_ON);
-    ASSERT_EQ(AMETA_CTRL_ON, event.getMetaState());
-}
-
-TEST_F(MotionEventTest, CopyFrom_KeepHistory) {
-    MotionEvent event;
-    initializeEventWithHistory(&event);
-
-    MotionEvent copy;
-    copy.copyFrom(&event, true /*keepHistory*/);
-
-    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
-}
-
-TEST_F(MotionEventTest, CopyFrom_DoNotKeepHistory) {
-    MotionEvent event;
-    initializeEventWithHistory(&event);
-
-    MotionEvent copy;
-    copy.copyFrom(&event, false /*keepHistory*/);
-
-    ASSERT_EQ(event.getPointerCount(), copy.getPointerCount());
-    ASSERT_EQ(0U, copy.getHistorySize());
-
-    ASSERT_EQ(event.getPointerId(0), copy.getPointerId(0));
-    ASSERT_EQ(event.getPointerId(1), copy.getPointerId(1));
-
-    ASSERT_EQ(event.getEventTime(), copy.getEventTime());
-
-    ASSERT_EQ(event.getX(0), copy.getX(0));
-}
-
-TEST_F(MotionEventTest, OffsetLocation) {
-    MotionEvent event;
-    initializeEventWithHistory(&event);
-
-    event.offsetLocation(5.0f, -2.0f);
-
-    ASSERT_EQ(X_OFFSET + 5.0f, event.getXOffset());
-    ASSERT_EQ(Y_OFFSET - 2.0f, event.getYOffset());
-}
-
-TEST_F(MotionEventTest, Scale) {
-    MotionEvent event;
-    initializeEventWithHistory(&event);
-
-    event.scale(2.0f);
-
-    ASSERT_EQ(X_OFFSET * 2, event.getXOffset());
-    ASSERT_EQ(Y_OFFSET * 2, event.getYOffset());
-
-    ASSERT_EQ(210 * 2, event.getRawX(0));
-    ASSERT_EQ(211 * 2, event.getRawY(0));
-    ASSERT_EQ((X_OFFSET + 210) * 2, event.getX(0));
-    ASSERT_EQ((Y_OFFSET + 211) * 2, event.getY(0));
-    ASSERT_EQ(212, event.getPressure(0));
-    ASSERT_EQ(213, event.getSize(0));
-    ASSERT_EQ(214 * 2, event.getTouchMajor(0));
-    ASSERT_EQ(215 * 2, event.getTouchMinor(0));
-    ASSERT_EQ(216 * 2, event.getToolMajor(0));
-    ASSERT_EQ(217 * 2, event.getToolMinor(0));
-    ASSERT_EQ(218, event.getOrientation(0));
-}
-
-TEST_F(MotionEventTest, Parcel) {
-    Parcel parcel;
-
-    MotionEvent inEvent;
-    initializeEventWithHistory(&inEvent);
-    MotionEvent outEvent;
-
-    // Round trip.
-    inEvent.writeToParcel(&parcel);
-    parcel.setDataPosition(0);
-    outEvent.readFromParcel(&parcel);
-
-    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&outEvent));
-}
-
-TEST_F(MotionEventTest, Transform) {
-    // Generate some points on a circle.
-    // Each point 'i' is a point on a circle of radius ROTATION centered at (3,2) at an angle
-    // of ARC * i degrees clockwise relative to the Y axis.
-    // The geometrical representation is irrelevant to the test, it's just easy to generate
-    // and check rotation.  We set the orientation to the same angle.
-    // Coordinate system: down is increasing Y, right is increasing X.
-    const float PI_180 = float(M_PI / 180);
-    const float RADIUS = 10;
-    const float ARC = 36;
-    const float ROTATION = ARC * 2;
-
-    const size_t pointerCount = 11;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        float angle = float(i * ARC * PI_180);
-        pointerProperties[i].clear();
-        pointerProperties[i].id = i;
-        pointerCoords[i].clear();
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, sinf(angle) * RADIUS + 3);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, -cosf(angle) * RADIUS + 2);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, angle);
-    }
-    MotionEvent event;
-    event.initialize(0, 0, AMOTION_EVENT_ACTION_MOVE, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords);
-    float originalRawX = 0 + 3;
-    float originalRawY = -RADIUS + 2;
-
-    // Check original raw X and Y assumption.
-    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
-    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
-
-    // Now translate the motion event so the circle's origin is at (0,0).
-    event.offsetLocation(-3, -2);
-
-    // Offsetting the location should preserve the raw X and Y of the first point.
-    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
-    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
-
-    // Apply a rotation about the origin by ROTATION degrees clockwise.
-    SkMatrix matrix;
-    matrix.setRotate(ROTATION);
-    event.transform(&matrix);
-
-    // Check the points.
-    for (size_t i = 0; i < pointerCount; i++) {
-        float angle = float((i * ARC + ROTATION) * PI_180);
-        ASSERT_NEAR(sinf(angle) * RADIUS, event.getX(i), 0.001);
-        ASSERT_NEAR(-cosf(angle) * RADIUS, event.getY(i), 0.001);
-        ASSERT_NEAR(tanf(angle), tanf(event.getOrientation(i)), 0.1);
-    }
-
-    // Applying the transformation should preserve the raw X and Y of the first point.
-    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
-    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
-}
-
-} // namespace android
diff --git a/libs/ui/tests/InputPublisherAndConsumer_test.cpp b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
deleted file mode 100644
index bb45247..0000000
--- a/libs/ui/tests/InputPublisherAndConsumer_test.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2010 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 <androidfw/InputTransport.h>
-#include <utils/Timers.h>
-#include <utils/StopWatch.h>
-#include <gtest/gtest.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/mman.h>
-#include <cutils/ashmem.h>
-
-#include "../../utils/tests/TestHelpers.h"
-
-namespace android {
-
-class InputPublisherAndConsumerTest : public testing::Test {
-protected:
-    sp<InputChannel> serverChannel, clientChannel;
-    InputPublisher* mPublisher;
-    InputConsumer* mConsumer;
-    PreallocatedInputEventFactory mEventFactory;
-
-    virtual void SetUp() {
-        status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-                serverChannel, clientChannel);
-
-        mPublisher = new InputPublisher(serverChannel);
-        mConsumer = new InputConsumer(clientChannel);
-    }
-
-    virtual void TearDown() {
-        if (mPublisher) {
-            delete mPublisher;
-            mPublisher = NULL;
-        }
-
-        if (mConsumer) {
-            delete mConsumer;
-            mConsumer = NULL;
-        }
-
-        serverChannel.clear();
-        clientChannel.clear();
-    }
-
-    void PublishAndConsumeKeyEvent();
-    void PublishAndConsumeMotionEvent();
-};
-
-TEST_F(InputPublisherAndConsumerTest, GetChannel_ReturnsTheChannel) {
-    EXPECT_EQ(serverChannel.get(), mPublisher->getChannel().get());
-    EXPECT_EQ(clientChannel.get(), mConsumer->getChannel().get());
-}
-
-void InputPublisherAndConsumerTest::PublishAndConsumeKeyEvent() {
-    status_t status;
-
-    const uint32_t seq = 15;
-    const int32_t deviceId = 1;
-    const int32_t source = AINPUT_SOURCE_KEYBOARD;
-    const int32_t action = AKEY_EVENT_ACTION_DOWN;
-    const int32_t flags = AKEY_EVENT_FLAG_FROM_SYSTEM;
-    const int32_t keyCode = AKEYCODE_ENTER;
-    const int32_t scanCode = 13;
-    const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
-    const int32_t repeatCount = 1;
-    const nsecs_t downTime = 3;
-    const nsecs_t eventTime = 4;
-
-    status = mPublisher->publishKeyEvent(seq, deviceId, source, action, flags,
-            keyCode, scanCode, metaState, repeatCount, downTime, eventTime);
-    ASSERT_EQ(OK, status)
-            << "publisher publishKeyEvent should return OK";
-
-    uint32_t consumeSeq;
-    InputEvent* event;
-    status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, &consumeSeq, &event);
-    ASSERT_EQ(OK, status)
-            << "consumer consume should return OK";
-
-    ASSERT_TRUE(event != NULL)
-            << "consumer should have returned non-NULL event";
-    ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event->getType())
-            << "consumer should have returned a key event";
-
-    KeyEvent* keyEvent = static_cast<KeyEvent*>(event);
-    EXPECT_EQ(seq, consumeSeq);
-    EXPECT_EQ(deviceId, keyEvent->getDeviceId());
-    EXPECT_EQ(source, keyEvent->getSource());
-    EXPECT_EQ(action, keyEvent->getAction());
-    EXPECT_EQ(flags, keyEvent->getFlags());
-    EXPECT_EQ(keyCode, keyEvent->getKeyCode());
-    EXPECT_EQ(scanCode, keyEvent->getScanCode());
-    EXPECT_EQ(metaState, keyEvent->getMetaState());
-    EXPECT_EQ(repeatCount, keyEvent->getRepeatCount());
-    EXPECT_EQ(downTime, keyEvent->getDownTime());
-    EXPECT_EQ(eventTime, keyEvent->getEventTime());
-
-    status = mConsumer->sendFinishedSignal(seq, true);
-    ASSERT_EQ(OK, status)
-            << "consumer sendFinishedSignal should return OK";
-
-    uint32_t finishedSeq = 0;
-    bool handled = false;
-    status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled);
-    ASSERT_EQ(OK, status)
-            << "publisher receiveFinishedSignal should return OK";
-    ASSERT_EQ(seq, finishedSeq)
-            << "publisher receiveFinishedSignal should have returned the original sequence number";
-    ASSERT_TRUE(handled)
-            << "publisher receiveFinishedSignal should have set handled to consumer's reply";
-}
-
-void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() {
-    status_t status;
-
-    const uint32_t seq = 15;
-    const int32_t deviceId = 1;
-    const int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
-    const int32_t action = AMOTION_EVENT_ACTION_MOVE;
-    const int32_t flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
-    const int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP;
-    const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
-    const int32_t buttonState = AMOTION_EVENT_BUTTON_PRIMARY;
-    const float xOffset = -10;
-    const float yOffset = -20;
-    const float xPrecision = 0.25;
-    const float yPrecision = 0.5;
-    const nsecs_t downTime = 3;
-    const size_t pointerCount = 3;
-    const nsecs_t eventTime = 4;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerProperties[i].clear();
-        pointerProperties[i].id = (i + 2) % pointerCount;
-        pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
-
-        pointerCoords[i].clear();
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, 100 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, 200 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.5 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 0.7 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 1.5 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 1.7 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.5 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.7 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 3.5 * i);
-    }
-
-    status = mPublisher->publishMotionEvent(seq, deviceId, source, action, flags, edgeFlags,
-            metaState, buttonState, xOffset, yOffset, xPrecision, yPrecision,
-            downTime, eventTime, pointerCount,
-            pointerProperties, pointerCoords);
-    ASSERT_EQ(OK, status)
-            << "publisher publishMotionEvent should return OK";
-
-    uint32_t consumeSeq;
-    InputEvent* event;
-    status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, &consumeSeq, &event);
-    ASSERT_EQ(OK, status)
-            << "consumer consume should return OK";
-
-    ASSERT_TRUE(event != NULL)
-            << "consumer should have returned non-NULL event";
-    ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
-            << "consumer should have returned a motion event";
-
-    MotionEvent* motionEvent = static_cast<MotionEvent*>(event);
-    EXPECT_EQ(seq, consumeSeq);
-    EXPECT_EQ(deviceId, motionEvent->getDeviceId());
-    EXPECT_EQ(source, motionEvent->getSource());
-    EXPECT_EQ(action, motionEvent->getAction());
-    EXPECT_EQ(flags, motionEvent->getFlags());
-    EXPECT_EQ(edgeFlags, motionEvent->getEdgeFlags());
-    EXPECT_EQ(metaState, motionEvent->getMetaState());
-    EXPECT_EQ(buttonState, motionEvent->getButtonState());
-    EXPECT_EQ(xPrecision, motionEvent->getXPrecision());
-    EXPECT_EQ(yPrecision, motionEvent->getYPrecision());
-    EXPECT_EQ(downTime, motionEvent->getDownTime());
-    EXPECT_EQ(eventTime, motionEvent->getEventTime());
-    EXPECT_EQ(pointerCount, motionEvent->getPointerCount());
-    EXPECT_EQ(0U, motionEvent->getHistorySize());
-
-    for (size_t i = 0; i < pointerCount; i++) {
-        SCOPED_TRACE(i);
-        EXPECT_EQ(pointerProperties[i].id, motionEvent->getPointerId(i));
-        EXPECT_EQ(pointerProperties[i].toolType, motionEvent->getToolType(i));
-
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
-                motionEvent->getRawX(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
-                motionEvent->getRawY(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset,
-                motionEvent->getX(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset,
-                motionEvent->getY(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
-                motionEvent->getPressure(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
-                motionEvent->getSize(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
-                motionEvent->getTouchMajor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
-                motionEvent->getTouchMinor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
-                motionEvent->getToolMajor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
-                motionEvent->getToolMinor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
-                motionEvent->getOrientation(i));
-    }
-
-    status = mConsumer->sendFinishedSignal(seq, false);
-    ASSERT_EQ(OK, status)
-            << "consumer sendFinishedSignal should return OK";
-
-    uint32_t finishedSeq = 0;
-    bool handled = true;
-    status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled);
-    ASSERT_EQ(OK, status)
-            << "publisher receiveFinishedSignal should return OK";
-    ASSERT_EQ(seq, finishedSeq)
-            << "publisher receiveFinishedSignal should have returned the original sequence number";
-    ASSERT_FALSE(handled)
-            << "publisher receiveFinishedSignal should have set handled to consumer's reply";
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishKeyEvent_EndToEnd) {
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_EndToEnd) {
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountLessThan1_ReturnsError) {
-    status_t status;
-    const size_t pointerCount = 0;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-
-    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            pointerCount, pointerProperties, pointerCoords);
-    ASSERT_EQ(BAD_VALUE, status)
-            << "publisher publishMotionEvent should return BAD_VALUE";
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountGreaterThanMax_ReturnsError) {
-    status_t status;
-    const size_t pointerCount = MAX_POINTERS + 1;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerProperties[i].clear();
-        pointerCoords[i].clear();
-    }
-
-    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            pointerCount, pointerProperties, pointerCoords);
-    ASSERT_EQ(BAD_VALUE, status)
-            << "publisher publishMotionEvent should return BAD_VALUE";
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishMultipleEvents_EndToEnd) {
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
-}
-
-} // namespace android
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index 24cf504..a96c8e6 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -18,9 +18,6 @@
 # and once for the device.
 
 commonSources:= \
-	Asset.cpp \
-	AssetDir.cpp \
-	AssetManager.cpp \
 	BasicHashtable.cpp \
 	BlobCache.cpp \
 	BufferedTextOutput.cpp \
@@ -29,14 +26,11 @@
 	FileMap.cpp \
 	Flattenable.cpp \
 	LinearTransform.cpp \
-	ObbFile.cpp \
 	PropertyMap.cpp \
 	RefBase.cpp \
-	ResourceTypes.cpp \
 	SharedBuffer.cpp \
 	Static.cpp \
 	StopWatch.cpp \
-	StreamingZipInflater.cpp \
 	String8.cpp \
 	String16.cpp \
 	StringArray.cpp \
@@ -47,9 +41,6 @@
 	Tokenizer.cpp \
 	Unicode.cpp \
 	VectorImpl.cpp \
-	ZipFileCRO.cpp \
-	ZipFileRO.cpp \
-	ZipUtils.cpp \
 	misc.cpp
 
 
@@ -63,7 +54,6 @@
 LOCAL_MODULE:= libutils
 
 LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS)
-LOCAL_C_INCLUDES += external/zlib
 
 ifeq ($(HOST_OS),windows)
 ifeq ($(strip $(USE_CYGWIN),),)
@@ -79,7 +69,6 @@
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 
-
 # For the device
 # =====================================================
 include $(CLEAR_VARS)
@@ -88,8 +77,6 @@
 # we have the common sources, plus some device-specific stuff
 LOCAL_SRC_FILES:= \
 	$(commonSources) \
-	BackupData.cpp \
-	BackupHelpers.cpp \
 	Looper.cpp
 
 ifeq ($(TARGET_OS),linux)
@@ -97,14 +84,11 @@
 endif
 
 LOCAL_C_INCLUDES += \
-		external/zlib \
-		external/icu4c/common \
 		bionic/libc/private
 
 LOCAL_LDLIBS += -lpthread
 
 LOCAL_SHARED_LIBRARIES := \
-	libz \
 	liblog \
 	libcutils \
 	libdl \
@@ -113,19 +97,6 @@
 LOCAL_MODULE:= libutils
 include $(BUILD_SHARED_LIBRARY)
 
-ifeq ($(TARGET_OS),linux)
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES += \
-		external/zlib \
-		external/icu4c/common \
-		bionic/libc/private
-LOCAL_LDLIBS := -lrt -ldl -lpthread
-LOCAL_MODULE := libutils
-LOCAL_SRC_FILES := $(commonSources) BackupData.cpp BackupHelpers.cpp
-include $(BUILD_STATIC_LIBRARY)
-endif
-
-
 # Include subdirectory makefiles
 # ============================================================
 
diff --git a/libs/utils/Asset.cpp b/libs/utils/Asset.cpp
deleted file mode 100644
index cb7628d..0000000
--- a/libs/utils/Asset.cpp
+++ /dev/null
@@ -1,897 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-// Provide access to a read-only asset.
-//
-
-#define LOG_TAG "asset"
-//#define NDEBUG 0
-
-#include <androidfw/Asset.h>
-#include <androidfw/StreamingZipInflater.h>
-#include <androidfw/ZipFileRO.h>
-#include <androidfw/ZipUtils.h>
-#include <utils/Atomic.h>
-#include <utils/FileMap.h>
-#include <utils/Log.h>
-#include <utils/threads.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <memory.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-using namespace android;
-
-#ifndef O_BINARY
-# define O_BINARY 0
-#endif
-
-static Mutex gAssetLock;
-static int32_t gCount = 0;
-static Asset* gHead = NULL;
-static Asset* gTail = NULL;
-
-int32_t Asset::getGlobalCount()
-{
-    AutoMutex _l(gAssetLock);
-    return gCount;
-}
-
-String8 Asset::getAssetAllocations()
-{
-    AutoMutex _l(gAssetLock);
-    String8 res;
-    Asset* cur = gHead;
-    while (cur != NULL) {
-        if (cur->isAllocated()) {
-            res.append("    ");
-            res.append(cur->getAssetSource());
-            off64_t size = (cur->getLength()+512)/1024;
-            char buf[64];
-            sprintf(buf, ": %dK\n", (int)size);
-            res.append(buf);
-        }
-        cur = cur->mNext;
-    }
-    
-    return res;
-}
-
-Asset::Asset(void)
-    : mAccessMode(ACCESS_UNKNOWN)
-{
-    AutoMutex _l(gAssetLock);
-    gCount++;
-    mNext = mPrev = NULL;
-    if (gTail == NULL) {
-        gHead = gTail = this;
-  	} else {
-  	    mPrev = gTail;
-  	    gTail->mNext = this;
-  	    gTail = this;
-  	}
-    //ALOGI("Creating Asset %p #%d\n", this, gCount);
-}
-
-Asset::~Asset(void)
-{
-    AutoMutex _l(gAssetLock);
-	gCount--;
-    if (gHead == this) {
-        gHead = mNext;
-    }
-    if (gTail == this) {
-        gTail = mPrev;
-    }
-    if (mNext != NULL) {
-        mNext->mPrev = mPrev;
-    }
-    if (mPrev != NULL) {
-        mPrev->mNext = mNext;
-    }
-    mNext = mPrev = NULL;
-    //ALOGI("Destroying Asset in %p #%d\n", this, gCount);
-}
-
-/*
- * Create a new Asset from a file on disk.  There is a fair chance that
- * the file doesn't actually exist.
- *
- * We can use "mode" to decide how we want to go about it.
- */
-/*static*/ Asset* Asset::createFromFile(const char* fileName, AccessMode mode)
-{
-    _FileAsset* pAsset;
-    status_t result;
-    off64_t length;
-    int fd;
-
-    fd = open(fileName, O_RDONLY | O_BINARY);
-    if (fd < 0)
-        return NULL;
-
-    /*
-     * Under Linux, the lseek fails if we actually opened a directory.  To
-     * be correct we should test the file type explicitly, but since we
-     * always open things read-only it doesn't really matter, so there's
-     * no value in incurring the extra overhead of an fstat() call.
-     */
-    // TODO(kroot): replace this with fstat despite the plea above.
-#if 1
-    length = lseek64(fd, 0, SEEK_END);
-    if (length < 0) {
-        ::close(fd);
-        return NULL;
-    }
-    (void) lseek64(fd, 0, SEEK_SET);
-#else
-    struct stat st;
-    if (fstat(fd, &st) < 0) {
-        ::close(fd);
-        return NULL;
-    }
-
-    if (!S_ISREG(st.st_mode)) {
-        ::close(fd);
-        return NULL;
-    }
-#endif
-
-    pAsset = new _FileAsset;
-    result = pAsset->openChunk(fileName, fd, 0, length);
-    if (result != NO_ERROR) {
-        delete pAsset;
-        return NULL;
-    }
-
-    pAsset->mAccessMode = mode;
-    return pAsset;
-}
-
-
-/*
- * Create a new Asset from a compressed file on disk.  There is a fair chance
- * that the file doesn't actually exist.
- *
- * We currently support gzip files.  We might want to handle .bz2 someday.
- */
-/*static*/ Asset* Asset::createFromCompressedFile(const char* fileName,
-    AccessMode mode)
-{
-    _CompressedAsset* pAsset;
-    status_t result;
-    off64_t fileLen;
-    bool scanResult;
-    long offset;
-    int method;
-    long uncompressedLen, compressedLen;
-    int fd;
-
-    fd = open(fileName, O_RDONLY | O_BINARY);
-    if (fd < 0)
-        return NULL;
-
-    fileLen = lseek(fd, 0, SEEK_END);
-    if (fileLen < 0) {
-        ::close(fd);
-        return NULL;
-    }
-    (void) lseek(fd, 0, SEEK_SET);
-
-    /* want buffered I/O for the file scan; must dup so fclose() is safe */
-    FILE* fp = fdopen(dup(fd), "rb");
-    if (fp == NULL) {
-        ::close(fd);
-        return NULL;
-    }
-
-    unsigned long crc32;
-    scanResult = ZipUtils::examineGzip(fp, &method, &uncompressedLen,
-                    &compressedLen, &crc32);
-    offset = ftell(fp);
-    fclose(fp);
-    if (!scanResult) {
-        ALOGD("File '%s' is not in gzip format\n", fileName);
-        ::close(fd);
-        return NULL;
-    }
-
-    pAsset = new _CompressedAsset;
-    result = pAsset->openChunk(fd, offset, method, uncompressedLen,
-                compressedLen);
-    if (result != NO_ERROR) {
-        delete pAsset;
-        return NULL;
-    }
-
-    pAsset->mAccessMode = mode;
-    return pAsset;
-}
-
-
-#if 0
-/*
- * Create a new Asset from part of an open file.
- */
-/*static*/ Asset* Asset::createFromFileSegment(int fd, off64_t offset,
-    size_t length, AccessMode mode)
-{
-    _FileAsset* pAsset;
-    status_t result;
-
-    pAsset = new _FileAsset;
-    result = pAsset->openChunk(NULL, fd, offset, length);
-    if (result != NO_ERROR)
-        return NULL;
-
-    pAsset->mAccessMode = mode;
-    return pAsset;
-}
-
-/*
- * Create a new Asset from compressed data in an open file.
- */
-/*static*/ Asset* Asset::createFromCompressedData(int fd, off64_t offset,
-    int compressionMethod, size_t uncompressedLen, size_t compressedLen,
-    AccessMode mode)
-{
-    _CompressedAsset* pAsset;
-    status_t result;
-
-    pAsset = new _CompressedAsset;
-    result = pAsset->openChunk(fd, offset, compressionMethod,
-                uncompressedLen, compressedLen);
-    if (result != NO_ERROR)
-        return NULL;
-
-    pAsset->mAccessMode = mode;
-    return pAsset;
-}
-#endif
-
-/*
- * Create a new Asset from a memory mapping.
- */
-/*static*/ Asset* Asset::createFromUncompressedMap(FileMap* dataMap,
-    AccessMode mode)
-{
-    _FileAsset* pAsset;
-    status_t result;
-
-    pAsset = new _FileAsset;
-    result = pAsset->openChunk(dataMap);
-    if (result != NO_ERROR)
-        return NULL;
-
-    pAsset->mAccessMode = mode;
-    return pAsset;
-}
-
-/*
- * Create a new Asset from compressed data in a memory mapping.
- */
-/*static*/ Asset* Asset::createFromCompressedMap(FileMap* dataMap,
-    int method, size_t uncompressedLen, AccessMode mode)
-{
-    _CompressedAsset* pAsset;
-    status_t result;
-
-    pAsset = new _CompressedAsset;
-    result = pAsset->openChunk(dataMap, method, uncompressedLen);
-    if (result != NO_ERROR)
-        return NULL;
-
-    pAsset->mAccessMode = mode;
-    return pAsset;
-}
-
-
-/*
- * Do generic seek() housekeeping.  Pass in the offset/whence values from
- * the seek request, along with the current chunk offset and the chunk
- * length.
- *
- * Returns the new chunk offset, or -1 if the seek is illegal.
- */
-off64_t Asset::handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn)
-{
-    off64_t newOffset;
-
-    switch (whence) {
-    case SEEK_SET:
-        newOffset = offset;
-        break;
-    case SEEK_CUR:
-        newOffset = curPosn + offset;
-        break;
-    case SEEK_END:
-        newOffset = maxPosn + offset;
-        break;
-    default:
-        ALOGW("unexpected whence %d\n", whence);
-        // this was happening due to an off64_t size mismatch
-        assert(false);
-        return (off64_t) -1;
-    }
-
-    if (newOffset < 0 || newOffset > maxPosn) {
-        ALOGW("seek out of range: want %ld, end=%ld\n",
-            (long) newOffset, (long) maxPosn);
-        return (off64_t) -1;
-    }
-
-    return newOffset;
-}
-
-
-/*
- * ===========================================================================
- *      _FileAsset
- * ===========================================================================
- */
-
-/*
- * Constructor.
- */
-_FileAsset::_FileAsset(void)
-    : mStart(0), mLength(0), mOffset(0), mFp(NULL), mFileName(NULL), mMap(NULL), mBuf(NULL)
-{
-}
-
-/*
- * Destructor.  Release resources.
- */
-_FileAsset::~_FileAsset(void)
-{
-    close();
-}
-
-/*
- * Operate on a chunk of an uncompressed file.
- *
- * Zero-length chunks are allowed.
- */
-status_t _FileAsset::openChunk(const char* fileName, int fd, off64_t offset, size_t length)
-{
-    assert(mFp == NULL);    // no reopen
-    assert(mMap == NULL);
-    assert(fd >= 0);
-    assert(offset >= 0);
-
-    /*
-     * Seek to end to get file length.
-     */
-    off64_t fileLength;
-    fileLength = lseek64(fd, 0, SEEK_END);
-    if (fileLength == (off64_t) -1) {
-        // probably a bad file descriptor
-        ALOGD("failed lseek (errno=%d)\n", errno);
-        return UNKNOWN_ERROR;
-    }
-
-    if ((off64_t) (offset + length) > fileLength) {
-        ALOGD("start (%ld) + len (%ld) > end (%ld)\n",
-            (long) offset, (long) length, (long) fileLength);
-        return BAD_INDEX;
-    }
-
-    /* after fdopen, the fd will be closed on fclose() */
-    mFp = fdopen(fd, "rb");
-    if (mFp == NULL)
-        return UNKNOWN_ERROR;
-
-    mStart = offset;
-    mLength = length;
-    assert(mOffset == 0);
-
-    /* seek the FILE* to the start of chunk */
-    if (fseek(mFp, mStart, SEEK_SET) != 0) {
-        assert(false);
-    }
-
-    mFileName = fileName != NULL ? strdup(fileName) : NULL;
-    
-    return NO_ERROR;
-}
-
-/*
- * Create the chunk from the map.
- */
-status_t _FileAsset::openChunk(FileMap* dataMap)
-{
-    assert(mFp == NULL);    // no reopen
-    assert(mMap == NULL);
-    assert(dataMap != NULL);
-
-    mMap = dataMap;
-    mStart = -1;            // not used
-    mLength = dataMap->getDataLength();
-    assert(mOffset == 0);
-
-    return NO_ERROR;
-}
-
-/*
- * Read a chunk of data.
- */
-ssize_t _FileAsset::read(void* buf, size_t count)
-{
-    size_t maxLen;
-    size_t actual;
-
-    assert(mOffset >= 0 && mOffset <= mLength);
-
-    if (getAccessMode() == ACCESS_BUFFER) {
-        /*
-         * On first access, read or map the entire file.  The caller has
-         * requested buffer access, either because they're going to be
-         * using the buffer or because what they're doing has appropriate
-         * performance needs and access patterns.
-         */
-        if (mBuf == NULL)
-            getBuffer(false);
-    }
-
-    /* adjust count if we're near EOF */
-    maxLen = mLength - mOffset;
-    if (count > maxLen)
-        count = maxLen;
-
-    if (!count)
-        return 0;
-
-    if (mMap != NULL) {
-        /* copy from mapped area */
-        //printf("map read\n");
-        memcpy(buf, (char*)mMap->getDataPtr() + mOffset, count);
-        actual = count;
-    } else if (mBuf != NULL) {
-        /* copy from buffer */
-        //printf("buf read\n");
-        memcpy(buf, (char*)mBuf + mOffset, count);
-        actual = count;
-    } else {
-        /* read from the file */
-        //printf("file read\n");
-        if (ftell(mFp) != mStart + mOffset) {
-            ALOGE("Hosed: %ld != %ld+%ld\n",
-                ftell(mFp), (long) mStart, (long) mOffset);
-            assert(false);
-        }
-
-        /*
-         * This returns 0 on error or eof.  We need to use ferror() or feof()
-         * to tell the difference, but we don't currently have those on the
-         * device.  However, we know how much data is *supposed* to be in the
-         * file, so if we don't read the full amount we know something is
-         * hosed.
-         */
-        actual = fread(buf, 1, count, mFp);
-        if (actual == 0)        // something failed -- I/O error?
-            return -1;
-
-        assert(actual == count);
-    }
-
-    mOffset += actual;
-    return actual;
-}
-
-/*
- * Seek to a new position.
- */
-off64_t _FileAsset::seek(off64_t offset, int whence)
-{
-    off64_t newPosn;
-    off64_t actualOffset;
-
-    // compute new position within chunk
-    newPosn = handleSeek(offset, whence, mOffset, mLength);
-    if (newPosn == (off64_t) -1)
-        return newPosn;
-
-    actualOffset = mStart + newPosn;
-
-    if (mFp != NULL) {
-        if (fseek(mFp, (long) actualOffset, SEEK_SET) != 0)
-            return (off64_t) -1;
-    }
-
-    mOffset = actualOffset - mStart;
-    return mOffset;
-}
-
-/*
- * Close the asset.
- */
-void _FileAsset::close(void)
-{
-    if (mMap != NULL) {
-        mMap->release();
-        mMap = NULL;
-    }
-    if (mBuf != NULL) {
-        delete[] mBuf;
-        mBuf = NULL;
-    }
-
-    if (mFileName != NULL) {
-        free(mFileName);
-        mFileName = NULL;
-    }
-    
-    if (mFp != NULL) {
-        // can only be NULL when called from destructor
-        // (otherwise we would never return this object)
-        fclose(mFp);
-        mFp = NULL;
-    }
-}
-
-/*
- * Return a read-only pointer to a buffer.
- *
- * We can either read the whole thing in or map the relevant piece of
- * the source file.  Ideally a map would be established at a higher
- * level and we'd be using a different object, but we didn't, so we
- * deal with it here.
- */
-const void* _FileAsset::getBuffer(bool wordAligned)
-{
-    /* subsequent requests just use what we did previously */
-    if (mBuf != NULL)
-        return mBuf;
-    if (mMap != NULL) {
-        if (!wordAligned) {
-            return  mMap->getDataPtr();
-        }
-        return ensureAlignment(mMap);
-    }
-
-    assert(mFp != NULL);
-
-    if (mLength < kReadVsMapThreshold) {
-        unsigned char* buf;
-        long allocLen;
-
-        /* zero-length files are allowed; not sure about zero-len allocs */
-        /* (works fine with gcc + x86linux) */
-        allocLen = mLength;
-        if (mLength == 0)
-            allocLen = 1;
-
-        buf = new unsigned char[allocLen];
-        if (buf == NULL) {
-            ALOGE("alloc of %ld bytes failed\n", (long) allocLen);
-            return NULL;
-        }
-
-        ALOGV("Asset %p allocating buffer size %d (smaller than threshold)", this, (int)allocLen);
-        if (mLength > 0) {
-            long oldPosn = ftell(mFp);
-            fseek(mFp, mStart, SEEK_SET);
-            if (fread(buf, 1, mLength, mFp) != (size_t) mLength) {
-                ALOGE("failed reading %ld bytes\n", (long) mLength);
-                delete[] buf;
-                return NULL;
-            }
-            fseek(mFp, oldPosn, SEEK_SET);
-        }
-
-        ALOGV(" getBuffer: loaded into buffer\n");
-
-        mBuf = buf;
-        return mBuf;
-    } else {
-        FileMap* map;
-
-        map = new FileMap;
-        if (!map->create(NULL, fileno(mFp), mStart, mLength, true)) {
-            map->release();
-            return NULL;
-        }
-
-        ALOGV(" getBuffer: mapped\n");
-
-        mMap = map;
-        if (!wordAligned) {
-            return  mMap->getDataPtr();
-        }
-        return ensureAlignment(mMap);
-    }
-}
-
-int _FileAsset::openFileDescriptor(off64_t* outStart, off64_t* outLength) const
-{
-    if (mMap != NULL) {
-        const char* fname = mMap->getFileName();
-        if (fname == NULL) {
-            fname = mFileName;
-        }
-        if (fname == NULL) {
-            return -1;
-        }
-        *outStart = mMap->getDataOffset();
-        *outLength = mMap->getDataLength();
-        return open(fname, O_RDONLY | O_BINARY);
-    }
-    if (mFileName == NULL) {
-        return -1;
-    }
-    *outStart = mStart;
-    *outLength = mLength;
-    return open(mFileName, O_RDONLY | O_BINARY);
-}
-
-const void* _FileAsset::ensureAlignment(FileMap* map)
-{
-    void* data = map->getDataPtr();
-    if ((((size_t)data)&0x3) == 0) {
-        // We can return this directly if it is aligned on a word
-        // boundary.
-        ALOGV("Returning aligned FileAsset %p (%s).", this,
-                getAssetSource());
-        return data;
-    }
-    // If not aligned on a word boundary, then we need to copy it into
-    // our own buffer.
-    ALOGV("Copying FileAsset %p (%s) to buffer size %d to make it aligned.", this,
-            getAssetSource(), (int)mLength);
-    unsigned char* buf = new unsigned char[mLength];
-    if (buf == NULL) {
-        ALOGE("alloc of %ld bytes failed\n", (long) mLength);
-        return NULL;
-    }
-    memcpy(buf, data, mLength);
-    mBuf = buf;
-    return buf;
-}
-
-/*
- * ===========================================================================
- *      _CompressedAsset
- * ===========================================================================
- */
-
-/*
- * Constructor.
- */
-_CompressedAsset::_CompressedAsset(void)
-    : mStart(0), mCompressedLen(0), mUncompressedLen(0), mOffset(0),
-      mMap(NULL), mFd(-1), mZipInflater(NULL), mBuf(NULL)
-{
-}
-
-/*
- * Destructor.  Release resources.
- */
-_CompressedAsset::~_CompressedAsset(void)
-{
-    close();
-}
-
-/*
- * Open a chunk of compressed data inside a file.
- *
- * This currently just sets up some values and returns.  On the first
- * read, we expand the entire file into a buffer and return data from it.
- */
-status_t _CompressedAsset::openChunk(int fd, off64_t offset,
-    int compressionMethod, size_t uncompressedLen, size_t compressedLen)
-{
-    assert(mFd < 0);        // no re-open
-    assert(mMap == NULL);
-    assert(fd >= 0);
-    assert(offset >= 0);
-    assert(compressedLen > 0);
-
-    if (compressionMethod != ZipFileRO::kCompressDeflated) {
-        assert(false);
-        return UNKNOWN_ERROR;
-    }
-
-    mStart = offset;
-    mCompressedLen = compressedLen;
-    mUncompressedLen = uncompressedLen;
-    assert(mOffset == 0);
-    mFd = fd;
-    assert(mBuf == NULL);
-
-    if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) {
-        mZipInflater = new StreamingZipInflater(mFd, offset, uncompressedLen, compressedLen);
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Open a chunk of compressed data in a mapped region.
- *
- * Nothing is expanded until the first read call.
- */
-status_t _CompressedAsset::openChunk(FileMap* dataMap, int compressionMethod,
-    size_t uncompressedLen)
-{
-    assert(mFd < 0);        // no re-open
-    assert(mMap == NULL);
-    assert(dataMap != NULL);
-
-    if (compressionMethod != ZipFileRO::kCompressDeflated) {
-        assert(false);
-        return UNKNOWN_ERROR;
-    }
-
-    mMap = dataMap;
-    mStart = -1;        // not used
-    mCompressedLen = dataMap->getDataLength();
-    mUncompressedLen = uncompressedLen;
-    assert(mOffset == 0);
-
-    if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) {
-        mZipInflater = new StreamingZipInflater(dataMap, uncompressedLen);
-    }
-    return NO_ERROR;
-}
-
-/*
- * Read data from a chunk of compressed data.
- *
- * [For now, that's just copying data out of a buffer.]
- */
-ssize_t _CompressedAsset::read(void* buf, size_t count)
-{
-    size_t maxLen;
-    size_t actual;
-
-    assert(mOffset >= 0 && mOffset <= mUncompressedLen);
-
-    /* If we're relying on a streaming inflater, go through that */
-    if (mZipInflater) {
-        actual = mZipInflater->read(buf, count);
-    } else {
-        if (mBuf == NULL) {
-            if (getBuffer(false) == NULL)
-                return -1;
-        }
-        assert(mBuf != NULL);
-
-        /* adjust count if we're near EOF */
-        maxLen = mUncompressedLen - mOffset;
-        if (count > maxLen)
-            count = maxLen;
-
-        if (!count)
-            return 0;
-
-        /* copy from buffer */
-        //printf("comp buf read\n");
-        memcpy(buf, (char*)mBuf + mOffset, count);
-        actual = count;
-    }
-
-    mOffset += actual;
-    return actual;
-}
-
-/*
- * Handle a seek request.
- *
- * If we're working in a streaming mode, this is going to be fairly
- * expensive, because it requires plowing through a bunch of compressed
- * data.
- */
-off64_t _CompressedAsset::seek(off64_t offset, int whence)
-{
-    off64_t newPosn;
-
-    // compute new position within chunk
-    newPosn = handleSeek(offset, whence, mOffset, mUncompressedLen);
-    if (newPosn == (off64_t) -1)
-        return newPosn;
-
-    if (mZipInflater) {
-        mZipInflater->seekAbsolute(newPosn);
-    }
-    mOffset = newPosn;
-    return mOffset;
-}
-
-/*
- * Close the asset.
- */
-void _CompressedAsset::close(void)
-{
-    if (mMap != NULL) {
-        mMap->release();
-        mMap = NULL;
-    }
-
-    delete[] mBuf;
-    mBuf = NULL;
-
-    delete mZipInflater;
-    mZipInflater = NULL;
-
-    if (mFd > 0) {
-        ::close(mFd);
-        mFd = -1;
-    }
-}
-
-/*
- * Get a pointer to a read-only buffer of data.
- *
- * The first time this is called, we expand the compressed data into a
- * buffer.
- */
-const void* _CompressedAsset::getBuffer(bool wordAligned)
-{
-    unsigned char* buf = NULL;
-
-    if (mBuf != NULL)
-        return mBuf;
-
-    /*
-     * Allocate a buffer and read the file into it.
-     */
-    buf = new unsigned char[mUncompressedLen];
-    if (buf == NULL) {
-        ALOGW("alloc %ld bytes failed\n", (long) mUncompressedLen);
-        goto bail;
-    }
-
-    if (mMap != NULL) {
-        if (!ZipFileRO::inflateBuffer(buf, mMap->getDataPtr(),
-                mUncompressedLen, mCompressedLen))
-            goto bail;
-    } else {
-        assert(mFd >= 0);
-
-        /*
-         * Seek to the start of the compressed data.
-         */
-        if (lseek(mFd, mStart, SEEK_SET) != mStart)
-            goto bail;
-
-        /*
-         * Expand the data into it.
-         */
-        if (!ZipUtils::inflateToBuffer(mFd, buf, mUncompressedLen,
-                mCompressedLen))
-            goto bail;
-    }
-
-    /*
-     * Success - now that we have the full asset in RAM we
-     * no longer need the streaming inflater
-     */
-    delete mZipInflater;
-    mZipInflater = NULL;
-
-    mBuf = buf;
-    buf = NULL;
-
-bail:
-    delete[] buf;
-    return mBuf;
-}
-
diff --git a/libs/utils/AssetDir.cpp b/libs/utils/AssetDir.cpp
deleted file mode 100644
index 475f521..0000000
--- a/libs/utils/AssetDir.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-// Provide access to a virtual directory in "asset space".  Most of the
-// implementation is in the header file or in friend functions in
-// AssetManager.
-//
-#include <androidfw/AssetDir.h>
-
-using namespace android;
-
-
-/*
- * Find a matching entry in a vector of FileInfo.  Because it's sorted, we
- * can use a binary search.
- *
- * Assumes the vector is sorted in ascending order.
- */
-/*static*/ int AssetDir::FileInfo::findEntry(const SortedVector<FileInfo>* pVector,
-    const String8& fileName)
-{
-    FileInfo tmpInfo;
-
-    tmpInfo.setFileName(fileName);
-    return pVector->indexOf(tmpInfo);
-
-#if 0  // don't need this after all (uses 1/2 compares of SortedVector though)
-    int lo, hi, cur;
-
-    lo = 0;
-    hi = pVector->size() -1;
-    while (lo <= hi) {
-        int cmp;
-
-        cur = (hi + lo) / 2;
-        cmp = strcmp(pVector->itemAt(cur).getFileName(), fileName);
-        if (cmp == 0) {
-            /* match, bail */
-            return cur;
-        } else if (cmp < 0) {
-            /* too low */
-            lo = cur + 1;
-        } else {
-            /* too high */
-            hi = cur -1;
-        }
-    }
-
-    return -1;
-#endif
-}
-
diff --git a/libs/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp
deleted file mode 100644
index 4829add..0000000
--- a/libs/utils/AssetManager.cpp
+++ /dev/null
@@ -1,2001 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-// Provide access to read-only assets.
-//
-
-#define LOG_TAG "asset"
-//#define LOG_NDEBUG 0
-
-#include <androidfw/Asset.h>
-#include <androidfw/AssetDir.h>
-#include <androidfw/AssetManager.h>
-#include <androidfw/ResourceTypes.h>
-#include <androidfw/ZipFileRO.h>
-#include <utils/Atomic.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-#include <utils/Timers.h>
-
-#include <assert.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <strings.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#ifndef TEMP_FAILURE_RETRY
-/* Used to retry syscalls that can return EINTR. */
-#define TEMP_FAILURE_RETRY(exp) ({         \
-    typeof (exp) _rc;                      \
-    do {                                   \
-        _rc = (exp);                       \
-    } while (_rc == -1 && errno == EINTR); \
-    _rc; })
-#endif
-
-using namespace android;
-
-/*
- * Names for default app, locale, and vendor.  We might want to change
- * these to be an actual locale, e.g. always use en-US as the default.
- */
-static const char* kDefaultLocale = "default";
-static const char* kDefaultVendor = "default";
-static const char* kAssetsRoot = "assets";
-static const char* kAppZipName = NULL; //"classes.jar";
-static const char* kSystemAssets = "framework/framework-res.apk";
-static const char* kIdmapCacheDir = "resource-cache";
-
-static const char* kExcludeExtension = ".EXCLUDE";
-
-static Asset* const kExcludedAsset = (Asset*) 0xd000000d;
-
-static volatile int32_t gCount = 0;
-
-namespace {
-    // Transform string /a/b/c.apk to /data/resource-cache/a@b@c.apk@idmap
-    String8 idmapPathForPackagePath(const String8& pkgPath)
-    {
-        const char* root = getenv("ANDROID_DATA");
-        LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_DATA not set");
-        String8 path(root);
-        path.appendPath(kIdmapCacheDir);
-
-        char buf[256]; // 256 chars should be enough for anyone...
-        strncpy(buf, pkgPath.string(), 255);
-        buf[255] = '\0';
-        char* filename = buf;
-        while (*filename && *filename == '/') {
-            ++filename;
-        }
-        char* p = filename;
-        while (*p) {
-            if (*p == '/') {
-                *p = '@';
-            }
-            ++p;
-        }
-        path.appendPath(filename);
-        path.append("@idmap");
-
-        return path;
-    }
-}
-
-/*
- * ===========================================================================
- *      AssetManager
- * ===========================================================================
- */
-
-int32_t AssetManager::getGlobalCount()
-{
-    return gCount;
-}
-
-AssetManager::AssetManager(CacheMode cacheMode)
-    : mLocale(NULL), mVendor(NULL),
-      mResources(NULL), mConfig(new ResTable_config),
-      mCacheMode(cacheMode), mCacheValid(false)
-{
-    int count = android_atomic_inc(&gCount)+1;
-    //ALOGI("Creating AssetManager %p #%d\n", this, count);
-    memset(mConfig, 0, sizeof(ResTable_config));
-}
-
-AssetManager::~AssetManager(void)
-{
-    int count = android_atomic_dec(&gCount);
-    //ALOGI("Destroying AssetManager in %p #%d\n", this, count);
-
-    delete mConfig;
-    delete mResources;
-
-    // don't have a String class yet, so make sure we clean up
-    delete[] mLocale;
-    delete[] mVendor;
-}
-
-bool AssetManager::addAssetPath(const String8& path, void** cookie)
-{
-    AutoMutex _l(mLock);
-
-    asset_path ap;
-
-    String8 realPath(path);
-    if (kAppZipName) {
-        realPath.appendPath(kAppZipName);
-    }
-    ap.type = ::getFileType(realPath.string());
-    if (ap.type == kFileTypeRegular) {
-        ap.path = realPath;
-    } else {
-        ap.path = path;
-        ap.type = ::getFileType(path.string());
-        if (ap.type != kFileTypeDirectory && ap.type != kFileTypeRegular) {
-            ALOGW("Asset path %s is neither a directory nor file (type=%d).",
-                 path.string(), (int)ap.type);
-            return false;
-        }
-    }
-
-    // Skip if we have it already.
-    for (size_t i=0; i<mAssetPaths.size(); i++) {
-        if (mAssetPaths[i].path == ap.path) {
-            if (cookie) {
-                *cookie = (void*)(i+1);
-            }
-            return true;
-        }
-    }
-
-    ALOGV("In %p Asset %s path: %s", this,
-         ap.type == kFileTypeDirectory ? "dir" : "zip", ap.path.string());
-
-    mAssetPaths.add(ap);
-
-    // new paths are always added at the end
-    if (cookie) {
-        *cookie = (void*)mAssetPaths.size();
-    }
-
-    // add overlay packages for /system/framework; apps are handled by the
-    // (Java) package manager
-    if (strncmp(path.string(), "/system/framework/", 18) == 0) {
-        // When there is an environment variable for /vendor, this
-        // should be changed to something similar to how ANDROID_ROOT
-        // and ANDROID_DATA are used in this file.
-        String8 overlayPath("/vendor/overlay/framework/");
-        overlayPath.append(path.getPathLeaf());
-        if (TEMP_FAILURE_RETRY(access(overlayPath.string(), R_OK)) == 0) {
-            asset_path oap;
-            oap.path = overlayPath;
-            oap.type = ::getFileType(overlayPath.string());
-            bool addOverlay = (oap.type == kFileTypeRegular); // only .apks supported as overlay
-            if (addOverlay) {
-                oap.idmap = idmapPathForPackagePath(overlayPath);
-
-                if (isIdmapStaleLocked(ap.path, oap.path, oap.idmap)) {
-                    addOverlay = createIdmapFileLocked(ap.path, oap.path, oap.idmap);
-                }
-            }
-            if (addOverlay) {
-                mAssetPaths.add(oap);
-            } else {
-                ALOGW("failed to add overlay package %s\n", overlayPath.string());
-            }
-        }
-    }
-
-    return true;
-}
-
-bool AssetManager::isIdmapStaleLocked(const String8& originalPath, const String8& overlayPath,
-                                      const String8& idmapPath)
-{
-    struct stat st;
-    if (TEMP_FAILURE_RETRY(stat(idmapPath.string(), &st)) == -1) {
-        if (errno == ENOENT) {
-            return true; // non-existing idmap is always stale
-        } else {
-            ALOGW("failed to stat file %s: %s\n", idmapPath.string(), strerror(errno));
-            return false;
-        }
-    }
-    if (st.st_size < ResTable::IDMAP_HEADER_SIZE_BYTES) {
-        ALOGW("file %s has unexpectedly small size=%zd\n", idmapPath.string(), (size_t)st.st_size);
-        return false;
-    }
-    int fd = TEMP_FAILURE_RETRY(::open(idmapPath.string(), O_RDONLY));
-    if (fd == -1) {
-        ALOGW("failed to open file %s: %s\n", idmapPath.string(), strerror(errno));
-        return false;
-    }
-    char buf[ResTable::IDMAP_HEADER_SIZE_BYTES];
-    ssize_t bytesLeft = ResTable::IDMAP_HEADER_SIZE_BYTES;
-    for (;;) {
-        ssize_t r = TEMP_FAILURE_RETRY(read(fd, buf + ResTable::IDMAP_HEADER_SIZE_BYTES - bytesLeft,
-                                            bytesLeft));
-        if (r < 0) {
-            TEMP_FAILURE_RETRY(close(fd));
-            return false;
-        }
-        bytesLeft -= r;
-        if (bytesLeft == 0) {
-            break;
-        }
-    }
-    TEMP_FAILURE_RETRY(close(fd));
-
-    uint32_t cachedOriginalCrc, cachedOverlayCrc;
-    if (!ResTable::getIdmapInfo(buf, ResTable::IDMAP_HEADER_SIZE_BYTES,
-                                &cachedOriginalCrc, &cachedOverlayCrc)) {
-        return false;
-    }
-
-    uint32_t actualOriginalCrc, actualOverlayCrc;
-    if (!getZipEntryCrcLocked(originalPath, "resources.arsc", &actualOriginalCrc)) {
-        return false;
-    }
-    if (!getZipEntryCrcLocked(overlayPath, "resources.arsc", &actualOverlayCrc)) {
-        return false;
-    }
-    return cachedOriginalCrc != actualOriginalCrc || cachedOverlayCrc != actualOverlayCrc;
-}
-
-bool AssetManager::getZipEntryCrcLocked(const String8& zipPath, const char* entryFilename,
-                                        uint32_t* pCrc)
-{
-    asset_path ap;
-    ap.path = zipPath;
-    const ZipFileRO* zip = getZipFileLocked(ap);
-    if (zip == NULL) {
-        return false;
-    }
-    const ZipEntryRO entry = zip->findEntryByName(entryFilename);
-    if (entry == NULL) {
-        return false;
-    }
-    if (!zip->getEntryInfo(entry, NULL, NULL, NULL, NULL, NULL, (long*)pCrc)) {
-        return false;
-    }
-    return true;
-}
-
-bool AssetManager::createIdmapFileLocked(const String8& originalPath, const String8& overlayPath,
-                                         const String8& idmapPath)
-{
-    ALOGD("%s: originalPath=%s overlayPath=%s idmapPath=%s\n",
-         __FUNCTION__, originalPath.string(), overlayPath.string(), idmapPath.string());
-    ResTable tables[2];
-    const String8* paths[2] = { &originalPath, &overlayPath };
-    uint32_t originalCrc, overlayCrc;
-    bool retval = false;
-    ssize_t offset = 0;
-    int fd = 0;
-    uint32_t* data = NULL;
-    size_t size;
-
-    for (int i = 0; i < 2; ++i) {
-        asset_path ap;
-        ap.type = kFileTypeRegular;
-        ap.path = *paths[i];
-        Asset* ass = openNonAssetInPathLocked("resources.arsc", Asset::ACCESS_BUFFER, ap);
-        if (ass == NULL) {
-            ALOGW("failed to find resources.arsc in %s\n", ap.path.string());
-            goto error;
-        }
-        tables[i].add(ass, (void*)1, false);
-    }
-
-    if (!getZipEntryCrcLocked(originalPath, "resources.arsc", &originalCrc)) {
-        ALOGW("failed to retrieve crc for resources.arsc in %s\n", originalPath.string());
-        goto error;
-    }
-    if (!getZipEntryCrcLocked(overlayPath, "resources.arsc", &overlayCrc)) {
-        ALOGW("failed to retrieve crc for resources.arsc in %s\n", overlayPath.string());
-        goto error;
-    }
-
-    if (tables[0].createIdmap(tables[1], originalCrc, overlayCrc,
-                              (void**)&data, &size) != NO_ERROR) {
-        ALOGW("failed to generate idmap data for file %s\n", idmapPath.string());
-        goto error;
-    }
-
-    // This should be abstracted (eg replaced by a stand-alone
-    // application like dexopt, triggered by something equivalent to
-    // installd).
-    fd = TEMP_FAILURE_RETRY(::open(idmapPath.string(), O_WRONLY | O_CREAT | O_TRUNC, 0644));
-    if (fd == -1) {
-        ALOGW("failed to write idmap file %s (open: %s)\n", idmapPath.string(), strerror(errno));
-        goto error_free;
-    }
-    for (;;) {
-        ssize_t written = TEMP_FAILURE_RETRY(write(fd, data + offset, size));
-        if (written < 0) {
-            ALOGW("failed to write idmap file %s (write: %s)\n", idmapPath.string(),
-                 strerror(errno));
-            goto error_close;
-        }
-        size -= (size_t)written;
-        offset += written;
-        if (size == 0) {
-            break;
-        }
-    }
-
-    retval = true;
-error_close:
-    TEMP_FAILURE_RETRY(close(fd));
-error_free:
-    free(data);
-error:
-    return retval;
-}
-
-bool AssetManager::addDefaultAssets()
-{
-    const char* root = getenv("ANDROID_ROOT");
-    LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_ROOT not set");
-
-    String8 path(root);
-    path.appendPath(kSystemAssets);
-
-    return addAssetPath(path, NULL);
-}
-
-void* AssetManager::nextAssetPath(void* cookie) const
-{
-    AutoMutex _l(mLock);
-    size_t next = ((size_t)cookie)+1;
-    return next > mAssetPaths.size() ? NULL : (void*)next;
-}
-
-String8 AssetManager::getAssetPath(void* cookie) const
-{
-    AutoMutex _l(mLock);
-    const size_t which = ((size_t)cookie)-1;
-    if (which < mAssetPaths.size()) {
-        return mAssetPaths[which].path;
-    }
-    return String8();
-}
-
-/*
- * Set the current locale.  Use NULL to indicate no locale.
- *
- * Close and reopen Zip archives as appropriate, and reset cached
- * information in the locale-specific sections of the tree.
- */
-void AssetManager::setLocale(const char* locale)
-{
-    AutoMutex _l(mLock);
-    setLocaleLocked(locale);
-}
-
-void AssetManager::setLocaleLocked(const char* locale)
-{
-    if (mLocale != NULL) {
-        /* previously set, purge cached data */
-        purgeFileNameCacheLocked();
-        //mZipSet.purgeLocale();
-        delete[] mLocale;
-    }
-    mLocale = strdupNew(locale);
-    
-    updateResourceParamsLocked();
-}
-
-/*
- * Set the current vendor.  Use NULL to indicate no vendor.
- *
- * Close and reopen Zip archives as appropriate, and reset cached
- * information in the vendor-specific sections of the tree.
- */
-void AssetManager::setVendor(const char* vendor)
-{
-    AutoMutex _l(mLock);
-
-    if (mVendor != NULL) {
-        /* previously set, purge cached data */
-        purgeFileNameCacheLocked();
-        //mZipSet.purgeVendor();
-        delete[] mVendor;
-    }
-    mVendor = strdupNew(vendor);
-}
-
-void AssetManager::setConfiguration(const ResTable_config& config, const char* locale)
-{
-    AutoMutex _l(mLock);
-    *mConfig = config;
-    if (locale) {
-        setLocaleLocked(locale);
-    } else if (config.language[0] != 0) {
-        char spec[9];
-        spec[0] = config.language[0];
-        spec[1] = config.language[1];
-        if (config.country[0] != 0) {
-            spec[2] = '_';
-            spec[3] = config.country[0];
-            spec[4] = config.country[1];
-            spec[5] = 0;
-        } else {
-            spec[3] = 0;
-        }
-        setLocaleLocked(spec);
-    } else {
-        updateResourceParamsLocked();
-    }
-}
-
-void AssetManager::getConfiguration(ResTable_config* outConfig) const
-{
-    AutoMutex _l(mLock);
-    *outConfig = *mConfig;
-}
-
-/*
- * Open an asset.
- *
- * The data could be;
- *  - In a file on disk (assetBase + fileName).
- *  - In a compressed file on disk (assetBase + fileName.gz).
- *  - In a Zip archive, uncompressed or compressed.
- *
- * It can be in a number of different directories and Zip archives.
- * The search order is:
- *  - [appname]
- *    - locale + vendor
- *    - "default" + vendor
- *    - locale + "default"
- *    - "default + "default"
- *  - "common"
- *    - (same as above)
- *
- * To find a particular file, we have to try up to eight paths with
- * all three forms of data.
- *
- * We should probably reject requests for "illegal" filenames, e.g. those
- * with illegal characters or "../" backward relative paths.
- */
-Asset* AssetManager::open(const char* fileName, AccessMode mode)
-{
-    AutoMutex _l(mLock);
-
-    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-
-
-    if (mCacheMode != CACHE_OFF && !mCacheValid)
-        loadFileNameCacheLocked();
-
-    String8 assetName(kAssetsRoot);
-    assetName.appendPath(fileName);
-
-    /*
-     * For each top-level asset path, search for the asset.
-     */
-
-    size_t i = mAssetPaths.size();
-    while (i > 0) {
-        i--;
-        ALOGV("Looking for asset '%s' in '%s'\n",
-                assetName.string(), mAssetPaths.itemAt(i).path.string());
-        Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, mAssetPaths.itemAt(i));
-        if (pAsset != NULL) {
-            return pAsset != kExcludedAsset ? pAsset : NULL;
-        }
-    }
-
-    return NULL;
-}
-
-/*
- * Open a non-asset file as if it were an asset.
- *
- * The "fileName" is the partial path starting from the application
- * name.
- */
-Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode)
-{
-    AutoMutex _l(mLock);
-
-    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-
-
-    if (mCacheMode != CACHE_OFF && !mCacheValid)
-        loadFileNameCacheLocked();
-
-    /*
-     * For each top-level asset path, search for the asset.
-     */
-
-    size_t i = mAssetPaths.size();
-    while (i > 0) {
-        i--;
-        ALOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.string());
-        Asset* pAsset = openNonAssetInPathLocked(
-            fileName, mode, mAssetPaths.itemAt(i));
-        if (pAsset != NULL) {
-            return pAsset != kExcludedAsset ? pAsset : NULL;
-        }
-    }
-
-    return NULL;
-}
-
-Asset* AssetManager::openNonAsset(void* cookie, const char* fileName, AccessMode mode)
-{
-    const size_t which = ((size_t)cookie)-1;
-
-    AutoMutex _l(mLock);
-
-    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-
-
-    if (mCacheMode != CACHE_OFF && !mCacheValid)
-        loadFileNameCacheLocked();
-
-    if (which < mAssetPaths.size()) {
-        ALOGV("Looking for non-asset '%s' in '%s'\n", fileName,
-                mAssetPaths.itemAt(which).path.string());
-        Asset* pAsset = openNonAssetInPathLocked(
-            fileName, mode, mAssetPaths.itemAt(which));
-        if (pAsset != NULL) {
-            return pAsset != kExcludedAsset ? pAsset : NULL;
-        }
-    }
-
-    return NULL;
-}
-
-/*
- * Get the type of a file in the asset namespace.
- *
- * This currently only works for regular files.  All others (including
- * directories) will return kFileTypeNonexistent.
- */
-FileType AssetManager::getFileType(const char* fileName)
-{
-    Asset* pAsset = NULL;
-
-    /*
-     * Open the asset.  This is less efficient than simply finding the
-     * file, but it's not too bad (we don't uncompress or mmap data until
-     * the first read() call).
-     */
-    pAsset = open(fileName, Asset::ACCESS_STREAMING);
-    delete pAsset;
-
-    if (pAsset == NULL)
-        return kFileTypeNonexistent;
-    else
-        return kFileTypeRegular;
-}
-
-const ResTable* AssetManager::getResTable(bool required) const
-{
-    ResTable* rt = mResources;
-    if (rt) {
-        return rt;
-    }
-
-    // Iterate through all asset packages, collecting resources from each.
-
-    AutoMutex _l(mLock);
-
-    if (mResources != NULL) {
-        return mResources;
-    }
-
-    if (required) {
-        LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-    }
-
-    if (mCacheMode != CACHE_OFF && !mCacheValid)
-        const_cast<AssetManager*>(this)->loadFileNameCacheLocked();
-
-    const size_t N = mAssetPaths.size();
-    for (size_t i=0; i<N; i++) {
-        Asset* ass = NULL;
-        ResTable* sharedRes = NULL;
-        bool shared = true;
-        const asset_path& ap = mAssetPaths.itemAt(i);
-        Asset* idmap = openIdmapLocked(ap);
-        ALOGV("Looking for resource asset in '%s'\n", ap.path.string());
-        if (ap.type != kFileTypeDirectory) {
-            if (i == 0) {
-                // The first item is typically the framework resources,
-                // which we want to avoid parsing every time.
-                sharedRes = const_cast<AssetManager*>(this)->
-                    mZipSet.getZipResourceTable(ap.path);
-            }
-            if (sharedRes == NULL) {
-                ass = const_cast<AssetManager*>(this)->
-                    mZipSet.getZipResourceTableAsset(ap.path);
-                if (ass == NULL) {
-                    ALOGV("loading resource table %s\n", ap.path.string());
-                    ass = const_cast<AssetManager*>(this)->
-                        openNonAssetInPathLocked("resources.arsc",
-                                                 Asset::ACCESS_BUFFER,
-                                                 ap);
-                    if (ass != NULL && ass != kExcludedAsset) {
-                        ass = const_cast<AssetManager*>(this)->
-                            mZipSet.setZipResourceTableAsset(ap.path, ass);
-                    }
-                }
-                
-                if (i == 0 && ass != NULL) {
-                    // If this is the first resource table in the asset
-                    // manager, then we are going to cache it so that we
-                    // can quickly copy it out for others.
-                    ALOGV("Creating shared resources for %s", ap.path.string());
-                    sharedRes = new ResTable();
-                    sharedRes->add(ass, (void*)(i+1), false, idmap);
-                    sharedRes = const_cast<AssetManager*>(this)->
-                        mZipSet.setZipResourceTable(ap.path, sharedRes);
-                }
-            }
-        } else {
-            ALOGV("loading resource table %s\n", ap.path.string());
-            Asset* ass = const_cast<AssetManager*>(this)->
-                openNonAssetInPathLocked("resources.arsc",
-                                         Asset::ACCESS_BUFFER,
-                                         ap);
-            shared = false;
-        }
-        if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) {
-            if (rt == NULL) {
-                mResources = rt = new ResTable();
-                updateResourceParamsLocked();
-            }
-            ALOGV("Installing resource asset %p in to table %p\n", ass, mResources);
-            if (sharedRes != NULL) {
-                ALOGV("Copying existing resources for %s", ap.path.string());
-                rt->add(sharedRes);
-            } else {
-                ALOGV("Parsing resources for %s", ap.path.string());
-                rt->add(ass, (void*)(i+1), !shared, idmap);
-            }
-
-            if (!shared) {
-                delete ass;
-            }
-        }
-        if (idmap != NULL) {
-            delete idmap;
-        }
-    }
-
-    if (required && !rt) ALOGW("Unable to find resources file resources.arsc");
-    if (!rt) {
-        mResources = rt = new ResTable();
-    }
-    return rt;
-}
-
-void AssetManager::updateResourceParamsLocked() const
-{
-    ResTable* res = mResources;
-    if (!res) {
-        return;
-    }
-
-    size_t llen = mLocale ? strlen(mLocale) : 0;
-    mConfig->language[0] = 0;
-    mConfig->language[1] = 0;
-    mConfig->country[0] = 0;
-    mConfig->country[1] = 0;
-    if (llen >= 2) {
-        mConfig->language[0] = mLocale[0];
-        mConfig->language[1] = mLocale[1];
-    }
-    if (llen >= 5) {
-        mConfig->country[0] = mLocale[3];
-        mConfig->country[1] = mLocale[4];
-    }
-    mConfig->size = sizeof(*mConfig);
-
-    res->setParameters(mConfig);
-}
-
-Asset* AssetManager::openIdmapLocked(const struct asset_path& ap) const
-{
-    Asset* ass = NULL;
-    if (ap.idmap.size() != 0) {
-        ass = const_cast<AssetManager*>(this)->
-            openAssetFromFileLocked(ap.idmap, Asset::ACCESS_BUFFER);
-        if (ass) {
-            ALOGV("loading idmap %s\n", ap.idmap.string());
-        } else {
-            ALOGW("failed to load idmap %s\n", ap.idmap.string());
-        }
-    }
-    return ass;
-}
-
-const ResTable& AssetManager::getResources(bool required) const
-{
-    const ResTable* rt = getResTable(required);
-    return *rt;
-}
-
-bool AssetManager::isUpToDate()
-{
-    AutoMutex _l(mLock);
-    return mZipSet.isUpToDate();
-}
-
-void AssetManager::getLocales(Vector<String8>* locales) const
-{
-    ResTable* res = mResources;
-    if (res != NULL) {
-        res->getLocales(locales);
-    }
-}
-
-/*
- * Open a non-asset file as if it were an asset, searching for it in the
- * specified app.
- *
- * Pass in a NULL values for "appName" if the common app directory should
- * be used.
- */
-Asset* AssetManager::openNonAssetInPathLocked(const char* fileName, AccessMode mode,
-    const asset_path& ap)
-{
-    Asset* pAsset = NULL;
-
-    /* look at the filesystem on disk */
-    if (ap.type == kFileTypeDirectory) {
-        String8 path(ap.path);
-        path.appendPath(fileName);
-
-        pAsset = openAssetFromFileLocked(path, mode);
-
-        if (pAsset == NULL) {
-            /* try again, this time with ".gz" */
-            path.append(".gz");
-            pAsset = openAssetFromFileLocked(path, mode);
-        }
-
-        if (pAsset != NULL) {
-            //printf("FOUND NA '%s' on disk\n", fileName);
-            pAsset->setAssetSource(path);
-        }
-
-    /* look inside the zip file */
-    } else {
-        String8 path(fileName);
-
-        /* check the appropriate Zip file */
-        ZipFileRO* pZip;
-        ZipEntryRO entry;
-
-        pZip = getZipFileLocked(ap);
-        if (pZip != NULL) {
-            //printf("GOT zip, checking NA '%s'\n", (const char*) path);
-            entry = pZip->findEntryByName(path.string());
-            if (entry != NULL) {
-                //printf("FOUND NA in Zip file for %s\n", appName ? appName : kAppCommon);
-                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
-            }
-        }
-
-        if (pAsset != NULL) {
-            /* create a "source" name, for debug/display */
-            pAsset->setAssetSource(
-                    createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()), String8(""),
-                                                String8(fileName)));
-        }
-    }
-
-    return pAsset;
-}
-
-/*
- * Open an asset, searching for it in the directory hierarchy for the
- * specified app.
- *
- * Pass in a NULL values for "appName" if the common app directory should
- * be used.
- */
-Asset* AssetManager::openInPathLocked(const char* fileName, AccessMode mode,
-    const asset_path& ap)
-{
-    Asset* pAsset = NULL;
-
-    /*
-     * Try various combinations of locale and vendor.
-     */
-    if (mLocale != NULL && mVendor != NULL)
-        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, mVendor);
-    if (pAsset == NULL && mVendor != NULL)
-        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, mVendor);
-    if (pAsset == NULL && mLocale != NULL)
-        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, NULL);
-    if (pAsset == NULL)
-        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, NULL);
-
-    return pAsset;
-}
-
-/*
- * Open an asset, searching for it in the directory hierarchy for the
- * specified locale and vendor.
- *
- * We also search in "app.jar".
- *
- * Pass in NULL values for "appName", "locale", and "vendor" if the
- * defaults should be used.
- */
-Asset* AssetManager::openInLocaleVendorLocked(const char* fileName, AccessMode mode,
-    const asset_path& ap, const char* locale, const char* vendor)
-{
-    Asset* pAsset = NULL;
-
-    if (ap.type == kFileTypeDirectory) {
-        if (mCacheMode == CACHE_OFF) {
-            /* look at the filesystem on disk */
-            String8 path(createPathNameLocked(ap, locale, vendor));
-            path.appendPath(fileName);
-    
-            String8 excludeName(path);
-            excludeName.append(kExcludeExtension);
-            if (::getFileType(excludeName.string()) != kFileTypeNonexistent) {
-                /* say no more */
-                //printf("+++ excluding '%s'\n", (const char*) excludeName);
-                return kExcludedAsset;
-            }
-    
-            pAsset = openAssetFromFileLocked(path, mode);
-    
-            if (pAsset == NULL) {
-                /* try again, this time with ".gz" */
-                path.append(".gz");
-                pAsset = openAssetFromFileLocked(path, mode);
-            }
-    
-            if (pAsset != NULL)
-                pAsset->setAssetSource(path);
-        } else {
-            /* find in cache */
-            String8 path(createPathNameLocked(ap, locale, vendor));
-            path.appendPath(fileName);
-    
-            AssetDir::FileInfo tmpInfo;
-            bool found = false;
-    
-            String8 excludeName(path);
-            excludeName.append(kExcludeExtension);
-    
-            if (mCache.indexOf(excludeName) != NAME_NOT_FOUND) {
-                /* go no farther */
-                //printf("+++ Excluding '%s'\n", (const char*) excludeName);
-                return kExcludedAsset;
-            }
-
-            /*
-             * File compression extensions (".gz") don't get stored in the
-             * name cache, so we have to try both here.
-             */
-            if (mCache.indexOf(path) != NAME_NOT_FOUND) {
-                found = true;
-                pAsset = openAssetFromFileLocked(path, mode);
-                if (pAsset == NULL) {
-                    /* try again, this time with ".gz" */
-                    path.append(".gz");
-                    pAsset = openAssetFromFileLocked(path, mode);
-                }
-            }
-
-            if (pAsset != NULL)
-                pAsset->setAssetSource(path);
-
-            /*
-             * Don't continue the search into the Zip files.  Our cached info
-             * said it was a file on disk; to be consistent with openDir()
-             * we want to return the loose asset.  If the cached file gets
-             * removed, we fail.
-             *
-             * The alternative is to update our cache when files get deleted,
-             * or make some sort of "best effort" promise, but for now I'm
-             * taking the hard line.
-             */
-            if (found) {
-                if (pAsset == NULL)
-                    ALOGD("Expected file not found: '%s'\n", path.string());
-                return pAsset;
-            }
-        }
-    }
-
-    /*
-     * Either it wasn't found on disk or on the cached view of the disk.
-     * Dig through the currently-opened set of Zip files.  If caching
-     * is disabled, the Zip file may get reopened.
-     */
-    if (pAsset == NULL && ap.type == kFileTypeRegular) {
-        String8 path;
-
-        path.appendPath((locale != NULL) ? locale : kDefaultLocale);
-        path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);
-        path.appendPath(fileName);
-
-        /* check the appropriate Zip file */
-        ZipFileRO* pZip;
-        ZipEntryRO entry;
-
-        pZip = getZipFileLocked(ap);
-        if (pZip != NULL) {
-            //printf("GOT zip, checking '%s'\n", (const char*) path);
-            entry = pZip->findEntryByName(path.string());
-            if (entry != NULL) {
-                //printf("FOUND in Zip file for %s/%s-%s\n",
-                //    appName, locale, vendor);
-                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
-            }
-        }
-
-        if (pAsset != NULL) {
-            /* create a "source" name, for debug/display */
-            pAsset->setAssetSource(createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()),
-                                                             String8(""), String8(fileName)));
-        }
-    }
-
-    return pAsset;
-}
-
-/*
- * Create a "source name" for a file from a Zip archive.
- */
-String8 AssetManager::createZipSourceNameLocked(const String8& zipFileName,
-    const String8& dirName, const String8& fileName)
-{
-    String8 sourceName("zip:");
-    sourceName.append(zipFileName);
-    sourceName.append(":");
-    if (dirName.length() > 0) {
-        sourceName.appendPath(dirName);
-    }
-    sourceName.appendPath(fileName);
-    return sourceName;
-}
-
-/*
- * Create a path to a loose asset (asset-base/app/locale/vendor).
- */
-String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* locale,
-    const char* vendor)
-{
-    String8 path(ap.path);
-    path.appendPath((locale != NULL) ? locale : kDefaultLocale);
-    path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);
-    return path;
-}
-
-/*
- * Create a path to a loose asset (asset-base/app/rootDir).
- */
-String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* rootDir)
-{
-    String8 path(ap.path);
-    if (rootDir != NULL) path.appendPath(rootDir);
-    return path;
-}
-
-/*
- * Return a pointer to one of our open Zip archives.  Returns NULL if no
- * matching Zip file exists.
- *
- * Right now we have 2 possible Zip files (1 each in app/"common").
- *
- * If caching is set to CACHE_OFF, to get the expected behavior we
- * need to reopen the Zip file on every request.  That would be silly
- * and expensive, so instead we just check the file modification date.
- *
- * Pass in NULL values for "appName", "locale", and "vendor" if the
- * generics should be used.
- */
-ZipFileRO* AssetManager::getZipFileLocked(const asset_path& ap)
-{
-    ALOGV("getZipFileLocked() in %p\n", this);
-
-    return mZipSet.getZip(ap.path);
-}
-
-/*
- * Try to open an asset from a file on disk.
- *
- * If the file is compressed with gzip, we seek to the start of the
- * deflated data and pass that in (just like we would for a Zip archive).
- *
- * For uncompressed data, we may already have an mmap()ed version sitting
- * around.  If so, we want to hand that to the Asset instead.
- *
- * This returns NULL if the file doesn't exist, couldn't be opened, or
- * claims to be a ".gz" but isn't.
- */
-Asset* AssetManager::openAssetFromFileLocked(const String8& pathName,
-    AccessMode mode)
-{
-    Asset* pAsset = NULL;
-
-    if (strcasecmp(pathName.getPathExtension().string(), ".gz") == 0) {
-        //printf("TRYING '%s'\n", (const char*) pathName);
-        pAsset = Asset::createFromCompressedFile(pathName.string(), mode);
-    } else {
-        //printf("TRYING '%s'\n", (const char*) pathName);
-        pAsset = Asset::createFromFile(pathName.string(), mode);
-    }
-
-    return pAsset;
-}
-
-/*
- * Given an entry in a Zip archive, create a new Asset object.
- *
- * If the entry is uncompressed, we may want to create or share a
- * slice of shared memory.
- */
-Asset* AssetManager::openAssetFromZipLocked(const ZipFileRO* pZipFile,
-    const ZipEntryRO entry, AccessMode mode, const String8& entryName)
-{
-    Asset* pAsset = NULL;
-
-    // TODO: look for previously-created shared memory slice?
-    int method;
-    size_t uncompressedLen;
-
-    //printf("USING Zip '%s'\n", pEntry->getFileName());
-
-    //pZipFile->getEntryInfo(entry, &method, &uncompressedLen, &compressedLen,
-    //    &offset);
-    if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, NULL, NULL,
-            NULL, NULL))
-    {
-        ALOGW("getEntryInfo failed\n");
-        return NULL;
-    }
-
-    FileMap* dataMap = pZipFile->createEntryFileMap(entry);
-    if (dataMap == NULL) {
-        ALOGW("create map from entry failed\n");
-        return NULL;
-    }
-
-    if (method == ZipFileRO::kCompressStored) {
-        pAsset = Asset::createFromUncompressedMap(dataMap, mode);
-        ALOGV("Opened uncompressed entry %s in zip %s mode %d: %p", entryName.string(),
-                dataMap->getFileName(), mode, pAsset);
-    } else {
-        pAsset = Asset::createFromCompressedMap(dataMap, method,
-            uncompressedLen, mode);
-        ALOGV("Opened compressed entry %s in zip %s mode %d: %p", entryName.string(),
-                dataMap->getFileName(), mode, pAsset);
-    }
-    if (pAsset == NULL) {
-        /* unexpected */
-        ALOGW("create from segment failed\n");
-    }
-
-    return pAsset;
-}
-
-
-
-/*
- * Open a directory in the asset namespace.
- *
- * An "asset directory" is simply the combination of all files in all
- * locations, with ".gz" stripped for loose files.  With app, locale, and
- * vendor defined, we have 8 directories and 2 Zip archives to scan.
- *
- * Pass in "" for the root dir.
- */
-AssetDir* AssetManager::openDir(const char* dirName)
-{
-    AutoMutex _l(mLock);
-
-    AssetDir* pDir = NULL;
-    SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;
-
-    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-    assert(dirName != NULL);
-
-    //printf("+++ openDir(%s) in '%s'\n", dirName, (const char*) mAssetBase);
-
-    if (mCacheMode != CACHE_OFF && !mCacheValid)
-        loadFileNameCacheLocked();
-
-    pDir = new AssetDir;
-
-    /*
-     * Scan the various directories, merging what we find into a single
-     * vector.  We want to scan them in reverse priority order so that
-     * the ".EXCLUDE" processing works correctly.  Also, if we decide we
-     * want to remember where the file is coming from, we'll get the right
-     * version.
-     *
-     * We start with Zip archives, then do loose files.
-     */
-    pMergedInfo = new SortedVector<AssetDir::FileInfo>;
-
-    size_t i = mAssetPaths.size();
-    while (i > 0) {
-        i--;
-        const asset_path& ap = mAssetPaths.itemAt(i);
-        if (ap.type == kFileTypeRegular) {
-            ALOGV("Adding directory %s from zip %s", dirName, ap.path.string());
-            scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName);
-        } else {
-            ALOGV("Adding directory %s from dir %s", dirName, ap.path.string());
-            scanAndMergeDirLocked(pMergedInfo, ap, kAssetsRoot, dirName);
-        }
-    }
-
-#if 0
-    printf("FILE LIST:\n");
-    for (i = 0; i < (size_t) pMergedInfo->size(); i++) {
-        printf(" %d: (%d) '%s'\n", i,
-            pMergedInfo->itemAt(i).getFileType(),
-            (const char*) pMergedInfo->itemAt(i).getFileName());
-    }
-#endif
-
-    pDir->setFileList(pMergedInfo);
-    return pDir;
-}
-
-/*
- * Open a directory in the non-asset namespace.
- *
- * An "asset directory" is simply the combination of all files in all
- * locations, with ".gz" stripped for loose files.  With app, locale, and
- * vendor defined, we have 8 directories and 2 Zip archives to scan.
- *
- * Pass in "" for the root dir.
- */
-AssetDir* AssetManager::openNonAssetDir(void* cookie, const char* dirName)
-{
-    AutoMutex _l(mLock);
-
-    AssetDir* pDir = NULL;
-    SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;
-
-    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
-    assert(dirName != NULL);
-
-    //printf("+++ openDir(%s) in '%s'\n", dirName, (const char*) mAssetBase);
-
-    if (mCacheMode != CACHE_OFF && !mCacheValid)
-        loadFileNameCacheLocked();
-
-    pDir = new AssetDir;
-
-    pMergedInfo = new SortedVector<AssetDir::FileInfo>;
-
-    const size_t which = ((size_t)cookie)-1;
-
-    if (which < mAssetPaths.size()) {
-        const asset_path& ap = mAssetPaths.itemAt(which);
-        if (ap.type == kFileTypeRegular) {
-            ALOGV("Adding directory %s from zip %s", dirName, ap.path.string());
-            scanAndMergeZipLocked(pMergedInfo, ap, NULL, dirName);
-        } else {
-            ALOGV("Adding directory %s from dir %s", dirName, ap.path.string());
-            scanAndMergeDirLocked(pMergedInfo, ap, NULL, dirName);
-        }
-    }
-
-#if 0
-    printf("FILE LIST:\n");
-    for (i = 0; i < (size_t) pMergedInfo->size(); i++) {
-        printf(" %d: (%d) '%s'\n", i,
-            pMergedInfo->itemAt(i).getFileType(),
-            (const char*) pMergedInfo->itemAt(i).getFileName());
-    }
-#endif
-
-    pDir->setFileList(pMergedInfo);
-    return pDir;
-}
-
-/*
- * Scan the contents of the specified directory and merge them into the
- * "pMergedInfo" vector, removing previous entries if we find "exclude"
- * directives.
- *
- * Returns "false" if we found nothing to contribute.
- */
-bool AssetManager::scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
-    const asset_path& ap, const char* rootDir, const char* dirName)
-{
-    SortedVector<AssetDir::FileInfo>* pContents;
-    String8 path;
-
-    assert(pMergedInfo != NULL);
-
-    //printf("scanAndMergeDir: %s %s %s %s\n", appName, locale, vendor,dirName);
-
-    if (mCacheValid) {
-        int i, start, count;
-
-        pContents = new SortedVector<AssetDir::FileInfo>;
-
-        /*
-         * Get the basic partial path and find it in the cache.  That's
-         * the start point for the search.
-         */
-        path = createPathNameLocked(ap, rootDir);
-        if (dirName[0] != '\0')
-            path.appendPath(dirName);
-
-        start = mCache.indexOf(path);
-        if (start == NAME_NOT_FOUND) {
-            //printf("+++ not found in cache: dir '%s'\n", (const char*) path);
-            delete pContents;
-            return false;
-        }
-
-        /*
-         * The match string looks like "common/default/default/foo/bar/".
-         * The '/' on the end ensures that we don't match on the directory
-         * itself or on ".../foo/barfy/".
-         */
-        path.append("/");
-
-        count = mCache.size();
-
-        /*
-         * Pick out the stuff in the current dir by examining the pathname.
-         * It needs to match the partial pathname prefix, and not have a '/'
-         * (fssep) anywhere after the prefix.
-         */
-        for (i = start+1; i < count; i++) {
-            if (mCache[i].getFileName().length() > path.length() &&
-                strncmp(mCache[i].getFileName().string(), path.string(), path.length()) == 0)
-            {
-                const char* name = mCache[i].getFileName().string();
-                // XXX THIS IS BROKEN!  Looks like we need to store the full
-                // path prefix separately from the file path.
-                if (strchr(name + path.length(), '/') == NULL) {
-                    /* grab it, reducing path to just the filename component */
-                    AssetDir::FileInfo tmp = mCache[i];
-                    tmp.setFileName(tmp.getFileName().getPathLeaf());
-                    pContents->add(tmp);
-                }
-            } else {
-                /* no longer in the dir or its subdirs */
-                break;
-            }
-
-        }
-    } else {
-        path = createPathNameLocked(ap, rootDir);
-        if (dirName[0] != '\0')
-            path.appendPath(dirName);
-        pContents = scanDirLocked(path);
-        if (pContents == NULL)
-            return false;
-    }
-
-    // if we wanted to do an incremental cache fill, we would do it here
-
-    /*
-     * Process "exclude" directives.  If we find a filename that ends with
-     * ".EXCLUDE", we look for a matching entry in the "merged" set, and
-     * remove it if we find it.  We also delete the "exclude" entry.
-     */
-    int i, count, exclExtLen;
-
-    count = pContents->size();
-    exclExtLen = strlen(kExcludeExtension);
-    for (i = 0; i < count; i++) {
-        const char* name;
-        int nameLen;
-
-        name = pContents->itemAt(i).getFileName().string();
-        nameLen = strlen(name);
-        if (nameLen > exclExtLen &&
-            strcmp(name + (nameLen - exclExtLen), kExcludeExtension) == 0)
-        {
-            String8 match(name, nameLen - exclExtLen);
-            int matchIdx;
-
-            matchIdx = AssetDir::FileInfo::findEntry(pMergedInfo, match);
-            if (matchIdx > 0) {
-                ALOGV("Excluding '%s' [%s]\n",
-                    pMergedInfo->itemAt(matchIdx).getFileName().string(),
-                    pMergedInfo->itemAt(matchIdx).getSourceName().string());
-                pMergedInfo->removeAt(matchIdx);
-            } else {
-                //printf("+++ no match on '%s'\n", (const char*) match);
-            }
-
-            ALOGD("HEY: size=%d removing %d\n", (int)pContents->size(), i);
-            pContents->removeAt(i);
-            i--;        // adjust "for" loop
-            count--;    //  and loop limit
-        }
-    }
-
-    mergeInfoLocked(pMergedInfo, pContents);
-
-    delete pContents;
-
-    return true;
-}
-
-/*
- * Scan the contents of the specified directory, and stuff what we find
- * into a newly-allocated vector.
- *
- * Files ending in ".gz" will have their extensions removed.
- *
- * We should probably think about skipping files with "illegal" names,
- * e.g. illegal characters (/\:) or excessive length.
- *
- * Returns NULL if the specified directory doesn't exist.
- */
-SortedVector<AssetDir::FileInfo>* AssetManager::scanDirLocked(const String8& path)
-{
-    SortedVector<AssetDir::FileInfo>* pContents = NULL;
-    DIR* dir;
-    struct dirent* entry;
-    FileType fileType;
-
-    ALOGV("Scanning dir '%s'\n", path.string());
-
-    dir = opendir(path.string());
-    if (dir == NULL)
-        return NULL;
-
-    pContents = new SortedVector<AssetDir::FileInfo>;
-
-    while (1) {
-        entry = readdir(dir);
-        if (entry == NULL)
-            break;
-
-        if (strcmp(entry->d_name, ".") == 0 ||
-            strcmp(entry->d_name, "..") == 0)
-            continue;
-
-#ifdef _DIRENT_HAVE_D_TYPE
-        if (entry->d_type == DT_REG)
-            fileType = kFileTypeRegular;
-        else if (entry->d_type == DT_DIR)
-            fileType = kFileTypeDirectory;
-        else
-            fileType = kFileTypeUnknown;
-#else
-        // stat the file
-        fileType = ::getFileType(path.appendPathCopy(entry->d_name).string());
-#endif
-
-        if (fileType != kFileTypeRegular && fileType != kFileTypeDirectory)
-            continue;
-
-        AssetDir::FileInfo info;
-        info.set(String8(entry->d_name), fileType);
-        if (strcasecmp(info.getFileName().getPathExtension().string(), ".gz") == 0)
-            info.setFileName(info.getFileName().getBasePath());
-        info.setSourceName(path.appendPathCopy(info.getFileName()));
-        pContents->add(info);
-    }
-
-    closedir(dir);
-    return pContents;
-}
-
-/*
- * Scan the contents out of the specified Zip archive, and merge what we
- * find into "pMergedInfo".  If the Zip archive in question doesn't exist,
- * we return immediately.
- *
- * Returns "false" if we found nothing to contribute.
- */
-bool AssetManager::scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
-    const asset_path& ap, const char* rootDir, const char* baseDirName)
-{
-    ZipFileRO* pZip;
-    Vector<String8> dirs;
-    AssetDir::FileInfo info;
-    SortedVector<AssetDir::FileInfo> contents;
-    String8 sourceName, zipName, dirName;
-
-    pZip = mZipSet.getZip(ap.path);
-    if (pZip == NULL) {
-        ALOGW("Failure opening zip %s\n", ap.path.string());
-        return false;
-    }
-
-    zipName = ZipSet::getPathName(ap.path.string());
-
-    /* convert "sounds" to "rootDir/sounds" */
-    if (rootDir != NULL) dirName = rootDir;
-    dirName.appendPath(baseDirName);
-
-    /*
-     * Scan through the list of files, looking for a match.  The files in
-     * the Zip table of contents are not in sorted order, so we have to
-     * process the entire list.  We're looking for a string that begins
-     * with the characters in "dirName", is followed by a '/', and has no
-     * subsequent '/' in the stuff that follows.
-     *
-     * What makes this especially fun is that directories are not stored
-     * explicitly in Zip archives, so we have to infer them from context.
-     * When we see "sounds/foo.wav" we have to leave a note to ourselves
-     * to insert a directory called "sounds" into the list.  We store
-     * these in temporary vector so that we only return each one once.
-     *
-     * Name comparisons are case-sensitive to match UNIX filesystem
-     * semantics.
-     */
-    int dirNameLen = dirName.length();
-    for (int i = 0; i < pZip->getNumEntries(); i++) {
-        ZipEntryRO entry;
-        char nameBuf[256];
-
-        entry = pZip->findEntryByIndex(i);
-        if (pZip->getEntryFileName(entry, nameBuf, sizeof(nameBuf)) != 0) {
-            // TODO: fix this if we expect to have long names
-            ALOGE("ARGH: name too long?\n");
-            continue;
-        }
-        //printf("Comparing %s in %s?\n", nameBuf, dirName.string());
-        if (dirNameLen == 0 ||
-            (strncmp(nameBuf, dirName.string(), dirNameLen) == 0 &&
-             nameBuf[dirNameLen] == '/'))
-        {
-            const char* cp;
-            const char* nextSlash;
-
-            cp = nameBuf + dirNameLen;
-            if (dirNameLen != 0)
-                cp++;       // advance past the '/'
-
-            nextSlash = strchr(cp, '/');
-//xxx this may break if there are bare directory entries
-            if (nextSlash == NULL) {
-                /* this is a file in the requested directory */
-
-                info.set(String8(nameBuf).getPathLeaf(), kFileTypeRegular);
-
-                info.setSourceName(
-                    createZipSourceNameLocked(zipName, dirName, info.getFileName()));
-
-                contents.add(info);
-                //printf("FOUND: file '%s'\n", info.getFileName().string());
-            } else {
-                /* this is a subdir; add it if we don't already have it*/
-                String8 subdirName(cp, nextSlash - cp);
-                size_t j;
-                size_t N = dirs.size();
-
-                for (j = 0; j < N; j++) {
-                    if (subdirName == dirs[j]) {
-                        break;
-                    }
-                }
-                if (j == N) {
-                    dirs.add(subdirName);
-                }
-
-                //printf("FOUND: dir '%s'\n", subdirName.string());
-            }
-        }
-    }
-
-    /*
-     * Add the set of unique directories.
-     */
-    for (int i = 0; i < (int) dirs.size(); i++) {
-        info.set(dirs[i], kFileTypeDirectory);
-        info.setSourceName(
-            createZipSourceNameLocked(zipName, dirName, info.getFileName()));
-        contents.add(info);
-    }
-
-    mergeInfoLocked(pMergedInfo, &contents);
-
-    return true;
-}
-
-
-/*
- * Merge two vectors of FileInfo.
- *
- * The merged contents will be stuffed into *pMergedInfo.
- *
- * If an entry for a file exists in both "pMergedInfo" and "pContents",
- * we use the newer "pContents" entry.
- */
-void AssetManager::mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
-    const SortedVector<AssetDir::FileInfo>* pContents)
-{
-    /*
-     * Merge what we found in this directory with what we found in
-     * other places.
-     *
-     * Two basic approaches:
-     * (1) Create a new array that holds the unique values of the two
-     *     arrays.
-     * (2) Take the elements from pContents and shove them into pMergedInfo.
-     *
-     * Because these are vectors of complex objects, moving elements around
-     * inside the vector requires constructing new objects and allocating
-     * storage for members.  With approach #1, we're always adding to the
-     * end, whereas with #2 we could be inserting multiple elements at the
-     * front of the vector.  Approach #1 requires a full copy of the
-     * contents of pMergedInfo, but approach #2 requires the same copy for
-     * every insertion at the front of pMergedInfo.
-     *
-     * (We should probably use a SortedVector interface that allows us to
-     * just stuff items in, trusting us to maintain the sort order.)
-     */
-    SortedVector<AssetDir::FileInfo>* pNewSorted;
-    int mergeMax, contMax;
-    int mergeIdx, contIdx;
-
-    pNewSorted = new SortedVector<AssetDir::FileInfo>;
-    mergeMax = pMergedInfo->size();
-    contMax = pContents->size();
-    mergeIdx = contIdx = 0;
-
-    while (mergeIdx < mergeMax || contIdx < contMax) {
-        if (mergeIdx == mergeMax) {
-            /* hit end of "merge" list, copy rest of "contents" */
-            pNewSorted->add(pContents->itemAt(contIdx));
-            contIdx++;
-        } else if (contIdx == contMax) {
-            /* hit end of "cont" list, copy rest of "merge" */
-            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));
-            mergeIdx++;
-        } else if (pMergedInfo->itemAt(mergeIdx) == pContents->itemAt(contIdx))
-        {
-            /* items are identical, add newer and advance both indices */
-            pNewSorted->add(pContents->itemAt(contIdx));
-            mergeIdx++;
-            contIdx++;
-        } else if (pMergedInfo->itemAt(mergeIdx) < pContents->itemAt(contIdx))
-        {
-            /* "merge" is lower, add that one */
-            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));
-            mergeIdx++;
-        } else {
-            /* "cont" is lower, add that one */
-            assert(pContents->itemAt(contIdx) < pMergedInfo->itemAt(mergeIdx));
-            pNewSorted->add(pContents->itemAt(contIdx));
-            contIdx++;
-        }
-    }
-
-    /*
-     * Overwrite the "merged" list with the new stuff.
-     */
-    *pMergedInfo = *pNewSorted;
-    delete pNewSorted;
-
-#if 0       // for Vector, rather than SortedVector
-    int i, j;
-    for (i = pContents->size() -1; i >= 0; i--) {
-        bool add = true;
-
-        for (j = pMergedInfo->size() -1; j >= 0; j--) {
-            /* case-sensitive comparisons, to behave like UNIX fs */
-            if (strcmp(pContents->itemAt(i).mFileName,
-                       pMergedInfo->itemAt(j).mFileName) == 0)
-            {
-                /* match, don't add this entry */
-                add = false;
-                break;
-            }
-        }
-
-        if (add)
-            pMergedInfo->add(pContents->itemAt(i));
-    }
-#endif
-}
-
-
-/*
- * Load all files into the file name cache.  We want to do this across
- * all combinations of { appname, locale, vendor }, performing a recursive
- * directory traversal.
- *
- * This is not the most efficient data structure.  Also, gathering the
- * information as we needed it (file-by-file or directory-by-directory)
- * would be faster.  However, on the actual device, 99% of the files will
- * live in Zip archives, so this list will be very small.  The trouble
- * is that we have to check the "loose" files first, so it's important
- * that we don't beat the filesystem silly looking for files that aren't
- * there.
- *
- * Note on thread safety: this is the only function that causes updates
- * to mCache, and anybody who tries to use it will call here if !mCacheValid,
- * so we need to employ a mutex here.
- */
-void AssetManager::loadFileNameCacheLocked(void)
-{
-    assert(!mCacheValid);
-    assert(mCache.size() == 0);
-
-#ifdef DO_TIMINGS   // need to link against -lrt for this now
-    DurationTimer timer;
-    timer.start();
-#endif
-
-    fncScanLocked(&mCache, "");
-
-#ifdef DO_TIMINGS
-    timer.stop();
-    ALOGD("Cache scan took %.3fms\n",
-        timer.durationUsecs() / 1000.0);
-#endif
-
-#if 0
-    int i;
-    printf("CACHED FILE LIST (%d entries):\n", mCache.size());
-    for (i = 0; i < (int) mCache.size(); i++) {
-        printf(" %d: (%d) '%s'\n", i,
-            mCache.itemAt(i).getFileType(),
-            (const char*) mCache.itemAt(i).getFileName());
-    }
-#endif
-
-    mCacheValid = true;
-}
-
-/*
- * Scan up to 8 versions of the specified directory.
- */
-void AssetManager::fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
-    const char* dirName)
-{
-    size_t i = mAssetPaths.size();
-    while (i > 0) {
-        i--;
-        const asset_path& ap = mAssetPaths.itemAt(i);
-        fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, NULL, dirName);
-        if (mLocale != NULL)
-            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, NULL, dirName);
-        if (mVendor != NULL)
-            fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, mVendor, dirName);
-        if (mLocale != NULL && mVendor != NULL)
-            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, mVendor, dirName);
-    }
-}
-
-/*
- * Recursively scan this directory and all subdirs.
- *
- * This is similar to scanAndMergeDir, but we don't remove the .EXCLUDE
- * files, and we prepend the extended partial path to the filenames.
- */
-bool AssetManager::fncScanAndMergeDirLocked(
-    SortedVector<AssetDir::FileInfo>* pMergedInfo,
-    const asset_path& ap, const char* locale, const char* vendor,
-    const char* dirName)
-{
-    SortedVector<AssetDir::FileInfo>* pContents;
-    String8 partialPath;
-    String8 fullPath;
-
-    // XXX This is broken -- the filename cache needs to hold the base
-    // asset path separately from its filename.
-    
-    partialPath = createPathNameLocked(ap, locale, vendor);
-    if (dirName[0] != '\0') {
-        partialPath.appendPath(dirName);
-    }
-
-    fullPath = partialPath;
-    pContents = scanDirLocked(fullPath);
-    if (pContents == NULL) {
-        return false;       // directory did not exist
-    }
-
-    /*
-     * Scan all subdirectories of the current dir, merging what we find
-     * into "pMergedInfo".
-     */
-    for (int i = 0; i < (int) pContents->size(); i++) {
-        if (pContents->itemAt(i).getFileType() == kFileTypeDirectory) {
-            String8 subdir(dirName);
-            subdir.appendPath(pContents->itemAt(i).getFileName());
-
-            fncScanAndMergeDirLocked(pMergedInfo, ap, locale, vendor, subdir.string());
-        }
-    }
-
-    /*
-     * To be consistent, we want entries for the root directory.  If
-     * we're the root, add one now.
-     */
-    if (dirName[0] == '\0') {
-        AssetDir::FileInfo tmpInfo;
-
-        tmpInfo.set(String8(""), kFileTypeDirectory);
-        tmpInfo.setSourceName(createPathNameLocked(ap, locale, vendor));
-        pContents->add(tmpInfo);
-    }
-
-    /*
-     * We want to prepend the extended partial path to every entry in
-     * "pContents".  It's the same value for each entry, so this will
-     * not change the sorting order of the vector contents.
-     */
-    for (int i = 0; i < (int) pContents->size(); i++) {
-        const AssetDir::FileInfo& info = pContents->itemAt(i);
-        pContents->editItemAt(i).setFileName(partialPath.appendPathCopy(info.getFileName()));
-    }
-
-    mergeInfoLocked(pMergedInfo, pContents);
-    return true;
-}
-
-/*
- * Trash the cache.
- */
-void AssetManager::purgeFileNameCacheLocked(void)
-{
-    mCacheValid = false;
-    mCache.clear();
-}
-
-/*
- * ===========================================================================
- *      AssetManager::SharedZip
- * ===========================================================================
- */
-
-
-Mutex AssetManager::SharedZip::gLock;
-DefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen;
-
-AssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen)
-    : mPath(path), mZipFile(NULL), mModWhen(modWhen),
-      mResourceTableAsset(NULL), mResourceTable(NULL)
-{
-    //ALOGI("Creating SharedZip %p %s\n", this, (const char*)mPath);
-    mZipFile = new ZipFileRO;
-    ALOGV("+++ opening zip '%s'\n", mPath.string());
-    if (mZipFile->open(mPath.string()) != NO_ERROR) {
-        ALOGD("failed to open Zip archive '%s'\n", mPath.string());
-        delete mZipFile;
-        mZipFile = NULL;
-    }
-}
-
-sp<AssetManager::SharedZip> AssetManager::SharedZip::get(const String8& path)
-{
-    AutoMutex _l(gLock);
-    time_t modWhen = getFileModDate(path);
-    sp<SharedZip> zip = gOpen.valueFor(path).promote();
-    if (zip != NULL && zip->mModWhen == modWhen) {
-        return zip;
-    }
-    zip = new SharedZip(path, modWhen);
-    gOpen.add(path, zip);
-    return zip;
-
-}
-
-ZipFileRO* AssetManager::SharedZip::getZip()
-{
-    return mZipFile;
-}
-
-Asset* AssetManager::SharedZip::getResourceTableAsset()
-{
-    ALOGV("Getting from SharedZip %p resource asset %p\n", this, mResourceTableAsset);
-    return mResourceTableAsset;
-}
-
-Asset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset)
-{
-    {
-        AutoMutex _l(gLock);
-        if (mResourceTableAsset == NULL) {
-            mResourceTableAsset = asset;
-            // This is not thread safe the first time it is called, so
-            // do it here with the global lock held.
-            asset->getBuffer(true);
-            return asset;
-        }
-    }
-    delete asset;
-    return mResourceTableAsset;
-}
-
-ResTable* AssetManager::SharedZip::getResourceTable()
-{
-    ALOGV("Getting from SharedZip %p resource table %p\n", this, mResourceTable);
-    return mResourceTable;
-}
-
-ResTable* AssetManager::SharedZip::setResourceTable(ResTable* res)
-{
-    {
-        AutoMutex _l(gLock);
-        if (mResourceTable == NULL) {
-            mResourceTable = res;
-            return res;
-        }
-    }
-    delete res;
-    return mResourceTable;
-}
-
-bool AssetManager::SharedZip::isUpToDate()
-{
-    time_t modWhen = getFileModDate(mPath.string());
-    return mModWhen == modWhen;
-}
-
-AssetManager::SharedZip::~SharedZip()
-{
-    //ALOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath);
-    if (mResourceTable != NULL) {
-        delete mResourceTable;
-    }
-    if (mResourceTableAsset != NULL) {
-        delete mResourceTableAsset;
-    }
-    if (mZipFile != NULL) {
-        delete mZipFile;
-        ALOGV("Closed '%s'\n", mPath.string());
-    }
-}
-
-/*
- * ===========================================================================
- *      AssetManager::ZipSet
- * ===========================================================================
- */
-
-/*
- * Constructor.
- */
-AssetManager::ZipSet::ZipSet(void)
-{
-}
-
-/*
- * Destructor.  Close any open archives.
- */
-AssetManager::ZipSet::~ZipSet(void)
-{
-    size_t N = mZipFile.size();
-    for (size_t i = 0; i < N; i++)
-        closeZip(i);
-}
-
-/*
- * Close a Zip file and reset the entry.
- */
-void AssetManager::ZipSet::closeZip(int idx)
-{
-    mZipFile.editItemAt(idx) = NULL;
-}
-
-
-/*
- * Retrieve the appropriate Zip file from the set.
- */
-ZipFileRO* AssetManager::ZipSet::getZip(const String8& path)
-{
-    int idx = getIndex(path);
-    sp<SharedZip> zip = mZipFile[idx];
-    if (zip == NULL) {
-        zip = SharedZip::get(path);
-        mZipFile.editItemAt(idx) = zip;
-    }
-    return zip->getZip();
-}
-
-Asset* AssetManager::ZipSet::getZipResourceTableAsset(const String8& path)
-{
-    int idx = getIndex(path);
-    sp<SharedZip> zip = mZipFile[idx];
-    if (zip == NULL) {
-        zip = SharedZip::get(path);
-        mZipFile.editItemAt(idx) = zip;
-    }
-    return zip->getResourceTableAsset();
-}
-
-Asset* AssetManager::ZipSet::setZipResourceTableAsset(const String8& path,
-                                                 Asset* asset)
-{
-    int idx = getIndex(path);
-    sp<SharedZip> zip = mZipFile[idx];
-    // doesn't make sense to call before previously accessing.
-    return zip->setResourceTableAsset(asset);
-}
-
-ResTable* AssetManager::ZipSet::getZipResourceTable(const String8& path)
-{
-    int idx = getIndex(path);
-    sp<SharedZip> zip = mZipFile[idx];
-    if (zip == NULL) {
-        zip = SharedZip::get(path);
-        mZipFile.editItemAt(idx) = zip;
-    }
-    return zip->getResourceTable();
-}
-
-ResTable* AssetManager::ZipSet::setZipResourceTable(const String8& path,
-                                                    ResTable* res)
-{
-    int idx = getIndex(path);
-    sp<SharedZip> zip = mZipFile[idx];
-    // doesn't make sense to call before previously accessing.
-    return zip->setResourceTable(res);
-}
-
-/*
- * Generate the partial pathname for the specified archive.  The caller
- * gets to prepend the asset root directory.
- *
- * Returns something like "common/en-US-noogle.jar".
- */
-/*static*/ String8 AssetManager::ZipSet::getPathName(const char* zipPath)
-{
-    return String8(zipPath);
-}
-
-bool AssetManager::ZipSet::isUpToDate()
-{
-    const size_t N = mZipFile.size();
-    for (size_t i=0; i<N; i++) {
-        if (mZipFile[i] != NULL && !mZipFile[i]->isUpToDate()) {
-            return false;
-        }
-    }
-    return true;
-}
-
-/*
- * Compute the zip file's index.
- *
- * "appName", "locale", and "vendor" should be set to NULL to indicate the
- * default directory.
- */
-int AssetManager::ZipSet::getIndex(const String8& zip) const
-{
-    const size_t N = mZipPath.size();
-    for (size_t i=0; i<N; i++) {
-        if (mZipPath[i] == zip) {
-            return i;
-        }
-    }
-
-    mZipPath.add(zip);
-    mZipFile.add(NULL);
-
-    return mZipPath.size()-1;
-}
diff --git a/libs/utils/BackupData.cpp b/libs/utils/BackupData.cpp
deleted file mode 100644
index 7b1bcba..0000000
--- a/libs/utils/BackupData.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "backup_data"
-
-#include <androidfw/BackupHelpers.h>
-#include <utils/ByteOrder.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <cutils/log.h>
-
-namespace android {
-
-static const bool DEBUG = false;
-
-/*
- * File Format (v1):
- *
- * All ints are stored little-endian.
- *
- *  - An app_header_v1 struct.
- *  - The name of the package, utf-8, null terminated, padded to 4-byte boundary.
- *  - A sequence of zero or more key/value paires (entities), each with
- *      - A entity_header_v1 struct
- *      - The key, utf-8, null terminated, padded to 4-byte boundary.
- *      - The value, padded to 4 byte boundary
- */
-
-const static int ROUND_UP[4] = { 0, 3, 2, 1 };
-
-static inline size_t
-round_up(size_t n)
-{
-    return n + ROUND_UP[n % 4];
-}
-
-static inline size_t
-padding_extra(size_t n)
-{
-    return ROUND_UP[n % 4];
-}
-
-BackupDataWriter::BackupDataWriter(int fd)
-    :m_fd(fd),
-     m_status(NO_ERROR),
-     m_pos(0),
-     m_entityCount(0)
-{
-}
-
-BackupDataWriter::~BackupDataWriter()
-{
-}
-
-// Pad out anything they've previously written to the next 4 byte boundary.
-status_t
-BackupDataWriter::write_padding_for(int n)
-{
-    ssize_t amt;
-    ssize_t paddingSize;
-
-    paddingSize = padding_extra(n);
-    if (paddingSize > 0) {
-        uint32_t padding = 0xbcbcbcbc;
-        if (DEBUG) ALOGI("writing %d padding bytes for %d", paddingSize, n);
-        amt = write(m_fd, &padding, paddingSize);
-        if (amt != paddingSize) {
-            m_status = errno;
-            return m_status;
-        }
-        m_pos += amt;
-    }
-    return NO_ERROR;
-}
-
-status_t
-BackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize)
-{
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-
-    ssize_t amt;
-
-    amt = write_padding_for(m_pos);
-    if (amt != 0) {
-        return amt;
-    }
-
-    String8 k;
-    if (m_keyPrefix.length() > 0) {
-        k = m_keyPrefix;
-        k += ":";
-        k += key;
-    } else {
-        k = key;
-    }
-    if (DEBUG) {
-        ALOGD("Writing header: prefix='%s' key='%s' dataSize=%d", m_keyPrefix.string(),
-                key.string(), dataSize);
-    }
-
-    entity_header_v1 header;
-    ssize_t keyLen;
-
-    keyLen = k.length();
-
-    header.type = tolel(BACKUP_HEADER_ENTITY_V1);
-    header.keyLen = tolel(keyLen);
-    header.dataSize = tolel(dataSize);
-
-    if (DEBUG) ALOGI("writing entity header, %d bytes", sizeof(entity_header_v1));
-    amt = write(m_fd, &header, sizeof(entity_header_v1));
-    if (amt != sizeof(entity_header_v1)) {
-        m_status = errno;
-        return m_status;
-    }
-    m_pos += amt;
-
-    if (DEBUG) ALOGI("writing entity header key, %d bytes", keyLen+1);
-    amt = write(m_fd, k.string(), keyLen+1);
-    if (amt != keyLen+1) {
-        m_status = errno;
-        return m_status;
-    }
-    m_pos += amt;
-
-    amt = write_padding_for(keyLen+1);
-
-    m_entityCount++;
-
-    return amt;
-}
-
-status_t
-BackupDataWriter::WriteEntityData(const void* data, size_t size)
-{
-    if (DEBUG) ALOGD("Writing data: size=%lu", (unsigned long) size);
-
-    if (m_status != NO_ERROR) {
-        if (DEBUG) {
-            ALOGD("Not writing data - stream in error state %d (%s)", m_status, strerror(m_status));
-        }
-        return m_status;
-    }
-
-    // We don't write padding here, because they're allowed to call this several
-    // times with smaller buffers.  We write it at the end of WriteEntityHeader
-    // instead.
-    ssize_t amt = write(m_fd, data, size);
-    if (amt != (ssize_t)size) {
-        m_status = errno;
-        if (DEBUG) ALOGD("write returned error %d (%s)", m_status, strerror(m_status));
-        return m_status;
-    }
-    m_pos += amt;
-    return NO_ERROR;
-}
-
-void
-BackupDataWriter::SetKeyPrefix(const String8& keyPrefix)
-{
-    m_keyPrefix = keyPrefix;
-}
-
-
-BackupDataReader::BackupDataReader(int fd)
-    :m_fd(fd),
-     m_done(false),
-     m_status(NO_ERROR),
-     m_pos(0),
-     m_entityCount(0)
-{
-    memset(&m_header, 0, sizeof(m_header));
-}
-
-BackupDataReader::~BackupDataReader()
-{
-}
-
-status_t
-BackupDataReader::Status()
-{
-    return m_status;
-}
-
-#define CHECK_SIZE(actual, expected) \
-    do { \
-        if ((actual) != (expected)) { \
-            if ((actual) == 0) { \
-                m_status = EIO; \
-                m_done = true; \
-            } else { \
-                m_status = errno; \
-                ALOGD("CHECK_SIZE(a=%ld e=%ld) failed at line %d m_status='%s'", \
-                    long(actual), long(expected), __LINE__, strerror(m_status)); \
-            } \
-            return m_status; \
-        } \
-    } while(0)
-#define SKIP_PADDING() \
-    do { \
-        status_t err = skip_padding(); \
-        if (err != NO_ERROR) { \
-            ALOGD("SKIP_PADDING FAILED at line %d", __LINE__); \
-            m_status = err; \
-            return err; \
-        } \
-    } while(0)
-
-status_t
-BackupDataReader::ReadNextHeader(bool* done, int* type)
-{
-    *done = m_done;
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-
-    int amt;
-
-    amt = skip_padding();
-    if (amt == EIO) {
-        *done = m_done = true;
-        return NO_ERROR;
-    }
-    else if (amt != NO_ERROR) {
-        return amt;
-    }
-    amt = read(m_fd, &m_header, sizeof(m_header));
-    *done = m_done = (amt == 0);
-    if (*done) {
-        return NO_ERROR;
-    }
-    CHECK_SIZE(amt, sizeof(m_header));
-    m_pos += sizeof(m_header);
-    if (type) {
-        *type = m_header.type;
-    }
-
-    // validate and fix up the fields.
-    m_header.type = fromlel(m_header.type);
-    switch (m_header.type)
-    {
-        case BACKUP_HEADER_ENTITY_V1:
-        {
-            m_header.entity.keyLen = fromlel(m_header.entity.keyLen);
-            if (m_header.entity.keyLen <= 0) {
-                ALOGD("Entity header at %d has keyLen<=0: 0x%08x\n", (int)m_pos,
-                        (int)m_header.entity.keyLen);
-                m_status = EINVAL;
-            }
-            m_header.entity.dataSize = fromlel(m_header.entity.dataSize);
-            m_entityCount++;
-
-            // read the rest of the header (filename)
-            size_t size = m_header.entity.keyLen;
-            char* buf = m_key.lockBuffer(size);
-            if (buf == NULL) {
-                m_status = ENOMEM;
-                return m_status;
-            }
-            int amt = read(m_fd, buf, size+1);
-            CHECK_SIZE(amt, (int)size+1);
-            m_key.unlockBuffer(size);
-            m_pos += size+1;
-            SKIP_PADDING();
-            m_dataEndPos = m_pos + m_header.entity.dataSize;
-
-            break;
-        }
-        default:
-            ALOGD("Chunk header at %d has invalid type: 0x%08x",
-                    (int)(m_pos - sizeof(m_header)), (int)m_header.type);
-            m_status = EINVAL;
-    }
-    
-    return m_status;
-}
-
-bool
-BackupDataReader::HasEntities()
-{
-    return m_status == NO_ERROR && m_header.type == BACKUP_HEADER_ENTITY_V1;
-}
-
-status_t
-BackupDataReader::ReadEntityHeader(String8* key, size_t* dataSize)
-{
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {
-        return EINVAL;
-    }
-    *key = m_key;
-    *dataSize = m_header.entity.dataSize;
-    return NO_ERROR;
-}
-
-status_t
-BackupDataReader::SkipEntityData()
-{
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {
-        return EINVAL;
-    }
-    if (m_header.entity.dataSize > 0) {
-        int pos = lseek(m_fd, m_dataEndPos, SEEK_SET);
-        if (pos == -1) {
-            return errno;
-        }
-    }
-    SKIP_PADDING();
-    return NO_ERROR;
-}
-
-ssize_t
-BackupDataReader::ReadEntityData(void* data, size_t size)
-{
-    if (m_status != NO_ERROR) {
-        return -1;
-    }
-    int remaining = m_dataEndPos - m_pos;
-    //ALOGD("ReadEntityData size=%d m_pos=0x%x m_dataEndPos=0x%x remaining=%d\n",
-    //        size, m_pos, m_dataEndPos, remaining);
-    if (remaining <= 0) {
-        return 0;
-    }
-    if (((int)size) > remaining) {
-        size = remaining;
-    }
-    //ALOGD("   reading %d bytes", size);
-    int amt = read(m_fd, data, size);
-    if (amt < 0) {
-        m_status = errno;
-        return -1;
-    }
-    if (amt == 0) {
-        m_status = EIO;
-        m_done = true;
-    }
-    m_pos += amt;
-    return amt;
-}
-
-status_t
-BackupDataReader::skip_padding()
-{
-    ssize_t amt;
-    ssize_t paddingSize;
-
-    paddingSize = padding_extra(m_pos);
-    if (paddingSize > 0) {
-        uint32_t padding;
-        amt = read(m_fd, &padding, paddingSize);
-        CHECK_SIZE(amt, paddingSize);
-        m_pos += amt;
-    }
-    return NO_ERROR;
-}
-
-
-} // namespace android
diff --git a/libs/utils/BackupHelpers.cpp b/libs/utils/BackupHelpers.cpp
deleted file mode 100644
index 7a817a7..0000000
--- a/libs/utils/BackupHelpers.cpp
+++ /dev/null
@@ -1,1591 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "file_backup_helper"
-
-#include <androidfw/BackupHelpers.h>
-
-#include <utils/KeyedVector.h>
-#include <utils/ByteOrder.h>
-#include <utils/String8.h>
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/stat.h>
-#include <sys/time.h>  // for utimes
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <utime.h>
-#include <fcntl.h>
-#include <zlib.h>
-
-#include <cutils/log.h>
-
-namespace android {
-
-#define MAGIC0 0x70616e53 // Snap
-#define MAGIC1 0x656c6946 // File
-
-/*
- * File entity data format (v1):
- *
- *   - 4-byte version number of the metadata, little endian (0x00000001 for v1)
- *   - 12 bytes of metadata
- *   - the file data itself
- *
- * i.e. a 16-byte metadata header followed by the raw file data.  If the
- * restore code does not recognize the metadata version, it can still
- * interpret the file data itself correctly.
- *
- * file_metadata_v1:
- *
- *   - 4 byte version number === 0x00000001 (little endian)
- *   - 4-byte access mode (little-endian)
- *   - undefined (8 bytes)
- */
-
-struct file_metadata_v1 {
-    int version;
-    int mode;
-    int undefined_1;
-    int undefined_2;
-};
-
-const static int CURRENT_METADATA_VERSION = 1;
-
-#if 1
-#define LOGP(f, x...)
-#else
-#if TEST_BACKUP_HELPERS
-#define LOGP(f, x...) printf(f "\n", x)
-#else
-#define LOGP(x...) ALOGD(x)
-#endif
-#endif
-
-const static int ROUND_UP[4] = { 0, 3, 2, 1 };
-
-static inline int
-round_up(int n)
-{
-    return n + ROUND_UP[n % 4];
-}
-
-static int
-read_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot)
-{
-    int bytesRead = 0;
-    int amt;
-    SnapshotHeader header;
-
-    amt = read(fd, &header, sizeof(header));
-    if (amt != sizeof(header)) {
-        return errno;
-    }
-    bytesRead += amt;
-
-    if (header.magic0 != MAGIC0 || header.magic1 != MAGIC1) {
-        ALOGW("read_snapshot_file header.magic0=0x%08x magic1=0x%08x", header.magic0, header.magic1);
-        return 1;
-    }
-
-    for (int i=0; i<header.fileCount; i++) {
-        FileState file;
-        char filenameBuf[128];
-
-        amt = read(fd, &file, sizeof(FileState));
-        if (amt != sizeof(FileState)) {
-            ALOGW("read_snapshot_file FileState truncated/error with read at %d bytes\n", bytesRead);
-            return 1;
-        }
-        bytesRead += amt;
-
-        // filename is not NULL terminated, but it is padded
-        int nameBufSize = round_up(file.nameLen);
-        char* filename = nameBufSize <= (int)sizeof(filenameBuf)
-                ? filenameBuf
-                : (char*)malloc(nameBufSize);
-        amt = read(fd, filename, nameBufSize);
-        if (amt == nameBufSize) {
-            snapshot->add(String8(filename, file.nameLen), file);
-        }
-        bytesRead += amt;
-        if (filename != filenameBuf) {
-            free(filename);
-        }
-        if (amt != nameBufSize) {
-            ALOGW("read_snapshot_file filename truncated/error with read at %d bytes\n", bytesRead);
-            return 1;
-        }
-    }
-
-    if (header.totalSize != bytesRead) {
-        ALOGW("read_snapshot_file length mismatch: header.totalSize=%d bytesRead=%d\n",
-                header.totalSize, bytesRead);
-        return 1;
-    }
-
-    return 0;
-}
-
-static int
-write_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot)
-{
-    int fileCount = 0;
-    int bytesWritten = sizeof(SnapshotHeader);
-    // preflight size
-    const int N = snapshot.size();
-    for (int i=0; i<N; i++) {
-        const FileRec& g = snapshot.valueAt(i);
-        if (!g.deleted) {
-            const String8& name = snapshot.keyAt(i);
-            bytesWritten += sizeof(FileState) + round_up(name.length());
-            fileCount++;
-        }
-    }
-
-    LOGP("write_snapshot_file fd=%d\n", fd);
-
-    int amt;
-    SnapshotHeader header = { MAGIC0, fileCount, MAGIC1, bytesWritten };
-
-    amt = write(fd, &header, sizeof(header));
-    if (amt != sizeof(header)) {
-        ALOGW("write_snapshot_file error writing header %s", strerror(errno));
-        return errno;
-    }
-
-    for (int i=0; i<N; i++) {
-        FileRec r = snapshot.valueAt(i);
-        if (!r.deleted) {
-            const String8& name = snapshot.keyAt(i);
-            int nameLen = r.s.nameLen = name.length();
-
-            amt = write(fd, &r.s, sizeof(FileState));
-            if (amt != sizeof(FileState)) {
-                ALOGW("write_snapshot_file error writing header %s", strerror(errno));
-                return 1;
-            }
-
-            // filename is not NULL terminated, but it is padded
-            amt = write(fd, name.string(), nameLen);
-            if (amt != nameLen) {
-                ALOGW("write_snapshot_file error writing filename %s", strerror(errno));
-                return 1;
-            }
-            int paddingLen = ROUND_UP[nameLen % 4];
-            if (paddingLen != 0) {
-                int padding = 0xabababab;
-                amt = write(fd, &padding, paddingLen);
-                if (amt != paddingLen) {
-                    ALOGW("write_snapshot_file error writing %d bytes of filename padding %s",
-                            paddingLen, strerror(errno));
-                    return 1;
-                }
-            }
-        }
-    }
-
-    return 0;
-}
-
-static int
-write_delete_file(BackupDataWriter* dataStream, const String8& key)
-{
-    LOGP("write_delete_file %s\n", key.string());
-    return dataStream->WriteEntityHeader(key, -1);
-}
-
-static int
-write_update_file(BackupDataWriter* dataStream, int fd, int mode, const String8& key,
-        char const* realFilename)
-{
-    LOGP("write_update_file %s (%s) : mode 0%o\n", realFilename, key.string(), mode);
-
-    const int bufsize = 4*1024;
-    int err;
-    int amt;
-    int fileSize;
-    int bytesLeft;
-    file_metadata_v1 metadata;
-
-    char* buf = (char*)malloc(bufsize);
-    int crc = crc32(0L, Z_NULL, 0);
-
-
-    fileSize = lseek(fd, 0, SEEK_END);
-    lseek(fd, 0, SEEK_SET);
-
-    if (sizeof(metadata) != 16) {
-        ALOGE("ERROR: metadata block is the wrong size!");
-    }
-
-    bytesLeft = fileSize + sizeof(metadata);
-    err = dataStream->WriteEntityHeader(key, bytesLeft);
-    if (err != 0) {
-        free(buf);
-        return err;
-    }
-
-    // store the file metadata first
-    metadata.version = tolel(CURRENT_METADATA_VERSION);
-    metadata.mode = tolel(mode);
-    metadata.undefined_1 = metadata.undefined_2 = 0;
-    err = dataStream->WriteEntityData(&metadata, sizeof(metadata));
-    if (err != 0) {
-        free(buf);
-        return err;
-    }
-    bytesLeft -= sizeof(metadata); // bytesLeft should == fileSize now
-
-    // now store the file content
-    while ((amt = read(fd, buf, bufsize)) != 0 && bytesLeft > 0) {
-        bytesLeft -= amt;
-        if (bytesLeft < 0) {
-            amt += bytesLeft; // Plus a negative is minus.  Don't write more than we promised.
-        }
-        err = dataStream->WriteEntityData(buf, amt);
-        if (err != 0) {
-            free(buf);
-            return err;
-        }
-    }
-    if (bytesLeft != 0) {
-        if (bytesLeft > 0) {
-            // Pad out the space we promised in the buffer.  We can't corrupt the buffer,
-            // even though the data we're sending is probably bad.
-            memset(buf, 0, bufsize);
-            while (bytesLeft > 0) {
-                amt = bytesLeft < bufsize ? bytesLeft : bufsize;
-                bytesLeft -= amt;
-                err = dataStream->WriteEntityData(buf, amt);
-                if (err != 0) {
-                    free(buf);
-                    return err;
-                }
-            }
-        }
-        ALOGE("write_update_file size mismatch for %s. expected=%d actual=%d."
-                " You aren't doing proper locking!", realFilename, fileSize, fileSize-bytesLeft);
-    }
-
-    free(buf);
-    return NO_ERROR;
-}
-
-static int
-write_update_file(BackupDataWriter* dataStream, const String8& key, char const* realFilename)
-{
-    int err;
-    struct stat st;
-
-    err = stat(realFilename, &st);
-    if (err < 0) {
-        return errno;
-    }
-
-    int fd = open(realFilename, O_RDONLY);
-    if (fd == -1) {
-        return errno;
-    }
-
-    err = write_update_file(dataStream, fd, st.st_mode, key, realFilename);
-    close(fd);
-    return err;
-}
-
-static int
-compute_crc32(int fd)
-{
-    const int bufsize = 4*1024;
-    int amt;
-
-    char* buf = (char*)malloc(bufsize);
-    int crc = crc32(0L, Z_NULL, 0);
-
-    lseek(fd, 0, SEEK_SET);
-
-    while ((amt = read(fd, buf, bufsize)) != 0) {
-        crc = crc32(crc, (Bytef*)buf, amt);
-    }
-
-    free(buf);
-    return crc;
-}
-
-int
-back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
-        char const* const* files, char const* const* keys, int fileCount)
-{
-    int err;
-    KeyedVector<String8,FileState> oldSnapshot;
-    KeyedVector<String8,FileRec> newSnapshot;
-
-    if (oldSnapshotFD != -1) {
-        err = read_snapshot_file(oldSnapshotFD, &oldSnapshot);
-        if (err != 0) {
-            // On an error, treat this as a full backup.
-            oldSnapshot.clear();
-        }
-    }
-
-    for (int i=0; i<fileCount; i++) {
-        String8 key(keys[i]);
-        FileRec r;
-        char const* file = files[i];
-        r.file = file;
-        struct stat st;
-
-        err = stat(file, &st);
-        if (err != 0) {
-            r.deleted = true;
-        } else {
-            r.deleted = false;
-            r.s.modTime_sec = st.st_mtime;
-            r.s.modTime_nsec = 0; // workaround sim breakage
-            //r.s.modTime_nsec = st.st_mtime_nsec;
-            r.s.mode = st.st_mode;
-            r.s.size = st.st_size;
-            // we compute the crc32 later down below, when we already have the file open.
-
-            if (newSnapshot.indexOfKey(key) >= 0) {
-                LOGP("back_up_files key already in use '%s'", key.string());
-                return -1;
-            }
-        }
-        newSnapshot.add(key, r);
-    }
-
-    int n = 0;
-    int N = oldSnapshot.size();
-    int m = 0;
-
-    while (n<N && m<fileCount) {
-        const String8& p = oldSnapshot.keyAt(n);
-        const String8& q = newSnapshot.keyAt(m);
-        FileRec& g = newSnapshot.editValueAt(m);
-        int cmp = p.compare(q);
-        if (g.deleted || cmp < 0) {
-            // file removed
-            LOGP("file removed: %s", p.string());
-            g.deleted = true; // They didn't mention the file, but we noticed that it's gone.
-            dataStream->WriteEntityHeader(p, -1);
-            n++;
-        }
-        else if (cmp > 0) {
-            // file added
-            LOGP("file added: %s", g.file.string());
-            write_update_file(dataStream, q, g.file.string());
-            m++;
-        }
-        else {
-            // both files exist, check them
-            const FileState& f = oldSnapshot.valueAt(n);
-
-            int fd = open(g.file.string(), O_RDONLY);
-            if (fd < 0) {
-                // We can't open the file.  Don't report it as a delete either.  Let the
-                // server keep the old version.  Maybe they'll be able to deal with it
-                // on restore.
-                LOGP("Unable to open file %s - skipping", g.file.string());
-            } else {
-                g.s.crc32 = compute_crc32(fd);
-
-                LOGP("%s", q.string());
-                LOGP("  new: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
-                        f.modTime_sec, f.modTime_nsec, f.mode, f.size, f.crc32);
-                LOGP("  old: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
-                        g.s.modTime_sec, g.s.modTime_nsec, g.s.mode, g.s.size, g.s.crc32);
-                if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
-                        || f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) {
-                    write_update_file(dataStream, fd, g.s.mode, p, g.file.string());
-                }
-
-                close(fd);
-            }
-            n++;
-            m++;
-        }
-    }
-
-    // these were deleted
-    while (n<N) {
-        dataStream->WriteEntityHeader(oldSnapshot.keyAt(n), -1);
-        n++;
-    }
-
-    // these were added
-    while (m<fileCount) {
-        const String8& q = newSnapshot.keyAt(m);
-        FileRec& g = newSnapshot.editValueAt(m);
-        write_update_file(dataStream, q, g.file.string());
-        m++;
-    }
-
-    err = write_snapshot_file(newSnapshotFD, newSnapshot);
-
-    return 0;
-}
-
-// Utility function, equivalent to stpcpy(): perform a strcpy, but instead of
-// returning the initial dest, return a pointer to the trailing NUL.
-static char* strcpy_ptr(char* dest, const char* str) {
-    if (dest && str) {
-        while ((*dest = *str) != 0) {
-            dest++;
-            str++;
-        }
-    }
-    return dest;
-}
-
-static void calc_tar_checksum(char* buf) {
-    // [ 148 :   8 ] checksum -- to be calculated with this field as space chars
-    memset(buf + 148, ' ', 8);
-
-    uint16_t sum = 0;
-    for (uint8_t* p = (uint8_t*) buf; p < ((uint8_t*)buf) + 512; p++) {
-        sum += *p;
-    }
-
-    // Now write the real checksum value:
-    // [ 148 :   8 ]  checksum: 6 octal digits [leading zeroes], NUL, SPC
-    sprintf(buf + 148, "%06o", sum); // the trailing space is already in place
-}
-
-// Returns number of bytes written
-static int write_pax_header_entry(char* buf, const char* key, const char* value) {
-    // start with the size of "1 key=value\n"
-    int len = strlen(key) + strlen(value) + 4;
-    if (len > 9) len++;
-    if (len > 99) len++;
-    if (len > 999) len++;
-    // since PATH_MAX is 4096 we don't expect to have to generate any single
-    // header entry longer than 9999 characters
-
-    return sprintf(buf, "%d %s=%s\n", len, key, value);
-}
-
-// Wire format to the backup manager service is chunked:  each chunk is prefixed by
-// a 4-byte count of its size.  A chunk size of zero (four zero bytes) indicates EOD.
-void send_tarfile_chunk(BackupDataWriter* writer, const char* buffer, size_t size) {
-    uint32_t chunk_size_no = htonl(size);
-    writer->WriteEntityData(&chunk_size_no, 4);
-    if (size != 0) writer->WriteEntityData(buffer, size);
-}
-
-int write_tarfile(const String8& packageName, const String8& domain,
-        const String8& rootpath, const String8& filepath, BackupDataWriter* writer)
-{
-    // In the output stream everything is stored relative to the root
-    const char* relstart = filepath.string() + rootpath.length();
-    if (*relstart == '/') relstart++;     // won't be true when path == rootpath
-    String8 relpath(relstart);
-
-    // If relpath is empty, it means this is the top of one of the standard named
-    // domain directories, so we should just skip it
-    if (relpath.length() == 0) {
-        return 0;
-    }
-
-    // Too long a name for the ustar format?
-    //    "apps/" + packagename + '/' + domainpath < 155 chars
-    //    relpath < 100 chars
-    bool needExtended = false;
-    if ((5 + packageName.length() + 1 + domain.length() >= 155) || (relpath.length() >= 100)) {
-        needExtended = true;
-    }
-
-    // Non-7bit-clean path also means needing pax extended format
-    if (!needExtended) {
-        for (size_t i = 0; i < filepath.length(); i++) {
-            if ((filepath[i] & 0x80) != 0) {
-                needExtended = true;
-                break;
-            }
-        }
-    }
-
-    int err = 0;
-    struct stat64 s;
-    if (lstat64(filepath.string(), &s) != 0) {
-        err = errno;
-        ALOGE("Error %d (%s) from lstat64(%s)", err, strerror(err), filepath.string());
-        return err;
-    }
-
-    String8 fullname;   // for pax later on
-    String8 prefix;
-
-    const int isdir = S_ISDIR(s.st_mode);
-    if (isdir) s.st_size = 0;   // directories get no actual data in the tar stream
-
-    // !!! TODO: use mmap when possible to avoid churning the buffer cache
-    // !!! TODO: this will break with symlinks; need to use readlink(2)
-    int fd = open(filepath.string(), O_RDONLY);
-    if (fd < 0) {
-        err = errno;
-        ALOGE("Error %d (%s) from open(%s)", err, strerror(err), filepath.string());
-        return err;
-    }
-
-    // read/write up to this much at a time.
-    const size_t BUFSIZE = 32 * 1024;
-    char* buf = (char *)calloc(1,BUFSIZE);
-    char* paxHeader = buf + 512;    // use a different chunk of it as separate scratch
-    char* paxData = buf + 1024;
-
-    if (buf == NULL) {
-        ALOGE("Out of mem allocating transfer buffer");
-        err = ENOMEM;
-        goto cleanup;
-    }
-
-    // Magic fields for the ustar file format
-    strcat(buf + 257, "ustar");
-    strcat(buf + 263, "00");
-
-    // [ 265 : 32 ] user name, ignored on restore
-    // [ 297 : 32 ] group name, ignored on restore
-
-    // [ 100 :   8 ] file mode
-    snprintf(buf + 100, 8, "%06o ", s.st_mode & ~S_IFMT);
-
-    // [ 108 :   8 ] uid -- ignored in Android format; uids are remapped at restore time
-    // [ 116 :   8 ] gid -- ignored in Android format
-    snprintf(buf + 108, 8, "0%lo", s.st_uid);
-    snprintf(buf + 116, 8, "0%lo", s.st_gid);
-
-    // [ 124 :  12 ] file size in bytes
-    if (s.st_size > 077777777777LL) {
-        // very large files need a pax extended size header
-        needExtended = true;
-    }
-    snprintf(buf + 124, 12, "%011llo", (isdir) ? 0LL : s.st_size);
-
-    // [ 136 :  12 ] last mod time as a UTC time_t
-    snprintf(buf + 136, 12, "%0lo", s.st_mtime);
-
-    // [ 156 :   1 ] link/file type
-    uint8_t type;
-    if (isdir) {
-        type = '5';     // tar magic: '5' == directory
-    } else if (S_ISREG(s.st_mode)) {
-        type = '0';     // tar magic: '0' == normal file
-    } else {
-        ALOGW("Error: unknown file mode 0%o [%s]", s.st_mode, filepath.string());
-        goto cleanup;
-    }
-    buf[156] = type;
-
-    // [ 157 : 100 ] name of linked file [not implemented]
-
-    {
-        // Prefix and main relative path.  Path lengths have been preflighted.
-        if (packageName.length() > 0) {
-            prefix = "apps/";
-            prefix += packageName;
-        }
-        if (domain.length() > 0) {
-            prefix.appendPath(domain);
-        }
-
-        // pax extended means we don't put in a prefix field, and put a different
-        // string in the basic name field.  We can also construct the full path name
-        // out of the substrings we've now built.
-        fullname = prefix;
-        fullname.appendPath(relpath);
-
-        // ustar:
-        //    [   0 : 100 ]; file name/path
-        //    [ 345 : 155 ] filename path prefix
-        // We only use the prefix area if fullname won't fit in the path
-        if (fullname.length() > 100) {
-            strncpy(buf, relpath.string(), 100);
-            strncpy(buf + 345, prefix.string(), 155);
-        } else {
-            strncpy(buf, fullname.string(), 100);
-        }
-    }
-
-    // [ 329 : 8 ] and [ 337 : 8 ] devmajor/devminor, not used
-
-    ALOGI("   Name: %s", fullname.string());
-
-    // If we're using a pax extended header, build & write that here; lengths are
-    // already preflighted
-    if (needExtended) {
-        char sizeStr[32];   // big enough for a 64-bit unsigned value in decimal
-        char* p = paxData;
-
-        // construct the pax extended header data block
-        memset(paxData, 0, BUFSIZE - (paxData - buf));
-        int len;
-
-        // size header -- calc len in digits by actually rendering the number
-        // to a string - brute force but simple
-        snprintf(sizeStr, sizeof(sizeStr), "%lld", s.st_size);
-        p += write_pax_header_entry(p, "size", sizeStr);
-
-        // fullname was generated above with the ustar paths
-        p += write_pax_header_entry(p, "path", fullname.string());
-
-        // Now we know how big the pax data is
-        int paxLen = p - paxData;
-
-        // Now build the pax *header* templated on the ustar header
-        memcpy(paxHeader, buf, 512);
-
-        String8 leaf = fullname.getPathLeaf();
-        memset(paxHeader, 0, 100);                  // rewrite the name area
-        snprintf(paxHeader, 100, "PaxHeader/%s", leaf.string());
-        memset(paxHeader + 345, 0, 155);            // rewrite the prefix area
-        strncpy(paxHeader + 345, prefix.string(), 155);
-
-        paxHeader[156] = 'x';                       // mark it as a pax extended header
-
-        // [ 124 :  12 ] size of pax extended header data
-        memset(paxHeader + 124, 0, 12);
-        snprintf(paxHeader + 124, 12, "%011o", p - paxData);
-
-        // Checksum and write the pax block header
-        calc_tar_checksum(paxHeader);
-        send_tarfile_chunk(writer, paxHeader, 512);
-
-        // Now write the pax data itself
-        int paxblocks = (paxLen + 511) / 512;
-        send_tarfile_chunk(writer, paxData, 512 * paxblocks);
-    }
-
-    // Checksum and write the 512-byte ustar file header block to the output
-    calc_tar_checksum(buf);
-    send_tarfile_chunk(writer, buf, 512);
-
-    // Now write the file data itself, for real files.  We honor tar's convention that
-    // only full 512-byte blocks are sent to write().
-    if (!isdir) {
-        off64_t toWrite = s.st_size;
-        while (toWrite > 0) {
-            size_t toRead = (toWrite < BUFSIZE) ? toWrite : BUFSIZE;
-            ssize_t nRead = read(fd, buf, toRead);
-            if (nRead < 0) {
-                err = errno;
-                ALOGE("Unable to read file [%s], err=%d (%s)", filepath.string(),
-                        err, strerror(err));
-                break;
-            } else if (nRead == 0) {
-                ALOGE("EOF but expect %lld more bytes in [%s]", (long long) toWrite,
-                        filepath.string());
-                err = EIO;
-                break;
-            }
-
-            // At EOF we might have a short block; NUL-pad that to a 512-byte multiple.  This
-            // depends on the OS guarantee that for ordinary files, read() will never return
-            // less than the number of bytes requested.
-            ssize_t partial = (nRead+512) % 512;
-            if (partial > 0) {
-                ssize_t remainder = 512 - partial;
-                memset(buf + nRead, 0, remainder);
-                nRead += remainder;
-            }
-            send_tarfile_chunk(writer, buf, nRead);
-            toWrite -= nRead;
-        }
-    }
-
-cleanup:
-    delete [] buf;
-done:
-    close(fd);
-    return err;
-}
-// end tarfile
-
-
-
-#define RESTORE_BUF_SIZE (8*1024)
-
-RestoreHelperBase::RestoreHelperBase()
-{
-    m_buf = malloc(RESTORE_BUF_SIZE);
-    m_loggedUnknownMetadata = false;
-}
-
-RestoreHelperBase::~RestoreHelperBase()
-{
-    free(m_buf);
-}
-
-status_t
-RestoreHelperBase::WriteFile(const String8& filename, BackupDataReader* in)
-{
-    ssize_t err;
-    size_t dataSize;
-    String8 key;
-    int fd;
-    void* buf = m_buf;
-    ssize_t amt;
-    int mode;
-    int crc;
-    struct stat st;
-    FileRec r;
-
-    err = in->ReadEntityHeader(&key, &dataSize);
-    if (err != NO_ERROR) {
-        return err;
-    }
-
-    // Get the metadata block off the head of the file entity and use that to
-    // set up the output file
-    file_metadata_v1 metadata;
-    amt = in->ReadEntityData(&metadata, sizeof(metadata));
-    if (amt != sizeof(metadata)) {
-        ALOGW("Could not read metadata for %s -- %ld / %s", filename.string(),
-                (long)amt, strerror(errno));
-        return EIO;
-    }
-    metadata.version = fromlel(metadata.version);
-    metadata.mode = fromlel(metadata.mode);
-    if (metadata.version > CURRENT_METADATA_VERSION) {
-        if (!m_loggedUnknownMetadata) {
-            m_loggedUnknownMetadata = true;
-            ALOGW("Restoring file with unsupported metadata version %d (currently %d)",
-                    metadata.version, CURRENT_METADATA_VERSION);
-        }
-    }
-    mode = metadata.mode;
-
-    // Write the file and compute the crc
-    crc = crc32(0L, Z_NULL, 0);
-    fd = open(filename.string(), O_CREAT|O_RDWR|O_TRUNC, mode);
-    if (fd == -1) {
-        ALOGW("Could not open file %s -- %s", filename.string(), strerror(errno));
-        return errno;
-    }
-    
-    while ((amt = in->ReadEntityData(buf, RESTORE_BUF_SIZE)) > 0) {
-        err = write(fd, buf, amt);
-        if (err != amt) {
-            close(fd);
-            ALOGW("Error '%s' writing '%s'", strerror(errno), filename.string());
-            return errno;
-        }
-        crc = crc32(crc, (Bytef*)buf, amt);
-    }
-
-    close(fd);
-
-    // Record for the snapshot
-    err = stat(filename.string(), &st);
-    if (err != 0) {
-        ALOGW("Error stating file that we just created %s", filename.string());
-        return errno;
-    }
-
-    r.file = filename;
-    r.deleted = false;
-    r.s.modTime_sec = st.st_mtime;
-    r.s.modTime_nsec = 0; // workaround sim breakage
-    //r.s.modTime_nsec = st.st_mtime_nsec;
-    r.s.mode = st.st_mode;
-    r.s.size = st.st_size;
-    r.s.crc32 = crc;
-
-    m_files.add(key, r);
-
-    return NO_ERROR;
-}
-
-status_t
-RestoreHelperBase::WriteSnapshot(int fd)
-{
-    return write_snapshot_file(fd, m_files);;
-}
-
-#if TEST_BACKUP_HELPERS
-
-#define SCRATCH_DIR "/data/backup_helper_test/"
-
-static int
-write_text_file(const char* path, const char* data)
-{
-    int amt;
-    int fd;
-    int len;
-
-    fd = creat(path, 0666);
-    if (fd == -1) {
-        fprintf(stderr, "creat %s failed\n", path);
-        return errno;
-    }
-
-    len = strlen(data);
-    amt = write(fd, data, len);
-    if (amt != len) {
-        fprintf(stderr, "error (%s) writing to file %s\n", strerror(errno), path);
-        return errno;
-    }
-
-    close(fd);
-
-    return 0;
-}
-
-static int
-compare_file(const char* path, const unsigned char* data, int len)
-{
-    int fd;
-    int amt;
-
-    fd = open(path, O_RDONLY);
-    if (fd == -1) {
-        fprintf(stderr, "compare_file error (%s) opening %s\n", strerror(errno), path);
-        return errno;
-    }
-
-    unsigned char* contents = (unsigned char*)malloc(len);
-    if (contents == NULL) {
-        fprintf(stderr, "malloc(%d) failed\n", len);
-        return ENOMEM;
-    }
-
-    bool sizesMatch = true;
-    amt = lseek(fd, 0, SEEK_END);
-    if (amt != len) {
-        fprintf(stderr, "compare_file file length should be %d, was %d\n", len, amt);
-        sizesMatch = false;
-    }
-    lseek(fd, 0, SEEK_SET);
-
-    int readLen = amt < len ? amt : len;
-    amt = read(fd, contents, readLen);
-    if (amt != readLen) {
-        fprintf(stderr, "compare_file read expected %d bytes but got %d\n", len, amt);
-    }
-
-    bool contentsMatch = true;
-    for (int i=0; i<readLen; i++) {
-        if (data[i] != contents[i]) {
-            if (contentsMatch) {
-                fprintf(stderr, "compare_file contents are different: (index, expected, actual)\n");
-                contentsMatch = false;
-            }
-            fprintf(stderr, "  [%-2d] %02x %02x\n", i, data[i], contents[i]);
-        }
-    }
-
-    free(contents);
-    return contentsMatch && sizesMatch ? 0 : 1;
-}
-
-int
-backup_helper_test_empty()
-{
-    int err;
-    int fd;
-    KeyedVector<String8,FileRec> snapshot;
-    const char* filename = SCRATCH_DIR "backup_helper_test_empty.snap";
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-
-    // write
-    fd = creat(filename, 0666);
-    if (fd == -1) {
-        fprintf(stderr, "error creating %s\n", filename);
-        return 1;
-    }
-
-    err = write_snapshot_file(fd, snapshot);
-
-    close(fd);
-
-    if (err != 0) {
-        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
-        return err;
-    }
-
-    static const unsigned char correct_data[] = {
-        0x53, 0x6e, 0x61, 0x70,  0x00, 0x00, 0x00, 0x00,
-        0x46, 0x69, 0x6c, 0x65,  0x10, 0x00, 0x00, 0x00
-    };
-
-    err = compare_file(filename, correct_data, sizeof(correct_data));
-    if (err != 0) {
-        return err;
-    }
-
-    // read
-    fd = open(filename, O_RDONLY);
-    if (fd == -1) {
-        fprintf(stderr, "error opening for read %s\n", filename);
-        return 1;
-    }
-
-    KeyedVector<String8,FileState> readSnapshot;
-    err = read_snapshot_file(fd, &readSnapshot);
-    if (err != 0) {
-        fprintf(stderr, "read_snapshot_file failed %d\n", err);
-        return err;
-    }
-
-    if (readSnapshot.size() != 0) {
-        fprintf(stderr, "readSnapshot should be length 0\n");
-        return 1;
-    }
-
-    return 0;
-}
-
-int
-backup_helper_test_four()
-{
-    int err;
-    int fd;
-    KeyedVector<String8,FileRec> snapshot;
-    const char* filename = SCRATCH_DIR "backup_helper_test_four.snap";
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-
-    // write
-    fd = creat(filename, 0666);
-    if (fd == -1) {
-        fprintf(stderr, "error opening %s\n", filename);
-        return 1;
-    }
-
-    String8 filenames[4];
-    FileState states[4];
-    FileRec r;
-    r.deleted = false;
-
-    states[0].modTime_sec = 0xfedcba98;
-    states[0].modTime_nsec = 0xdeadbeef;
-    states[0].mode = 0777; // decimal 511, hex 0x000001ff
-    states[0].size = 0xababbcbc;
-    states[0].crc32 = 0x12345678;
-    states[0].nameLen = -12;
-    r.s = states[0];
-    filenames[0] = String8("bytes_of_padding");
-    snapshot.add(filenames[0], r);
-
-    states[1].modTime_sec = 0x93400031;
-    states[1].modTime_nsec = 0xdeadbeef;
-    states[1].mode = 0666; // decimal 438, hex 0x000001b6
-    states[1].size = 0x88557766;
-    states[1].crc32 = 0x22334422;
-    states[1].nameLen = -1;
-    r.s = states[1];
-    filenames[1] = String8("bytes_of_padding3");
-    snapshot.add(filenames[1], r);
-
-    states[2].modTime_sec = 0x33221144;
-    states[2].modTime_nsec = 0xdeadbeef;
-    states[2].mode = 0744; // decimal 484, hex 0x000001e4
-    states[2].size = 0x11223344;
-    states[2].crc32 = 0x01122334;
-    states[2].nameLen = 0;
-    r.s = states[2];
-    filenames[2] = String8("bytes_of_padding_2");
-    snapshot.add(filenames[2], r);
-
-    states[3].modTime_sec = 0x33221144;
-    states[3].modTime_nsec = 0xdeadbeef;
-    states[3].mode = 0755; // decimal 493, hex 0x000001ed
-    states[3].size = 0x11223344;
-    states[3].crc32 = 0x01122334;
-    states[3].nameLen = 0;
-    r.s = states[3];
-    filenames[3] = String8("bytes_of_padding__1");
-    snapshot.add(filenames[3], r);
-
-    err = write_snapshot_file(fd, snapshot);
-
-    close(fd);
-
-    if (err != 0) {
-        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
-        return err;
-    }
-
-    static const unsigned char correct_data[] = {
-        // header
-        0x53, 0x6e, 0x61, 0x70,  0x04, 0x00, 0x00, 0x00,
-        0x46, 0x69, 0x6c, 0x65,  0xbc, 0x00, 0x00, 0x00,
-
-        // bytes_of_padding
-        0x98, 0xba, 0xdc, 0xfe,  0xef, 0xbe, 0xad, 0xde,
-        0xff, 0x01, 0x00, 0x00,  0xbc, 0xbc, 0xab, 0xab,
-        0x78, 0x56, 0x34, 0x12,  0x10, 0x00, 0x00, 0x00,
-        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
-        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
-
-        // bytes_of_padding3
-        0x31, 0x00, 0x40, 0x93,  0xef, 0xbe, 0xad, 0xde,
-        0xb6, 0x01, 0x00, 0x00,  0x66, 0x77, 0x55, 0x88,
-        0x22, 0x44, 0x33, 0x22,  0x11, 0x00, 0x00, 0x00,
-        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
-        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
-        0x33, 0xab, 0xab, 0xab,
-
-        // bytes of padding2
-        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
-        0xe4, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
-        0x34, 0x23, 0x12, 0x01,  0x12, 0x00, 0x00, 0x00,
-        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
-        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
-        0x5f, 0x32, 0xab, 0xab,
-
-        // bytes of padding3
-        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
-        0xed, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
-        0x34, 0x23, 0x12, 0x01,  0x13, 0x00, 0x00, 0x00,
-        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
-        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
-        0x5f, 0x5f, 0x31, 0xab
-    };
-
-    err = compare_file(filename, correct_data, sizeof(correct_data));
-    if (err != 0) {
-        return err;
-    }
-
-    // read
-    fd = open(filename, O_RDONLY);
-    if (fd == -1) {
-        fprintf(stderr, "error opening for read %s\n", filename);
-        return 1;
-    }
-
-
-    KeyedVector<String8,FileState> readSnapshot;
-    err = read_snapshot_file(fd, &readSnapshot);
-    if (err != 0) {
-        fprintf(stderr, "read_snapshot_file failed %d\n", err);
-        return err;
-    }
-
-    if (readSnapshot.size() != 4) {
-        fprintf(stderr, "readSnapshot should be length 4 is %d\n", readSnapshot.size());
-        return 1;
-    }
-
-    bool matched = true;
-    for (size_t i=0; i<readSnapshot.size(); i++) {
-        const String8& name = readSnapshot.keyAt(i);
-        const FileState state = readSnapshot.valueAt(i);
-
-        if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec
-                || states[i].modTime_nsec != state.modTime_nsec || states[i].mode != state.mode
-                || states[i].size != state.size || states[i].crc32 != states[i].crc32) {
-            fprintf(stderr, "state %d expected={%d/%d, 0x%08x, %04o, 0x%08x, %3d} '%s'\n"
-                            "          actual={%d/%d, 0x%08x, %04o, 0x%08x, %3d} '%s'\n", i,
-                    states[i].modTime_sec, states[i].modTime_nsec, states[i].mode, states[i].size,
-                    states[i].crc32, name.length(), filenames[i].string(),
-                    state.modTime_sec, state.modTime_nsec, state.mode, state.size, state.crc32,
-                    state.nameLen, name.string());
-            matched = false;
-        }
-    }
-
-    return matched ? 0 : 1;
-}
-
-// hexdump -v -e '"    " 8/1 " 0x%02x," "\n"' data_writer.data
-const unsigned char DATA_GOLDEN_FILE[] = {
-     0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,
-     0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,
-     0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
-     0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
-     0x6e, 0x67, 0x5f, 0x00, 0x44, 0x61, 0x74, 0x61,
-     0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
-     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
-     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
-     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
-     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
-     0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,
-     0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
-     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
-     0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
-     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
-     0x5f, 0x00, 0xbc, 0xbc, 0x44, 0x61, 0x74, 0x61,
-     0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
-     0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,
-     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00
-
-};
-const int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);
-
-static int
-test_write_header_and_entity(BackupDataWriter& writer, const char* str)
-{
-    int err;
-    String8 text(str);
-
-    err = writer.WriteEntityHeader(text, text.length()+1);
-    if (err != 0) {
-        fprintf(stderr, "WriteEntityHeader failed with %s\n", strerror(err));
-        return err;
-    }
-
-    err = writer.WriteEntityData(text.string(), text.length()+1);
-    if (err != 0) {
-        fprintf(stderr, "write failed for data '%s'\n", text.string());
-        return errno;
-    }
-
-    return err;
-}
-
-int
-backup_helper_test_data_writer()
-{
-    int err;
-    int fd;
-    const char* filename = SCRATCH_DIR "data_writer.data";
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-    mkdir(SCRATCH_DIR "data", 0777);
-
-    fd = creat(filename, 0666);
-    if (fd == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    BackupDataWriter writer(fd);
-
-    err = 0;
-    err |= test_write_header_and_entity(writer, "no_padding_");
-    err |= test_write_header_and_entity(writer, "padded_to__3");
-    err |= test_write_header_and_entity(writer, "padded_to_2__");
-    err |= test_write_header_and_entity(writer, "padded_to1");
-
-    close(fd);
-
-    err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
-    if (err != 0) {
-        return err;
-    }
-
-    return err;
-}
-
-int
-test_read_header_and_entity(BackupDataReader& reader, const char* str)
-{
-    int err;
-    int bufSize = strlen(str)+1;
-    char* buf = (char*)malloc(bufSize);
-    String8 string;
-    int cookie = 0x11111111;
-    size_t actualSize;
-    bool done;
-    int type;
-    ssize_t nRead;
-
-    // printf("\n\n---------- test_read_header_and_entity -- %s\n\n", str);
-
-    err = reader.ReadNextHeader(&done, &type);
-    if (done) {
-        fprintf(stderr, "should not be done yet\n");
-        goto finished;
-    }
-    if (err != 0) {
-        fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
-        goto finished;
-    }
-    if (type != BACKUP_HEADER_ENTITY_V1) {
-        err = EINVAL;
-        fprintf(stderr, "type=0x%08x expected 0x%08x\n", type, BACKUP_HEADER_ENTITY_V1);
-    }
-
-    err = reader.ReadEntityHeader(&string, &actualSize);
-    if (err != 0) {
-        fprintf(stderr, "ReadEntityHeader failed with %s\n", strerror(err));
-        goto finished;
-    }
-    if (string != str) {
-        fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.string());
-        err = EINVAL;
-        goto finished;
-    }
-    if ((int)actualSize != bufSize) {
-        fprintf(stderr, "ReadEntityHeader expected dataSize 0x%08x got 0x%08x\n", bufSize,
-                actualSize);
-        err = EINVAL;
-        goto finished;
-    }
-
-    nRead = reader.ReadEntityData(buf, bufSize);
-    if (nRead < 0) {
-        err = reader.Status();
-        fprintf(stderr, "ReadEntityData failed with %s\n", strerror(err));
-        goto finished;
-    }
-
-    if (0 != memcmp(buf, str, bufSize)) {
-        fprintf(stderr, "ReadEntityData expected '%s' but got something starting with "
-                "%02x %02x %02x %02x  '%c%c%c%c'\n", str, buf[0], buf[1], buf[2], buf[3],
-                buf[0], buf[1], buf[2], buf[3]);
-        err = EINVAL;
-        goto finished;
-    }
-
-    // The next read will confirm whether it got the right amount of data.
-
-finished:
-    if (err != NO_ERROR) {
-        fprintf(stderr, "test_read_header_and_entity failed with %s\n", strerror(err));
-    }
-    free(buf);
-    return err;
-}
-
-int
-backup_helper_test_data_reader()
-{
-    int err;
-    int fd;
-    const char* filename = SCRATCH_DIR "data_reader.data";
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-    mkdir(SCRATCH_DIR "data", 0777);
-
-    fd = creat(filename, 0666);
-    if (fd == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    err = write(fd, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
-    if (err != DATA_GOLDEN_FILE_SIZE) {
-        fprintf(stderr, "Error \"%s\" writing golden file %s\n", strerror(errno), filename);
-        return errno;
-    }
-
-    close(fd);
-
-    fd = open(filename, O_RDONLY);
-    if (fd == -1) {
-        fprintf(stderr, "Error \"%s\" opening golden file %s for read\n", strerror(errno),
-                filename);
-        return errno;
-    }
-
-    {
-        BackupDataReader reader(fd);
-
-        err = 0;
-
-        if (err == NO_ERROR) {
-            err = test_read_header_and_entity(reader, "no_padding_");
-        }
-
-        if (err == NO_ERROR) {
-            err = test_read_header_and_entity(reader, "padded_to__3");
-        }
-
-        if (err == NO_ERROR) {
-            err = test_read_header_and_entity(reader, "padded_to_2__");
-        }
-
-        if (err == NO_ERROR) {
-            err = test_read_header_and_entity(reader, "padded_to1");
-        }
-    }
-
-    close(fd);
-
-    return err;
-}
-
-static int
-get_mod_time(const char* filename, struct timeval times[2])
-{
-    int err;
-    struct stat64 st;
-    err = stat64(filename, &st);
-    if (err != 0) {
-        fprintf(stderr, "stat '%s' failed: %s\n", filename, strerror(errno));
-        return errno;
-    }
-    times[0].tv_sec = st.st_atime;
-    times[1].tv_sec = st.st_mtime;
-
-    // If st_atime is a macro then struct stat64 uses struct timespec
-    // to store the access and modif time values and typically
-    // st_*time_nsec is not defined. In glibc, this is controlled by
-    // __USE_MISC.
-#ifdef __USE_MISC
-#if !defined(st_atime) || defined(st_atime_nsec)
-#error "Check if this __USE_MISC conditional is still needed."
-#endif
-    times[0].tv_usec = st.st_atim.tv_nsec / 1000;
-    times[1].tv_usec = st.st_mtim.tv_nsec / 1000;
-#else
-    times[0].tv_usec = st.st_atime_nsec / 1000;
-    times[1].tv_usec = st.st_mtime_nsec / 1000;
-#endif
-
-    return 0;
-}
-
-int
-backup_helper_test_files()
-{
-    int err;
-    int oldSnapshotFD;
-    int dataStreamFD;
-    int newSnapshotFD;
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-    mkdir(SCRATCH_DIR "data", 0777);
-
-    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
-    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
-    write_text_file(SCRATCH_DIR "data/d", "d\ndd\n");
-    write_text_file(SCRATCH_DIR "data/e", "e\nee\n");
-    write_text_file(SCRATCH_DIR "data/f", "f\nff\n");
-    write_text_file(SCRATCH_DIR "data/h", "h\nhh\n");
-
-    char const* files_before[] = {
-        SCRATCH_DIR "data/b",
-        SCRATCH_DIR "data/c",
-        SCRATCH_DIR "data/d",
-        SCRATCH_DIR "data/e",
-        SCRATCH_DIR "data/f"
-    };
-
-    char const* keys_before[] = {
-        "data/b",
-        "data/c",
-        "data/d",
-        "data/e",
-        "data/f"
-    };
-
-    dataStreamFD = creat(SCRATCH_DIR "1.data", 0666);
-    if (dataStreamFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    newSnapshotFD = creat(SCRATCH_DIR "before.snap", 0666);
-    if (newSnapshotFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    {
-        BackupDataWriter dataStream(dataStreamFD);
-
-        err = back_up_files(-1, &dataStream, newSnapshotFD, files_before, keys_before, 5);
-        if (err != 0) {
-            return err;
-        }
-    }
-
-    close(dataStreamFD);
-    close(newSnapshotFD);
-
-    sleep(3);
-
-    struct timeval d_times[2];
-    struct timeval e_times[2];
-
-    err = get_mod_time(SCRATCH_DIR "data/d", d_times);
-    err |= get_mod_time(SCRATCH_DIR "data/e", e_times);
-    if (err != 0) {
-        return err;
-    }
-
-    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
-    unlink(SCRATCH_DIR "data/c");
-    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
-    write_text_file(SCRATCH_DIR "data/d", "dd\ndd\n");
-    utimes(SCRATCH_DIR "data/d", d_times);
-    write_text_file(SCRATCH_DIR "data/e", "z\nzz\n");
-    utimes(SCRATCH_DIR "data/e", e_times);
-    write_text_file(SCRATCH_DIR "data/g", "g\ngg\n");
-    unlink(SCRATCH_DIR "data/f");
-
-    char const* files_after[] = {
-        SCRATCH_DIR "data/a", // added
-        SCRATCH_DIR "data/b", // same
-        SCRATCH_DIR "data/c", // different mod time
-        SCRATCH_DIR "data/d", // different size (same mod time)
-        SCRATCH_DIR "data/e", // different contents (same mod time, same size)
-        SCRATCH_DIR "data/g"  // added
-    };
-
-    char const* keys_after[] = {
-        "data/a", // added
-        "data/b", // same
-        "data/c", // different mod time
-        "data/d", // different size (same mod time)
-        "data/e", // different contents (same mod time, same size)
-        "data/g"  // added
-    };
-
-    oldSnapshotFD = open(SCRATCH_DIR "before.snap", O_RDONLY);
-    if (oldSnapshotFD == -1) {
-        fprintf(stderr, "error opening: %s\n", strerror(errno));
-        return errno;
-    }
-
-    dataStreamFD = creat(SCRATCH_DIR "2.data", 0666);
-    if (dataStreamFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    newSnapshotFD = creat(SCRATCH_DIR "after.snap", 0666);
-    if (newSnapshotFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    {
-        BackupDataWriter dataStream(dataStreamFD);
-
-        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, files_after, keys_after, 6);
-        if (err != 0) {
-            return err;
-        }
-}
-
-    close(oldSnapshotFD);
-    close(dataStreamFD);
-    close(newSnapshotFD);
-
-    return 0;
-}
-
-int
-backup_helper_test_null_base()
-{
-    int err;
-    int oldSnapshotFD;
-    int dataStreamFD;
-    int newSnapshotFD;
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-    mkdir(SCRATCH_DIR "data", 0777);
-
-    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
-
-    char const* files[] = {
-        SCRATCH_DIR "data/a",
-    };
-
-    char const* keys[] = {
-        "a",
-    };
-
-    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
-    if (dataStreamFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
-    if (newSnapshotFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    {
-        BackupDataWriter dataStream(dataStreamFD);
-
-        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
-        if (err != 0) {
-            return err;
-        }
-    }
-
-    close(dataStreamFD);
-    close(newSnapshotFD);
-
-    return 0;
-}
-
-int
-backup_helper_test_missing_file()
-{
-    int err;
-    int oldSnapshotFD;
-    int dataStreamFD;
-    int newSnapshotFD;
-
-    system("rm -r " SCRATCH_DIR);
-    mkdir(SCRATCH_DIR, 0777);
-    mkdir(SCRATCH_DIR "data", 0777);
-
-    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
-
-    char const* files[] = {
-        SCRATCH_DIR "data/a",
-        SCRATCH_DIR "data/b",
-        SCRATCH_DIR "data/c",
-    };
-
-    char const* keys[] = {
-        "a",
-        "b",
-        "c",
-    };
-
-    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
-    if (dataStreamFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
-    if (newSnapshotFD == -1) {
-        fprintf(stderr, "error creating: %s\n", strerror(errno));
-        return errno;
-    }
-
-    {
-        BackupDataWriter dataStream(dataStreamFD);
-
-        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
-        if (err != 0) {
-            return err;
-        }
-    }
-
-    close(dataStreamFD);
-    close(newSnapshotFD);
-
-    return 0;
-}
-
-
-#endif // TEST_BACKUP_HELPERS
-
-}
diff --git a/libs/utils/ObbFile.cpp b/libs/utils/ObbFile.cpp
deleted file mode 100644
index 21e06c8..0000000
--- a/libs/utils/ObbFile.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2010 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 <errno.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define LOG_TAG "ObbFile"
-
-#include <androidfw/ObbFile.h>
-#include <utils/Compat.h>
-#include <utils/Log.h>
-
-//#define DEBUG 1
-
-#define kFooterTagSize 8  /* last two 32-bit integers */
-
-#define kFooterMinSize 33 /* 32-bit signature version (4 bytes)
-                           * 32-bit package version (4 bytes)
-                           * 32-bit flags (4 bytes)
-                           * 64-bit salt (8 bytes)
-                           * 32-bit package name size (4 bytes)
-                           * >=1-character package name (1 byte)
-                           * 32-bit footer size (4 bytes)
-                           * 32-bit footer marker (4 bytes)
-                           */
-
-#define kMaxBufSize    32768 /* Maximum file read buffer */
-
-#define kSignature     0x01059983U /* ObbFile signature */
-
-#define kSigVersion    1 /* We only know about signature version 1 */
-
-/* offsets in version 1 of the header */
-#define kPackageVersionOffset 4
-#define kFlagsOffset          8
-#define kSaltOffset           12
-#define kPackageNameLenOffset 20
-#define kPackageNameOffset    24
-
-/*
- * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
- * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
- * not already defined, then define it here.
- */
-#ifndef TEMP_FAILURE_RETRY
-/* Used to retry syscalls that can return EINTR. */
-#define TEMP_FAILURE_RETRY(exp) ({         \
-    typeof (exp) _rc;                      \
-    do {                                   \
-        _rc = (exp);                       \
-    } while (_rc == -1 && errno == EINTR); \
-    _rc; })
-#endif
-
-
-namespace android {
-
-ObbFile::ObbFile()
-        : mPackageName("")
-        , mVersion(-1)
-        , mFlags(0)
-{
-    memset(mSalt, 0, sizeof(mSalt));
-}
-
-ObbFile::~ObbFile() {
-}
-
-bool ObbFile::readFrom(const char* filename)
-{
-    int fd;
-    bool success = false;
-
-    fd = ::open(filename, O_RDONLY);
-    if (fd < 0) {
-        ALOGW("couldn't open file %s: %s", filename, strerror(errno));
-        goto out;
-    }
-    success = readFrom(fd);
-    close(fd);
-
-    if (!success) {
-        ALOGW("failed to read from %s (fd=%d)\n", filename, fd);
-    }
-
-out:
-    return success;
-}
-
-bool ObbFile::readFrom(int fd)
-{
-    if (fd < 0) {
-        ALOGW("attempt to read from invalid fd\n");
-        return false;
-    }
-
-    return parseObbFile(fd);
-}
-
-bool ObbFile::parseObbFile(int fd)
-{
-    off64_t fileLength = lseek64(fd, 0, SEEK_END);
-
-    if (fileLength < kFooterMinSize) {
-        if (fileLength < 0) {
-            ALOGW("error seeking in ObbFile: %s\n", strerror(errno));
-        } else {
-            ALOGW("file is only %lld (less than %d minimum)\n", fileLength, kFooterMinSize);
-        }
-        return false;
-    }
-
-    ssize_t actual;
-    size_t footerSize;
-
-    {
-        lseek64(fd, fileLength - kFooterTagSize, SEEK_SET);
-
-        char *footer = new char[kFooterTagSize];
-        actual = TEMP_FAILURE_RETRY(read(fd, footer, kFooterTagSize));
-        if (actual != kFooterTagSize) {
-            ALOGW("couldn't read footer signature: %s\n", strerror(errno));
-            return false;
-        }
-
-        unsigned int fileSig = get4LE((unsigned char*)footer + sizeof(int32_t));
-        if (fileSig != kSignature) {
-            ALOGW("footer didn't match magic string (expected 0x%08x; got 0x%08x)\n",
-                    kSignature, fileSig);
-            return false;
-        }
-
-        footerSize = get4LE((unsigned char*)footer);
-        if (footerSize > (size_t)fileLength - kFooterTagSize
-                || footerSize > kMaxBufSize) {
-            ALOGW("claimed footer size is too large (0x%08zx; file size is 0x%08llx)\n",
-                    footerSize, fileLength);
-            return false;
-        }
-
-        if (footerSize < (kFooterMinSize - kFooterTagSize)) {
-            ALOGW("claimed footer size is too small (0x%zx; minimum size is 0x%x)\n",
-                    footerSize, kFooterMinSize - kFooterTagSize);
-            return false;
-        }
-    }
-
-    off64_t fileOffset = fileLength - footerSize - kFooterTagSize;
-    if (lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {
-        ALOGW("seek %lld failed: %s\n", fileOffset, strerror(errno));
-        return false;
-    }
-
-    mFooterStart = fileOffset;
-
-    char* scanBuf = (char*)malloc(footerSize);
-    if (scanBuf == NULL) {
-        ALOGW("couldn't allocate scanBuf: %s\n", strerror(errno));
-        return false;
-    }
-
-    actual = TEMP_FAILURE_RETRY(read(fd, scanBuf, footerSize));
-    // readAmount is guaranteed to be less than kMaxBufSize
-    if (actual != (ssize_t)footerSize) {
-        ALOGI("couldn't read ObbFile footer: %s\n", strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-#ifdef DEBUG
-    for (int i = 0; i < footerSize; ++i) {
-        ALOGI("char: 0x%02x\n", scanBuf[i]);
-    }
-#endif
-
-    uint32_t sigVersion = get4LE((unsigned char*)scanBuf);
-    if (sigVersion != kSigVersion) {
-        ALOGW("Unsupported ObbFile version %d\n", sigVersion);
-        free(scanBuf);
-        return false;
-    }
-
-    mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);
-    mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset);
-
-    memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt));
-
-    size_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
-    if (packageNameLen == 0
-            || packageNameLen > (footerSize - kPackageNameOffset)) {
-        ALOGW("bad ObbFile package name length (0x%04zx; 0x%04zx possible)\n",
-                packageNameLen, footerSize - kPackageNameOffset);
-        free(scanBuf);
-        return false;
-    }
-
-    char* packageName = reinterpret_cast<char*>(scanBuf + kPackageNameOffset);
-    mPackageName = String8(const_cast<char*>(packageName), packageNameLen);
-
-    free(scanBuf);
-
-#ifdef DEBUG
-    ALOGI("Obb scan succeeded: packageName=%s, version=%d\n", mPackageName.string(), mVersion);
-#endif
-
-    return true;
-}
-
-bool ObbFile::writeTo(const char* filename)
-{
-    int fd;
-    bool success = false;
-
-    fd = ::open(filename, O_WRONLY);
-    if (fd < 0) {
-        goto out;
-    }
-    success = writeTo(fd);
-    close(fd);
-
-out:
-    if (!success) {
-        ALOGW("failed to write to %s: %s\n", filename, strerror(errno));
-    }
-    return success;
-}
-
-bool ObbFile::writeTo(int fd)
-{
-    if (fd < 0) {
-        return false;
-    }
-
-    lseek64(fd, 0, SEEK_END);
-
-    if (mPackageName.size() == 0 || mVersion == -1) {
-        ALOGW("tried to write uninitialized ObbFile data\n");
-        return false;
-    }
-
-    unsigned char intBuf[sizeof(uint32_t)+1];
-    memset(&intBuf, 0, sizeof(intBuf));
-
-    put4LE(intBuf, kSigVersion);
-    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
-        ALOGW("couldn't write signature version: %s\n", strerror(errno));
-        return false;
-    }
-
-    put4LE(intBuf, mVersion);
-    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
-        ALOGW("couldn't write package version\n");
-        return false;
-    }
-
-    put4LE(intBuf, mFlags);
-    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
-        ALOGW("couldn't write package version\n");
-        return false;
-    }
-
-    if (write(fd, mSalt, sizeof(mSalt)) != (ssize_t)sizeof(mSalt)) {
-        ALOGW("couldn't write salt: %s\n", strerror(errno));
-        return false;
-    }
-
-    size_t packageNameLen = mPackageName.size();
-    put4LE(intBuf, packageNameLen);
-    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
-        ALOGW("couldn't write package name length: %s\n", strerror(errno));
-        return false;
-    }
-
-    if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) {
-        ALOGW("couldn't write package name: %s\n", strerror(errno));
-        return false;
-    }
-
-    put4LE(intBuf, kPackageNameOffset + packageNameLen);
-    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
-        ALOGW("couldn't write footer size: %s\n", strerror(errno));
-        return false;
-    }
-
-    put4LE(intBuf, kSignature);
-    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
-        ALOGW("couldn't write footer magic signature: %s\n", strerror(errno));
-        return false;
-    }
-
-    return true;
-}
-
-bool ObbFile::removeFrom(const char* filename)
-{
-    int fd;
-    bool success = false;
-
-    fd = ::open(filename, O_RDWR);
-    if (fd < 0) {
-        goto out;
-    }
-    success = removeFrom(fd);
-    close(fd);
-
-out:
-    if (!success) {
-        ALOGW("failed to remove signature from %s: %s\n", filename, strerror(errno));
-    }
-    return success;
-}
-
-bool ObbFile::removeFrom(int fd)
-{
-    if (fd < 0) {
-        return false;
-    }
-
-    if (!readFrom(fd)) {
-        return false;
-    }
-
-    ftruncate(fd, mFooterStart);
-
-    return true;
-}
-
-}
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
deleted file mode 100644
index 07f3b16..0000000
--- a/libs/utils/ResourceTypes.cpp
+++ /dev/null
@@ -1,5580 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ResourceType"
-//#define LOG_NDEBUG 0
-
-#include <androidfw/ResourceTypes.h>
-#include <utils/Atomic.h>
-#include <utils/ByteOrder.h>
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <utils/String16.h>
-#include <utils/String8.h>
-#include <utils/TextOutput.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <memory.h>
-#include <ctype.h>
-#include <stdint.h>
-
-#ifndef INT32_MAX
-#define INT32_MAX ((int32_t)(2147483647))
-#endif
-
-#define POOL_NOISY(x) //x
-#define XML_NOISY(x) //x
-#define TABLE_NOISY(x) //x
-#define TABLE_GETENTRY(x) //x
-#define TABLE_SUPER_NOISY(x) //x
-#define LOAD_TABLE_NOISY(x) //x
-#define TABLE_THEME(x) //x
-
-namespace android {
-
-#ifdef HAVE_WINSOCK
-#undef  nhtol
-#undef  htonl
-
-#ifdef HAVE_LITTLE_ENDIAN
-#define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
-#define htonl(x)    ntohl(x)
-#define ntohs(x)    ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
-#define htons(x)    ntohs(x)
-#else
-#define ntohl(x)    (x)
-#define htonl(x)    (x)
-#define ntohs(x)    (x)
-#define htons(x)    (x)
-#endif
-#endif
-
-#define IDMAP_MAGIC         0x706d6469
-// size measured in sizeof(uint32_t)
-#define IDMAP_HEADER_SIZE (ResTable::IDMAP_HEADER_SIZE_BYTES / sizeof(uint32_t))
-
-static void printToLogFunc(void* cookie, const char* txt)
-{
-    ALOGV("%s", txt);
-}
-
-// Standard C isspace() is only required to look at the low byte of its input, so
-// produces incorrect results for UTF-16 characters.  For safety's sake, assume that
-// any high-byte UTF-16 code point is not whitespace.
-inline int isspace16(char16_t c) {
-    return (c < 0x0080 && isspace(c));
-}
-
-// range checked; guaranteed to NUL-terminate within the stated number of available slots
-// NOTE: if this truncates the dst string due to running out of space, no attempt is
-// made to avoid splitting surrogate pairs.
-static void strcpy16_dtoh(uint16_t* dst, const uint16_t* src, size_t avail)
-{
-    uint16_t* last = dst + avail - 1;
-    while (*src && (dst < last)) {
-        char16_t s = dtohs(*src);
-        *dst++ = s;
-        src++;
-    }
-    *dst = 0;
-}
-
-static status_t validate_chunk(const ResChunk_header* chunk,
-                               size_t minSize,
-                               const uint8_t* dataEnd,
-                               const char* name)
-{
-    const uint16_t headerSize = dtohs(chunk->headerSize);
-    const uint32_t size = dtohl(chunk->size);
-
-    if (headerSize >= minSize) {
-        if (headerSize <= size) {
-            if (((headerSize|size)&0x3) == 0) {
-                if ((ssize_t)size <= (dataEnd-((const uint8_t*)chunk))) {
-                    return NO_ERROR;
-                }
-                ALOGW("%s data size %p extends beyond resource end %p.",
-                     name, (void*)size,
-                     (void*)(dataEnd-((const uint8_t*)chunk)));
-                return BAD_TYPE;
-            }
-            ALOGW("%s size 0x%x or headerSize 0x%x is not on an integer boundary.",
-                 name, (int)size, (int)headerSize);
-            return BAD_TYPE;
-        }
-        ALOGW("%s size %p is smaller than header size %p.",
-             name, (void*)size, (void*)(int)headerSize);
-        return BAD_TYPE;
-    }
-    ALOGW("%s header size %p is too small.",
-         name, (void*)(int)headerSize);
-    return BAD_TYPE;
-}
-
-inline void Res_value::copyFrom_dtoh(const Res_value& src)
-{
-    size = dtohs(src.size);
-    res0 = src.res0;
-    dataType = src.dataType;
-    data = dtohl(src.data);
-}
-
-void Res_png_9patch::deviceToFile()
-{
-    for (int i = 0; i < numXDivs; i++) {
-        xDivs[i] = htonl(xDivs[i]);
-    }
-    for (int i = 0; i < numYDivs; i++) {
-        yDivs[i] = htonl(yDivs[i]);
-    }
-    paddingLeft = htonl(paddingLeft);
-    paddingRight = htonl(paddingRight);
-    paddingTop = htonl(paddingTop);
-    paddingBottom = htonl(paddingBottom);
-    for (int i=0; i<numColors; i++) {
-        colors[i] = htonl(colors[i]);
-    }
-}
-
-void Res_png_9patch::fileToDevice()
-{
-    for (int i = 0; i < numXDivs; i++) {
-        xDivs[i] = ntohl(xDivs[i]);
-    }
-    for (int i = 0; i < numYDivs; i++) {
-        yDivs[i] = ntohl(yDivs[i]);
-    }
-    paddingLeft = ntohl(paddingLeft);
-    paddingRight = ntohl(paddingRight);
-    paddingTop = ntohl(paddingTop);
-    paddingBottom = ntohl(paddingBottom);
-    for (int i=0; i<numColors; i++) {
-        colors[i] = ntohl(colors[i]);
-    }
-}
-
-size_t Res_png_9patch::serializedSize()
-{
-    // The size of this struct is 32 bytes on the 32-bit target system
-    // 4 * int8_t
-    // 4 * int32_t
-    // 3 * pointer
-    return 32
-            + numXDivs * sizeof(int32_t)
-            + numYDivs * sizeof(int32_t)
-            + numColors * sizeof(uint32_t);
-}
-
-void* Res_png_9patch::serialize()
-{
-    // Use calloc since we're going to leave a few holes in the data
-    // and want this to run cleanly under valgrind
-    void* newData = calloc(1, serializedSize());
-    serialize(newData);
-    return newData;
-}
-
-void Res_png_9patch::serialize(void * outData)
-{
-    char* data = (char*) outData;
-    memmove(data, &wasDeserialized, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
-    memmove(data + 12, &paddingLeft, 16);   // copy paddingXXXX
-    data += 32;
-
-    memmove(data, this->xDivs, numXDivs * sizeof(int32_t));
-    data +=  numXDivs * sizeof(int32_t);
-    memmove(data, this->yDivs, numYDivs * sizeof(int32_t));
-    data +=  numYDivs * sizeof(int32_t);
-    memmove(data, this->colors, numColors * sizeof(uint32_t));
-}
-
-static void deserializeInternal(const void* inData, Res_png_9patch* outData) {
-    char* patch = (char*) inData;
-    if (inData != outData) {
-        memmove(&outData->wasDeserialized, patch, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
-        memmove(&outData->paddingLeft, patch + 12, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
-    }
-    outData->wasDeserialized = true;
-    char* data = (char*)outData;
-    data +=  sizeof(Res_png_9patch);
-    outData->xDivs = (int32_t*) data;
-    data +=  outData->numXDivs * sizeof(int32_t);
-    outData->yDivs = (int32_t*) data;
-    data +=  outData->numYDivs * sizeof(int32_t);
-    outData->colors = (uint32_t*) data;
-}
-
-static bool assertIdmapHeader(const uint32_t* map, size_t sizeBytes)
-{
-    if (sizeBytes < ResTable::IDMAP_HEADER_SIZE_BYTES) {
-        ALOGW("idmap assertion failed: size=%d bytes\n", (int)sizeBytes);
-        return false;
-    }
-    if (*map != htodl(IDMAP_MAGIC)) { // htodl: map data expected to be in correct endianess
-        ALOGW("idmap assertion failed: invalid magic found (is 0x%08x, expected 0x%08x)\n",
-             *map, htodl(IDMAP_MAGIC));
-        return false;
-    }
-    return true;
-}
-
-static status_t idmapLookup(const uint32_t* map, size_t sizeBytes, uint32_t key, uint32_t* outValue)
-{
-    // see README for details on the format of map
-    if (!assertIdmapHeader(map, sizeBytes)) {
-        return UNKNOWN_ERROR;
-    }
-    map = map + IDMAP_HEADER_SIZE; // skip ahead to data segment
-    // size of data block, in uint32_t
-    const size_t size = (sizeBytes - ResTable::IDMAP_HEADER_SIZE_BYTES) / sizeof(uint32_t);
-    const uint32_t type = Res_GETTYPE(key) + 1; // add one, idmap stores "public" type id
-    const uint32_t entry = Res_GETENTRY(key);
-    const uint32_t typeCount = *map;
-
-    if (type > typeCount) {
-        ALOGW("Resource ID map: type=%d exceeds number of types=%d\n", type, typeCount);
-        return UNKNOWN_ERROR;
-    }
-    if (typeCount > size) {
-        ALOGW("Resource ID map: number of types=%d exceeds size of map=%d\n", typeCount, (int)size);
-        return UNKNOWN_ERROR;
-    }
-    const uint32_t typeOffset = map[type];
-    if (typeOffset == 0) {
-        *outValue = 0;
-        return NO_ERROR;
-    }
-    if (typeOffset + 1 > size) {
-        ALOGW("Resource ID map: type offset=%d exceeds reasonable value, size of map=%d\n",
-             typeOffset, (int)size);
-        return UNKNOWN_ERROR;
-    }
-    const uint32_t entryCount = map[typeOffset];
-    const uint32_t entryOffset = map[typeOffset + 1];
-    if (entryCount == 0 || entry < entryOffset || entry - entryOffset > entryCount - 1) {
-        *outValue = 0;
-        return NO_ERROR;
-    }
-    const uint32_t index = typeOffset + 2 + entry - entryOffset;
-    if (index > size) {
-        ALOGW("Resource ID map: entry index=%d exceeds size of map=%d\n", index, (int)size);
-        *outValue = 0;
-        return NO_ERROR;
-    }
-    *outValue = map[index];
-
-    return NO_ERROR;
-}
-
-static status_t getIdmapPackageId(const uint32_t* map, size_t mapSize, uint32_t *outId)
-{
-    if (!assertIdmapHeader(map, mapSize)) {
-        return UNKNOWN_ERROR;
-    }
-    const uint32_t* p = map + IDMAP_HEADER_SIZE + 1;
-    while (*p == 0) {
-        ++p;
-    }
-    *outId = (map[*p + IDMAP_HEADER_SIZE + 2] >> 24) & 0x000000ff;
-    return NO_ERROR;
-}
-
-Res_png_9patch* Res_png_9patch::deserialize(const void* inData)
-{
-    if (sizeof(void*) != sizeof(int32_t)) {
-        ALOGE("Cannot deserialize on non 32-bit system\n");
-        return NULL;
-    }
-    deserializeInternal(inData, (Res_png_9patch*) inData);
-    return (Res_png_9patch*) inData;
-}
-
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-
-ResStringPool::ResStringPool()
-    : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)
-{
-}
-
-ResStringPool::ResStringPool(const void* data, size_t size, bool copyData)
-    : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)
-{
-    setTo(data, size, copyData);
-}
-
-ResStringPool::~ResStringPool()
-{
-    uninit();
-}
-
-status_t ResStringPool::setTo(const void* data, size_t size, bool copyData)
-{
-    if (!data || !size) {
-        return (mError=BAD_TYPE);
-    }
-
-    uninit();
-
-    const bool notDeviceEndian = htods(0xf0) != 0xf0;
-
-    if (copyData || notDeviceEndian) {
-        mOwnedData = malloc(size);
-        if (mOwnedData == NULL) {
-            return (mError=NO_MEMORY);
-        }
-        memcpy(mOwnedData, data, size);
-        data = mOwnedData;
-    }
-
-    mHeader = (const ResStringPool_header*)data;
-
-    if (notDeviceEndian) {
-        ResStringPool_header* h = const_cast<ResStringPool_header*>(mHeader);
-        h->header.headerSize = dtohs(mHeader->header.headerSize);
-        h->header.type = dtohs(mHeader->header.type);
-        h->header.size = dtohl(mHeader->header.size);
-        h->stringCount = dtohl(mHeader->stringCount);
-        h->styleCount = dtohl(mHeader->styleCount);
-        h->flags = dtohl(mHeader->flags);
-        h->stringsStart = dtohl(mHeader->stringsStart);
-        h->stylesStart = dtohl(mHeader->stylesStart);
-    }
-
-    if (mHeader->header.headerSize > mHeader->header.size
-            || mHeader->header.size > size) {
-        ALOGW("Bad string block: header size %d or total size %d is larger than data size %d\n",
-                (int)mHeader->header.headerSize, (int)mHeader->header.size, (int)size);
-        return (mError=BAD_TYPE);
-    }
-    mSize = mHeader->header.size;
-    mEntries = (const uint32_t*)
-        (((const uint8_t*)data)+mHeader->header.headerSize);
-
-    if (mHeader->stringCount > 0) {
-        if ((mHeader->stringCount*sizeof(uint32_t) < mHeader->stringCount)  // uint32 overflow?
-            || (mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t)))
-                > size) {
-            ALOGW("Bad string block: entry of %d items extends past data size %d\n",
-                    (int)(mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t))),
-                    (int)size);
-            return (mError=BAD_TYPE);
-        }
-
-        size_t charSize;
-        if (mHeader->flags&ResStringPool_header::UTF8_FLAG) {
-            charSize = sizeof(uint8_t);
-            mCache = (char16_t**)calloc(mHeader->stringCount, sizeof(char16_t**));
-        } else {
-            charSize = sizeof(char16_t);
-        }
-
-        mStrings = (const void*)
-            (((const uint8_t*)data)+mHeader->stringsStart);
-        if (mHeader->stringsStart >= (mHeader->header.size-sizeof(uint16_t))) {
-            ALOGW("Bad string block: string pool starts at %d, after total size %d\n",
-                    (int)mHeader->stringsStart, (int)mHeader->header.size);
-            return (mError=BAD_TYPE);
-        }
-        if (mHeader->styleCount == 0) {
-            mStringPoolSize =
-                (mHeader->header.size-mHeader->stringsStart)/charSize;
-        } else {
-            // check invariant: styles starts before end of data
-            if (mHeader->stylesStart >= (mHeader->header.size-sizeof(uint16_t))) {
-                ALOGW("Bad style block: style block starts at %d past data size of %d\n",
-                    (int)mHeader->stylesStart, (int)mHeader->header.size);
-                return (mError=BAD_TYPE);
-            }
-            // check invariant: styles follow the strings
-            if (mHeader->stylesStart <= mHeader->stringsStart) {
-                ALOGW("Bad style block: style block starts at %d, before strings at %d\n",
-                    (int)mHeader->stylesStart, (int)mHeader->stringsStart);
-                return (mError=BAD_TYPE);
-            }
-            mStringPoolSize =
-                (mHeader->stylesStart-mHeader->stringsStart)/charSize;
-        }
-
-        // check invariant: stringCount > 0 requires a string pool to exist
-        if (mStringPoolSize == 0) {
-            ALOGW("Bad string block: stringCount is %d but pool size is 0\n", (int)mHeader->stringCount);
-            return (mError=BAD_TYPE);
-        }
-
-        if (notDeviceEndian) {
-            size_t i;
-            uint32_t* e = const_cast<uint32_t*>(mEntries);
-            for (i=0; i<mHeader->stringCount; i++) {
-                e[i] = dtohl(mEntries[i]);
-            }
-            if (!(mHeader->flags&ResStringPool_header::UTF8_FLAG)) {
-                const char16_t* strings = (const char16_t*)mStrings;
-                char16_t* s = const_cast<char16_t*>(strings);
-                for (i=0; i<mStringPoolSize; i++) {
-                    s[i] = dtohs(strings[i]);
-                }
-            }
-        }
-
-        if ((mHeader->flags&ResStringPool_header::UTF8_FLAG &&
-                ((uint8_t*)mStrings)[mStringPoolSize-1] != 0) ||
-                (!mHeader->flags&ResStringPool_header::UTF8_FLAG &&
-                ((char16_t*)mStrings)[mStringPoolSize-1] != 0)) {
-            ALOGW("Bad string block: last string is not 0-terminated\n");
-            return (mError=BAD_TYPE);
-        }
-    } else {
-        mStrings = NULL;
-        mStringPoolSize = 0;
-    }
-
-    if (mHeader->styleCount > 0) {
-        mEntryStyles = mEntries + mHeader->stringCount;
-        // invariant: integer overflow in calculating mEntryStyles
-        if (mEntryStyles < mEntries) {
-            ALOGW("Bad string block: integer overflow finding styles\n");
-            return (mError=BAD_TYPE);
-        }
-
-        if (((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader) > (int)size) {
-            ALOGW("Bad string block: entry of %d styles extends past data size %d\n",
-                    (int)((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader),
-                    (int)size);
-            return (mError=BAD_TYPE);
-        }
-        mStyles = (const uint32_t*)
-            (((const uint8_t*)data)+mHeader->stylesStart);
-        if (mHeader->stylesStart >= mHeader->header.size) {
-            ALOGW("Bad string block: style pool starts %d, after total size %d\n",
-                    (int)mHeader->stylesStart, (int)mHeader->header.size);
-            return (mError=BAD_TYPE);
-        }
-        mStylePoolSize =
-            (mHeader->header.size-mHeader->stylesStart)/sizeof(uint32_t);
-
-        if (notDeviceEndian) {
-            size_t i;
-            uint32_t* e = const_cast<uint32_t*>(mEntryStyles);
-            for (i=0; i<mHeader->styleCount; i++) {
-                e[i] = dtohl(mEntryStyles[i]);
-            }
-            uint32_t* s = const_cast<uint32_t*>(mStyles);
-            for (i=0; i<mStylePoolSize; i++) {
-                s[i] = dtohl(mStyles[i]);
-            }
-        }
-
-        const ResStringPool_span endSpan = {
-            { htodl(ResStringPool_span::END) },
-            htodl(ResStringPool_span::END), htodl(ResStringPool_span::END)
-        };
-        if (memcmp(&mStyles[mStylePoolSize-(sizeof(endSpan)/sizeof(uint32_t))],
-                   &endSpan, sizeof(endSpan)) != 0) {
-            ALOGW("Bad string block: last style is not 0xFFFFFFFF-terminated\n");
-            return (mError=BAD_TYPE);
-        }
-    } else {
-        mEntryStyles = NULL;
-        mStyles = NULL;
-        mStylePoolSize = 0;
-    }
-
-    return (mError=NO_ERROR);
-}
-
-status_t ResStringPool::getError() const
-{
-    return mError;
-}
-
-void ResStringPool::uninit()
-{
-    mError = NO_INIT;
-    if (mOwnedData) {
-        free(mOwnedData);
-        mOwnedData = NULL;
-    }
-    if (mHeader != NULL && mCache != NULL) {
-        for (size_t x = 0; x < mHeader->stringCount; x++) {
-            if (mCache[x] != NULL) {
-                free(mCache[x]);
-                mCache[x] = NULL;
-            }
-        }
-        free(mCache);
-        mCache = NULL;
-    }
-}
-
-/**
- * Strings in UTF-16 format have length indicated by a length encoded in the
- * stored data. It is either 1 or 2 characters of length data. This allows a
- * maximum length of 0x7FFFFFF (2147483647 bytes), but if you're storing that
- * much data in a string, you're abusing them.
- *
- * If the high bit is set, then there are two characters or 4 bytes of length
- * data encoded. In that case, drop the high bit of the first character and
- * add it together with the next character.
- */
-static inline size_t
-decodeLength(const char16_t** str)
-{
-    size_t len = **str;
-    if ((len & 0x8000) != 0) {
-        (*str)++;
-        len = ((len & 0x7FFF) << 16) | **str;
-    }
-    (*str)++;
-    return len;
-}
-
-/**
- * Strings in UTF-8 format have length indicated by a length encoded in the
- * stored data. It is either 1 or 2 characters of length data. This allows a
- * maximum length of 0x7FFF (32767 bytes), but you should consider storing
- * text in another way if you're using that much data in a single string.
- *
- * If the high bit is set, then there are two characters or 2 bytes of length
- * data encoded. In that case, drop the high bit of the first character and
- * add it together with the next character.
- */
-static inline size_t
-decodeLength(const uint8_t** str)
-{
-    size_t len = **str;
-    if ((len & 0x80) != 0) {
-        (*str)++;
-        len = ((len & 0x7F) << 8) | **str;
-    }
-    (*str)++;
-    return len;
-}
-
-const uint16_t* ResStringPool::stringAt(size_t idx, size_t* u16len) const
-{
-    if (mError == NO_ERROR && idx < mHeader->stringCount) {
-        const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0;
-        const uint32_t off = mEntries[idx]/(isUTF8?sizeof(char):sizeof(char16_t));
-        if (off < (mStringPoolSize-1)) {
-            if (!isUTF8) {
-                const char16_t* strings = (char16_t*)mStrings;
-                const char16_t* str = strings+off;
-
-                *u16len = decodeLength(&str);
-                if ((uint32_t)(str+*u16len-strings) < mStringPoolSize) {
-                    return str;
-                } else {
-                    ALOGW("Bad string block: string #%d extends to %d, past end at %d\n",
-                            (int)idx, (int)(str+*u16len-strings), (int)mStringPoolSize);
-                }
-            } else {
-                const uint8_t* strings = (uint8_t*)mStrings;
-                const uint8_t* u8str = strings+off;
-
-                *u16len = decodeLength(&u8str);
-                size_t u8len = decodeLength(&u8str);
-
-                // encLen must be less than 0x7FFF due to encoding.
-                if ((uint32_t)(u8str+u8len-strings) < mStringPoolSize) {
-                    AutoMutex lock(mDecodeLock);
-
-                    if (mCache[idx] != NULL) {
-                        return mCache[idx];
-                    }
-
-                    ssize_t actualLen = utf8_to_utf16_length(u8str, u8len);
-                    if (actualLen < 0 || (size_t)actualLen != *u16len) {
-                        ALOGW("Bad string block: string #%lld decoded length is not correct "
-                                "%lld vs %llu\n",
-                                (long long)idx, (long long)actualLen, (long long)*u16len);
-                        return NULL;
-                    }
-
-                    char16_t *u16str = (char16_t *)calloc(*u16len+1, sizeof(char16_t));
-                    if (!u16str) {
-                        ALOGW("No memory when trying to allocate decode cache for string #%d\n",
-                                (int)idx);
-                        return NULL;
-                    }
-
-                    utf8_to_utf16(u8str, u8len, u16str);
-                    mCache[idx] = u16str;
-                    return u16str;
-                } else {
-                    ALOGW("Bad string block: string #%lld extends to %lld, past end at %lld\n",
-                            (long long)idx, (long long)(u8str+u8len-strings),
-                            (long long)mStringPoolSize);
-                }
-            }
-        } else {
-            ALOGW("Bad string block: string #%d entry is at %d, past end at %d\n",
-                    (int)idx, (int)(off*sizeof(uint16_t)),
-                    (int)(mStringPoolSize*sizeof(uint16_t)));
-        }
-    }
-    return NULL;
-}
-
-const char* ResStringPool::string8At(size_t idx, size_t* outLen) const
-{
-    if (mError == NO_ERROR && idx < mHeader->stringCount) {
-        const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0;
-        const uint32_t off = mEntries[idx]/(isUTF8?sizeof(char):sizeof(char16_t));
-        if (off < (mStringPoolSize-1)) {
-            if (isUTF8) {
-                const uint8_t* strings = (uint8_t*)mStrings;
-                const uint8_t* str = strings+off;
-                *outLen = decodeLength(&str);
-                size_t encLen = decodeLength(&str);
-                if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {
-                    return (const char*)str;
-                } else {
-                    ALOGW("Bad string block: string #%d extends to %d, past end at %d\n",
-                            (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize);
-                }
-            }
-        } else {
-            ALOGW("Bad string block: string #%d entry is at %d, past end at %d\n",
-                    (int)idx, (int)(off*sizeof(uint16_t)),
-                    (int)(mStringPoolSize*sizeof(uint16_t)));
-        }
-    }
-    return NULL;
-}
-
-const String8 ResStringPool::string8ObjectAt(size_t idx) const
-{
-    size_t len;
-    const char *str = (const char*)string8At(idx, &len);
-    if (str != NULL) {
-        return String8(str);
-    }
-    return String8(stringAt(idx, &len));
-}
-
-const ResStringPool_span* ResStringPool::styleAt(const ResStringPool_ref& ref) const
-{
-    return styleAt(ref.index);
-}
-
-const ResStringPool_span* ResStringPool::styleAt(size_t idx) const
-{
-    if (mError == NO_ERROR && idx < mHeader->styleCount) {
-        const uint32_t off = (mEntryStyles[idx]/sizeof(uint32_t));
-        if (off < mStylePoolSize) {
-            return (const ResStringPool_span*)(mStyles+off);
-        } else {
-            ALOGW("Bad string block: style #%d entry is at %d, past end at %d\n",
-                    (int)idx, (int)(off*sizeof(uint32_t)),
-                    (int)(mStylePoolSize*sizeof(uint32_t)));
-        }
-    }
-    return NULL;
-}
-
-ssize_t ResStringPool::indexOfString(const char16_t* str, size_t strLen) const
-{
-    if (mError != NO_ERROR) {
-        return mError;
-    }
-
-    size_t len;
-
-    // TODO optimize searching for UTF-8 strings taking into account
-    // the cache fill to determine when to convert the searched-for
-    // string key to UTF-8.
-
-    if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
-        // Do a binary search for the string...
-        ssize_t l = 0;
-        ssize_t h = mHeader->stringCount-1;
-
-        ssize_t mid;
-        while (l <= h) {
-            mid = l + (h - l)/2;
-            const char16_t* s = stringAt(mid, &len);
-            int c = s ? strzcmp16(s, len, str, strLen) : -1;
-            POOL_NOISY(printf("Looking for %s, at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
-                         String8(str).string(),
-                         String8(s).string(),
-                         c, (int)l, (int)mid, (int)h));
-            if (c == 0) {
-                return mid;
-            } else if (c < 0) {
-                l = mid + 1;
-            } else {
-                h = mid - 1;
-            }
-        }
-    } else {
-        // It is unusual to get the ID from an unsorted string block...
-        // most often this happens because we want to get IDs for style
-        // span tags; since those always appear at the end of the string
-        // block, start searching at the back.
-        for (int i=mHeader->stringCount-1; i>=0; i--) {
-            const char16_t* s = stringAt(i, &len);
-            POOL_NOISY(printf("Looking for %s, at %s, i=%d\n",
-                         String8(str, strLen).string(),
-                         String8(s).string(),
-                         i));
-            if (s && strzcmp16(s, len, str, strLen) == 0) {
-                return i;
-            }
-        }
-    }
-
-    return NAME_NOT_FOUND;
-}
-
-size_t ResStringPool::size() const
-{
-    return (mError == NO_ERROR) ? mHeader->stringCount : 0;
-}
-
-size_t ResStringPool::styleCount() const
-{
-    return (mError == NO_ERROR) ? mHeader->styleCount : 0;
-}
-
-size_t ResStringPool::bytes() const
-{
-    return (mError == NO_ERROR) ? mHeader->header.size : 0;
-}
-
-bool ResStringPool::isSorted() const
-{
-    return (mHeader->flags&ResStringPool_header::SORTED_FLAG)!=0;
-}
-
-bool ResStringPool::isUTF8() const
-{
-    return (mHeader->flags&ResStringPool_header::UTF8_FLAG)!=0;
-}
-
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-
-ResXMLParser::ResXMLParser(const ResXMLTree& tree)
-    : mTree(tree), mEventCode(BAD_DOCUMENT)
-{
-}
-
-void ResXMLParser::restart()
-{
-    mCurNode = NULL;
-    mEventCode = mTree.mError == NO_ERROR ? START_DOCUMENT : BAD_DOCUMENT;
-}
-const ResStringPool& ResXMLParser::getStrings() const
-{
-    return mTree.mStrings;
-}
-
-ResXMLParser::event_code_t ResXMLParser::getEventType() const
-{
-    return mEventCode;
-}
-
-ResXMLParser::event_code_t ResXMLParser::next()
-{
-    if (mEventCode == START_DOCUMENT) {
-        mCurNode = mTree.mRootNode;
-        mCurExt = mTree.mRootExt;
-        return (mEventCode=mTree.mRootCode);
-    } else if (mEventCode >= FIRST_CHUNK_CODE) {
-        return nextNode();
-    }
-    return mEventCode;
-}
-
-int32_t ResXMLParser::getCommentID() const
-{
-    return mCurNode != NULL ? dtohl(mCurNode->comment.index) : -1;
-}
-
-const uint16_t* ResXMLParser::getComment(size_t* outLen) const
-{
-    int32_t id = getCommentID();
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-uint32_t ResXMLParser::getLineNumber() const
-{
-    return mCurNode != NULL ? dtohl(mCurNode->lineNumber) : -1;
-}
-
-int32_t ResXMLParser::getTextID() const
-{
-    if (mEventCode == TEXT) {
-        return dtohl(((const ResXMLTree_cdataExt*)mCurExt)->data.index);
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getText(size_t* outLen) const
-{
-    int32_t id = getTextID();
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-ssize_t ResXMLParser::getTextValue(Res_value* outValue) const
-{
-    if (mEventCode == TEXT) {
-        outValue->copyFrom_dtoh(((const ResXMLTree_cdataExt*)mCurExt)->typedData);
-        return sizeof(Res_value);
-    }
-    return BAD_TYPE;
-}
-
-int32_t ResXMLParser::getNamespacePrefixID() const
-{
-    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {
-        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->prefix.index);
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const
-{
-    int32_t id = getNamespacePrefixID();
-    //printf("prefix=%d  event=%p\n", id, mEventCode);
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-int32_t ResXMLParser::getNamespaceUriID() const
-{
-    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {
-        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->uri.index);
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const
-{
-    int32_t id = getNamespaceUriID();
-    //printf("uri=%d  event=%p\n", id, mEventCode);
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-int32_t ResXMLParser::getElementNamespaceID() const
-{
-    if (mEventCode == START_TAG) {
-        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->ns.index);
-    }
-    if (mEventCode == END_TAG) {
-        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->ns.index);
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getElementNamespace(size_t* outLen) const
-{
-    int32_t id = getElementNamespaceID();
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-int32_t ResXMLParser::getElementNameID() const
-{
-    if (mEventCode == START_TAG) {
-        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->name.index);
-    }
-    if (mEventCode == END_TAG) {
-        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->name.index);
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getElementName(size_t* outLen) const
-{
-    int32_t id = getElementNameID();
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-size_t ResXMLParser::getAttributeCount() const
-{
-    if (mEventCode == START_TAG) {
-        return dtohs(((const ResXMLTree_attrExt*)mCurExt)->attributeCount);
-    }
-    return 0;
-}
-
-int32_t ResXMLParser::getAttributeNamespaceID(size_t idx) const
-{
-    if (mEventCode == START_TAG) {
-        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
-        if (idx < dtohs(tag->attributeCount)) {
-            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
-                (((const uint8_t*)tag)
-                 + dtohs(tag->attributeStart)
-                 + (dtohs(tag->attributeSize)*idx));
-            return dtohl(attr->ns.index);
-        }
-    }
-    return -2;
-}
-
-const uint16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) const
-{
-    int32_t id = getAttributeNamespaceID(idx);
-    //printf("attribute namespace=%d  idx=%d  event=%p\n", id, idx, mEventCode);
-    //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id));
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-int32_t ResXMLParser::getAttributeNameID(size_t idx) const
-{
-    if (mEventCode == START_TAG) {
-        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
-        if (idx < dtohs(tag->attributeCount)) {
-            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
-                (((const uint8_t*)tag)
-                 + dtohs(tag->attributeStart)
-                 + (dtohs(tag->attributeSize)*idx));
-            return dtohl(attr->name.index);
-        }
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const
-{
-    int32_t id = getAttributeNameID(idx);
-    //printf("attribute name=%d  idx=%d  event=%p\n", id, idx, mEventCode);
-    //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id));
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-uint32_t ResXMLParser::getAttributeNameResID(size_t idx) const
-{
-    int32_t id = getAttributeNameID(idx);
-    if (id >= 0 && (size_t)id < mTree.mNumResIds) {
-        return dtohl(mTree.mResIds[id]);
-    }
-    return 0;
-}
-
-int32_t ResXMLParser::getAttributeValueStringID(size_t idx) const
-{
-    if (mEventCode == START_TAG) {
-        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
-        if (idx < dtohs(tag->attributeCount)) {
-            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
-                (((const uint8_t*)tag)
-                 + dtohs(tag->attributeStart)
-                 + (dtohs(tag->attributeSize)*idx));
-            return dtohl(attr->rawValue.index);
-        }
-    }
-    return -1;
-}
-
-const uint16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen) const
-{
-    int32_t id = getAttributeValueStringID(idx);
-    //XML_NOISY(printf("getAttributeValue 0x%x=0x%x\n", idx, id));
-    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
-}
-
-int32_t ResXMLParser::getAttributeDataType(size_t idx) const
-{
-    if (mEventCode == START_TAG) {
-        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
-        if (idx < dtohs(tag->attributeCount)) {
-            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
-                (((const uint8_t*)tag)
-                 + dtohs(tag->attributeStart)
-                 + (dtohs(tag->attributeSize)*idx));
-            return attr->typedValue.dataType;
-        }
-    }
-    return Res_value::TYPE_NULL;
-}
-
-int32_t ResXMLParser::getAttributeData(size_t idx) const
-{
-    if (mEventCode == START_TAG) {
-        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
-        if (idx < dtohs(tag->attributeCount)) {
-            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
-                (((const uint8_t*)tag)
-                 + dtohs(tag->attributeStart)
-                 + (dtohs(tag->attributeSize)*idx));
-            return dtohl(attr->typedValue.data);
-        }
-    }
-    return 0;
-}
-
-ssize_t ResXMLParser::getAttributeValue(size_t idx, Res_value* outValue) const
-{
-    if (mEventCode == START_TAG) {
-        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
-        if (idx < dtohs(tag->attributeCount)) {
-            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
-                (((const uint8_t*)tag)
-                 + dtohs(tag->attributeStart)
-                 + (dtohs(tag->attributeSize)*idx));
-            outValue->copyFrom_dtoh(attr->typedValue);
-            return sizeof(Res_value);
-        }
-    }
-    return BAD_TYPE;
-}
-
-ssize_t ResXMLParser::indexOfAttribute(const char* ns, const char* attr) const
-{
-    String16 nsStr(ns != NULL ? ns : "");
-    String16 attrStr(attr);
-    return indexOfAttribute(ns ? nsStr.string() : NULL, ns ? nsStr.size() : 0,
-                            attrStr.string(), attrStr.size());
-}
-
-ssize_t ResXMLParser::indexOfAttribute(const char16_t* ns, size_t nsLen,
-                                       const char16_t* attr, size_t attrLen) const
-{
-    if (mEventCode == START_TAG) {
-        const size_t N = getAttributeCount();
-        for (size_t i=0; i<N; i++) {
-            size_t curNsLen, curAttrLen;
-            const char16_t* curNs = getAttributeNamespace(i, &curNsLen);
-            const char16_t* curAttr = getAttributeName(i, &curAttrLen);
-            //printf("%d: ns=%p attr=%p curNs=%p curAttr=%p\n",
-            //       i, ns, attr, curNs, curAttr);
-            //printf(" --> attr=%s, curAttr=%s\n",
-            //       String8(attr).string(), String8(curAttr).string());
-            if (attr && curAttr && (strzcmp16(attr, attrLen, curAttr, curAttrLen) == 0)) {
-                if (ns == NULL) {
-                    if (curNs == NULL) return i;
-                } else if (curNs != NULL) {
-                    //printf(" --> ns=%s, curNs=%s\n",
-                    //       String8(ns).string(), String8(curNs).string());
-                    if (strzcmp16(ns, nsLen, curNs, curNsLen) == 0) return i;
-                }
-            }
-        }
-    }
-
-    return NAME_NOT_FOUND;
-}
-
-ssize_t ResXMLParser::indexOfID() const
-{
-    if (mEventCode == START_TAG) {
-        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->idIndex);
-        if (idx > 0) return (idx-1);
-    }
-    return NAME_NOT_FOUND;
-}
-
-ssize_t ResXMLParser::indexOfClass() const
-{
-    if (mEventCode == START_TAG) {
-        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->classIndex);
-        if (idx > 0) return (idx-1);
-    }
-    return NAME_NOT_FOUND;
-}
-
-ssize_t ResXMLParser::indexOfStyle() const
-{
-    if (mEventCode == START_TAG) {
-        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->styleIndex);
-        if (idx > 0) return (idx-1);
-    }
-    return NAME_NOT_FOUND;
-}
-
-ResXMLParser::event_code_t ResXMLParser::nextNode()
-{
-    if (mEventCode < 0) {
-        return mEventCode;
-    }
-
-    do {
-        const ResXMLTree_node* next = (const ResXMLTree_node*)
-            (((const uint8_t*)mCurNode) + dtohl(mCurNode->header.size));
-        //ALOGW("Next node: prev=%p, next=%p\n", mCurNode, next);
-        
-        if (((const uint8_t*)next) >= mTree.mDataEnd) {
-            mCurNode = NULL;
-            return (mEventCode=END_DOCUMENT);
-        }
-
-        if (mTree.validateNode(next) != NO_ERROR) {
-            mCurNode = NULL;
-            return (mEventCode=BAD_DOCUMENT);
-        }
-
-        mCurNode = next;
-        const uint16_t headerSize = dtohs(next->header.headerSize);
-        const uint32_t totalSize = dtohl(next->header.size);
-        mCurExt = ((const uint8_t*)next) + headerSize;
-        size_t minExtSize = 0;
-        event_code_t eventCode = (event_code_t)dtohs(next->header.type);
-        switch ((mEventCode=eventCode)) {
-            case RES_XML_START_NAMESPACE_TYPE:
-            case RES_XML_END_NAMESPACE_TYPE:
-                minExtSize = sizeof(ResXMLTree_namespaceExt);
-                break;
-            case RES_XML_START_ELEMENT_TYPE:
-                minExtSize = sizeof(ResXMLTree_attrExt);
-                break;
-            case RES_XML_END_ELEMENT_TYPE:
-                minExtSize = sizeof(ResXMLTree_endElementExt);
-                break;
-            case RES_XML_CDATA_TYPE:
-                minExtSize = sizeof(ResXMLTree_cdataExt);
-                break;
-            default:
-                ALOGW("Unknown XML block: header type %d in node at %d\n",
-                     (int)dtohs(next->header.type),
-                     (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)));
-                continue;
-        }
-        
-        if ((totalSize-headerSize) < minExtSize) {
-            ALOGW("Bad XML block: header type 0x%x in node at 0x%x has size %d, need %d\n",
-                 (int)dtohs(next->header.type),
-                 (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)),
-                 (int)(totalSize-headerSize), (int)minExtSize);
-            return (mEventCode=BAD_DOCUMENT);
-        }
-        
-        //printf("CurNode=%p, CurExt=%p, headerSize=%d, minExtSize=%d\n",
-        //       mCurNode, mCurExt, headerSize, minExtSize);
-        
-        return eventCode;
-    } while (true);
-}
-
-void ResXMLParser::getPosition(ResXMLParser::ResXMLPosition* pos) const
-{
-    pos->eventCode = mEventCode;
-    pos->curNode = mCurNode;
-    pos->curExt = mCurExt;
-}
-
-void ResXMLParser::setPosition(const ResXMLParser::ResXMLPosition& pos)
-{
-    mEventCode = pos.eventCode;
-    mCurNode = pos.curNode;
-    mCurExt = pos.curExt;
-}
-
-
-// --------------------------------------------------------------------
-
-static volatile int32_t gCount = 0;
-
-ResXMLTree::ResXMLTree()
-    : ResXMLParser(*this)
-    , mError(NO_INIT), mOwnedData(NULL)
-{
-    //ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
-    restart();
-}
-
-ResXMLTree::ResXMLTree(const void* data, size_t size, bool copyData)
-    : ResXMLParser(*this)
-    , mError(NO_INIT), mOwnedData(NULL)
-{
-    //ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
-    setTo(data, size, copyData);
-}
-
-ResXMLTree::~ResXMLTree()
-{
-    //ALOGI("Destroying ResXMLTree in %p #%d\n", this, android_atomic_dec(&gCount)-1);
-    uninit();
-}
-
-status_t ResXMLTree::setTo(const void* data, size_t size, bool copyData)
-{
-    uninit();
-    mEventCode = START_DOCUMENT;
-
-    if (copyData) {
-        mOwnedData = malloc(size);
-        if (mOwnedData == NULL) {
-            return (mError=NO_MEMORY);
-        }
-        memcpy(mOwnedData, data, size);
-        data = mOwnedData;
-    }
-
-    mHeader = (const ResXMLTree_header*)data;
-    mSize = dtohl(mHeader->header.size);
-    if (dtohs(mHeader->header.headerSize) > mSize || mSize > size) {
-        ALOGW("Bad XML block: header size %d or total size %d is larger than data size %d\n",
-             (int)dtohs(mHeader->header.headerSize),
-             (int)dtohl(mHeader->header.size), (int)size);
-        mError = BAD_TYPE;
-        restart();
-        return mError;
-    }
-    mDataEnd = ((const uint8_t*)mHeader) + mSize;
-
-    mStrings.uninit();
-    mRootNode = NULL;
-    mResIds = NULL;
-    mNumResIds = 0;
-
-    // First look for a couple interesting chunks: the string block
-    // and first XML node.
-    const ResChunk_header* chunk =
-        (const ResChunk_header*)(((const uint8_t*)mHeader) + dtohs(mHeader->header.headerSize));
-    const ResChunk_header* lastChunk = chunk;
-    while (((const uint8_t*)chunk) < (mDataEnd-sizeof(ResChunk_header)) &&
-           ((const uint8_t*)chunk) < (mDataEnd-dtohl(chunk->size))) {
-        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), mDataEnd, "XML");
-        if (err != NO_ERROR) {
-            mError = err;
-            goto done;
-        }
-        const uint16_t type = dtohs(chunk->type);
-        const size_t size = dtohl(chunk->size);
-        XML_NOISY(printf("Scanning @ %p: type=0x%x, size=0x%x\n",
-                     (void*)(((uint32_t)chunk)-((uint32_t)mHeader)), type, size));
-        if (type == RES_STRING_POOL_TYPE) {
-            mStrings.setTo(chunk, size);
-        } else if (type == RES_XML_RESOURCE_MAP_TYPE) {
-            mResIds = (const uint32_t*)
-                (((const uint8_t*)chunk)+dtohs(chunk->headerSize));
-            mNumResIds = (dtohl(chunk->size)-dtohs(chunk->headerSize))/sizeof(uint32_t);
-        } else if (type >= RES_XML_FIRST_CHUNK_TYPE
-                   && type <= RES_XML_LAST_CHUNK_TYPE) {
-            if (validateNode((const ResXMLTree_node*)chunk) != NO_ERROR) {
-                mError = BAD_TYPE;
-                goto done;
-            }
-            mCurNode = (const ResXMLTree_node*)lastChunk;
-            if (nextNode() == BAD_DOCUMENT) {
-                mError = BAD_TYPE;
-                goto done;
-            }
-            mRootNode = mCurNode;
-            mRootExt = mCurExt;
-            mRootCode = mEventCode;
-            break;
-        } else {
-            XML_NOISY(printf("Skipping unknown chunk!\n"));
-        }
-        lastChunk = chunk;
-        chunk = (const ResChunk_header*)
-            (((const uint8_t*)chunk) + size);
-    }
-
-    if (mRootNode == NULL) {
-        ALOGW("Bad XML block: no root element node found\n");
-        mError = BAD_TYPE;
-        goto done;
-    }
-
-    mError = mStrings.getError();
-
-done:
-    restart();
-    return mError;
-}
-
-status_t ResXMLTree::getError() const
-{
-    return mError;
-}
-
-void ResXMLTree::uninit()
-{
-    mError = NO_INIT;
-    mStrings.uninit();
-    if (mOwnedData) {
-        free(mOwnedData);
-        mOwnedData = NULL;
-    }
-    restart();
-}
-
-status_t ResXMLTree::validateNode(const ResXMLTree_node* node) const
-{
-    const uint16_t eventCode = dtohs(node->header.type);
-
-    status_t err = validate_chunk(
-        &node->header, sizeof(ResXMLTree_node),
-        mDataEnd, "ResXMLTree_node");
-
-    if (err >= NO_ERROR) {
-        // Only perform additional validation on START nodes
-        if (eventCode != RES_XML_START_ELEMENT_TYPE) {
-            return NO_ERROR;
-        }
-
-        const uint16_t headerSize = dtohs(node->header.headerSize);
-        const uint32_t size = dtohl(node->header.size);
-        const ResXMLTree_attrExt* attrExt = (const ResXMLTree_attrExt*)
-            (((const uint8_t*)node) + headerSize);
-        // check for sensical values pulled out of the stream so far...
-        if ((size >= headerSize + sizeof(ResXMLTree_attrExt))
-                && ((void*)attrExt > (void*)node)) {
-            const size_t attrSize = ((size_t)dtohs(attrExt->attributeSize))
-                * dtohs(attrExt->attributeCount);
-            if ((dtohs(attrExt->attributeStart)+attrSize) <= (size-headerSize)) {
-                return NO_ERROR;
-            }
-            ALOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n",
-                    (unsigned int)(dtohs(attrExt->attributeStart)+attrSize),
-                    (unsigned int)(size-headerSize));
-        }
-        else {
-            ALOGW("Bad XML start block: node header size 0x%x, size 0x%x\n",
-                (unsigned int)headerSize, (unsigned int)size);
-        }
-        return BAD_TYPE;
-    }
-
-    return err;
-
-#if 0
-    const bool isStart = dtohs(node->header.type) == RES_XML_START_ELEMENT_TYPE;
-
-    const uint16_t headerSize = dtohs(node->header.headerSize);
-    const uint32_t size = dtohl(node->header.size);
-
-    if (headerSize >= (isStart ? sizeof(ResXMLTree_attrNode) : sizeof(ResXMLTree_node))) {
-        if (size >= headerSize) {
-            if (((const uint8_t*)node) <= (mDataEnd-size)) {
-                if (!isStart) {
-                    return NO_ERROR;
-                }
-                if ((((size_t)dtohs(node->attributeSize))*dtohs(node->attributeCount))
-                        <= (size-headerSize)) {
-                    return NO_ERROR;
-                }
-                ALOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n",
-                        ((int)dtohs(node->attributeSize))*dtohs(node->attributeCount),
-                        (int)(size-headerSize));
-                return BAD_TYPE;
-            }
-            ALOGW("Bad XML block: node at 0x%x extends beyond data end 0x%x\n",
-                    (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), (int)mSize);
-            return BAD_TYPE;
-        }
-        ALOGW("Bad XML block: node at 0x%x header size 0x%x smaller than total size 0x%x\n",
-                (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),
-                (int)headerSize, (int)size);
-        return BAD_TYPE;
-    }
-    ALOGW("Bad XML block: node at 0x%x header size 0x%x too small\n",
-            (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),
-            (int)headerSize);
-    return BAD_TYPE;
-#endif
-}
-
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-
-void ResTable_config::copyFromDeviceNoSwap(const ResTable_config& o) {
-    const size_t size = dtohl(o.size);
-    if (size >= sizeof(ResTable_config)) {
-        *this = o;
-    } else {
-        memcpy(this, &o, size);
-        memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size);
-    }
-}
-
-void ResTable_config::copyFromDtoH(const ResTable_config& o) {
-    copyFromDeviceNoSwap(o);
-    size = sizeof(ResTable_config);
-    mcc = dtohs(mcc);
-    mnc = dtohs(mnc);
-    density = dtohs(density);
-    screenWidth = dtohs(screenWidth);
-    screenHeight = dtohs(screenHeight);
-    sdkVersion = dtohs(sdkVersion);
-    minorVersion = dtohs(minorVersion);
-    smallestScreenWidthDp = dtohs(smallestScreenWidthDp);
-    screenWidthDp = dtohs(screenWidthDp);
-    screenHeightDp = dtohs(screenHeightDp);
-}
-
-void ResTable_config::swapHtoD() {
-    size = htodl(size);
-    mcc = htods(mcc);
-    mnc = htods(mnc);
-    density = htods(density);
-    screenWidth = htods(screenWidth);
-    screenHeight = htods(screenHeight);
-    sdkVersion = htods(sdkVersion);
-    minorVersion = htods(minorVersion);
-    smallestScreenWidthDp = htods(smallestScreenWidthDp);
-    screenWidthDp = htods(screenWidthDp);
-    screenHeightDp = htods(screenHeightDp);
-}
-
-int ResTable_config::compare(const ResTable_config& o) const {
-    int32_t diff = (int32_t)(imsi - o.imsi);
-    if (diff != 0) return diff;
-    diff = (int32_t)(locale - o.locale);
-    if (diff != 0) return diff;
-    diff = (int32_t)(screenType - o.screenType);
-    if (diff != 0) return diff;
-    diff = (int32_t)(input - o.input);
-    if (diff != 0) return diff;
-    diff = (int32_t)(screenSize - o.screenSize);
-    if (diff != 0) return diff;
-    diff = (int32_t)(version - o.version);
-    if (diff != 0) return diff;
-    diff = (int32_t)(screenLayout - o.screenLayout);
-    if (diff != 0) return diff;
-    diff = (int32_t)(uiMode - o.uiMode);
-    if (diff != 0) return diff;
-    diff = (int32_t)(smallestScreenWidthDp - o.smallestScreenWidthDp);
-    if (diff != 0) return diff;
-    diff = (int32_t)(screenSizeDp - o.screenSizeDp);
-    return (int)diff;
-}
-
-int ResTable_config::compareLogical(const ResTable_config& o) const {
-    if (mcc != o.mcc) {
-        return mcc < o.mcc ? -1 : 1;
-    }
-    if (mnc != o.mnc) {
-        return mnc < o.mnc ? -1 : 1;
-    }
-    if (language[0] != o.language[0]) {
-        return language[0] < o.language[0] ? -1 : 1;
-    }
-    if (language[1] != o.language[1]) {
-        return language[1] < o.language[1] ? -1 : 1;
-    }
-    if (country[0] != o.country[0]) {
-        return country[0] < o.country[0] ? -1 : 1;
-    }
-    if (country[1] != o.country[1]) {
-        return country[1] < o.country[1] ? -1 : 1;
-    }
-    if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
-        return smallestScreenWidthDp < o.smallestScreenWidthDp ? -1 : 1;
-    }
-    if (screenWidthDp != o.screenWidthDp) {
-        return screenWidthDp < o.screenWidthDp ? -1 : 1;
-    }
-    if (screenHeightDp != o.screenHeightDp) {
-        return screenHeightDp < o.screenHeightDp ? -1 : 1;
-    }
-    if (screenWidth != o.screenWidth) {
-        return screenWidth < o.screenWidth ? -1 : 1;
-    }
-    if (screenHeight != o.screenHeight) {
-        return screenHeight < o.screenHeight ? -1 : 1;
-    }
-    if (density != o.density) {
-        return density < o.density ? -1 : 1;
-    }
-    if (orientation != o.orientation) {
-        return orientation < o.orientation ? -1 : 1;
-    }
-    if (touchscreen != o.touchscreen) {
-        return touchscreen < o.touchscreen ? -1 : 1;
-    }
-    if (input != o.input) {
-        return input < o.input ? -1 : 1;
-    }
-    if (screenLayout != o.screenLayout) {
-        return screenLayout < o.screenLayout ? -1 : 1;
-    }
-    if (uiMode != o.uiMode) {
-        return uiMode < o.uiMode ? -1 : 1;
-    }
-    if (version != o.version) {
-        return version < o.version ? -1 : 1;
-    }
-    return 0;
-}
-
-int ResTable_config::diff(const ResTable_config& o) const {
-    int diffs = 0;
-    if (mcc != o.mcc) diffs |= CONFIG_MCC;
-    if (mnc != o.mnc) diffs |= CONFIG_MNC;
-    if (locale != o.locale) diffs |= CONFIG_LOCALE;
-    if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION;
-    if (density != o.density) diffs |= CONFIG_DENSITY;
-    if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN;
-    if (((inputFlags^o.inputFlags)&(MASK_KEYSHIDDEN|MASK_NAVHIDDEN)) != 0)
-            diffs |= CONFIG_KEYBOARD_HIDDEN;
-    if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD;
-    if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
-    if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
-    if (version != o.version) diffs |= CONFIG_VERSION;
-    if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT;
-    if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE;
-    if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE;
-    if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE;
-    return diffs;
-}
-
-bool ResTable_config::isMoreSpecificThan(const ResTable_config& o) const {
-    // The order of the following tests defines the importance of one
-    // configuration parameter over another.  Those tests first are more
-    // important, trumping any values in those following them.
-    if (imsi || o.imsi) {
-        if (mcc != o.mcc) {
-            if (!mcc) return false;
-            if (!o.mcc) return true;
-        }
-
-        if (mnc != o.mnc) {
-            if (!mnc) return false;
-            if (!o.mnc) return true;
-        }
-    }
-
-    if (locale || o.locale) {
-        if (language[0] != o.language[0]) {
-            if (!language[0]) return false;
-            if (!o.language[0]) return true;
-        }
-
-        if (country[0] != o.country[0]) {
-            if (!country[0]) return false;
-            if (!o.country[0]) return true;
-        }
-    }
-
-    if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
-        if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
-            if (!smallestScreenWidthDp) return false;
-            if (!o.smallestScreenWidthDp) return true;
-        }
-    }
-
-    if (screenSizeDp || o.screenSizeDp) {
-        if (screenWidthDp != o.screenWidthDp) {
-            if (!screenWidthDp) return false;
-            if (!o.screenWidthDp) return true;
-        }
-
-        if (screenHeightDp != o.screenHeightDp) {
-            if (!screenHeightDp) return false;
-            if (!o.screenHeightDp) return true;
-        }
-    }
-
-    if (screenLayout || o.screenLayout) {
-        if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) {
-            if (!(screenLayout & MASK_SCREENSIZE)) return false;
-            if (!(o.screenLayout & MASK_SCREENSIZE)) return true;
-        }
-        if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) {
-            if (!(screenLayout & MASK_SCREENLONG)) return false;
-            if (!(o.screenLayout & MASK_SCREENLONG)) return true;
-        }
-    }
-
-    if (orientation != o.orientation) {
-        if (!orientation) return false;
-        if (!o.orientation) return true;
-    }
-
-    if (uiMode || o.uiMode) {
-        if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0) {
-            if (!(uiMode & MASK_UI_MODE_TYPE)) return false;
-            if (!(o.uiMode & MASK_UI_MODE_TYPE)) return true;
-        }
-        if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0) {
-            if (!(uiMode & MASK_UI_MODE_NIGHT)) return false;
-            if (!(o.uiMode & MASK_UI_MODE_NIGHT)) return true;
-        }
-    }
-
-    // density is never 'more specific'
-    // as the default just equals 160
-
-    if (touchscreen != o.touchscreen) {
-        if (!touchscreen) return false;
-        if (!o.touchscreen) return true;
-    }
-
-    if (input || o.input) {
-        if (((inputFlags^o.inputFlags) & MASK_KEYSHIDDEN) != 0) {
-            if (!(inputFlags & MASK_KEYSHIDDEN)) return false;
-            if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true;
-        }
-
-        if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) {
-            if (!(inputFlags & MASK_NAVHIDDEN)) return false;
-            if (!(o.inputFlags & MASK_NAVHIDDEN)) return true;
-        }
-
-        if (keyboard != o.keyboard) {
-            if (!keyboard) return false;
-            if (!o.keyboard) return true;
-        }
-
-        if (navigation != o.navigation) {
-            if (!navigation) return false;
-            if (!o.navigation) return true;
-        }
-    }
-
-    if (screenSize || o.screenSize) {
-        if (screenWidth != o.screenWidth) {
-            if (!screenWidth) return false;
-            if (!o.screenWidth) return true;
-        }
-
-        if (screenHeight != o.screenHeight) {
-            if (!screenHeight) return false;
-            if (!o.screenHeight) return true;
-        }
-    }
-
-    if (version || o.version) {
-        if (sdkVersion != o.sdkVersion) {
-            if (!sdkVersion) return false;
-            if (!o.sdkVersion) return true;
-        }
-
-        if (minorVersion != o.minorVersion) {
-            if (!minorVersion) return false;
-            if (!o.minorVersion) return true;
-        }
-    }
-    return false;
-}
-
-bool ResTable_config::isBetterThan(const ResTable_config& o,
-        const ResTable_config* requested) const {
-    if (requested) {
-        if (imsi || o.imsi) {
-            if ((mcc != o.mcc) && requested->mcc) {
-                return (mcc);
-            }
-
-            if ((mnc != o.mnc) && requested->mnc) {
-                return (mnc);
-            }
-        }
-
-        if (locale || o.locale) {
-            if ((language[0] != o.language[0]) && requested->language[0]) {
-                return (language[0]);
-            }
-
-            if ((country[0] != o.country[0]) && requested->country[0]) {
-                return (country[0]);
-            }
-        }
-
-        if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
-            // The configuration closest to the actual size is best.
-            // We assume that larger configs have already been filtered
-            // out at this point.  That means we just want the largest one.
-            return smallestScreenWidthDp >= o.smallestScreenWidthDp;
-        }
-
-        if (screenSizeDp || o.screenSizeDp) {
-            // "Better" is based on the sum of the difference between both
-            // width and height from the requested dimensions.  We are
-            // assuming the invalid configs (with smaller dimens) have
-            // already been filtered.  Note that if a particular dimension
-            // is unspecified, we will end up with a large value (the
-            // difference between 0 and the requested dimension), which is
-            // good since we will prefer a config that has specified a
-            // dimension value.
-            int myDelta = 0, otherDelta = 0;
-            if (requested->screenWidthDp) {
-                myDelta += requested->screenWidthDp - screenWidthDp;
-                otherDelta += requested->screenWidthDp - o.screenWidthDp;
-            }
-            if (requested->screenHeightDp) {
-                myDelta += requested->screenHeightDp - screenHeightDp;
-                otherDelta += requested->screenHeightDp - o.screenHeightDp;
-            }
-            //ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
-            //    screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
-            //    requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
-            return (myDelta <= otherDelta);
-        }
-
-        if (screenLayout || o.screenLayout) {
-            if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
-                    && (requested->screenLayout & MASK_SCREENSIZE)) {
-                // A little backwards compatibility here: undefined is
-                // considered equivalent to normal.  But only if the
-                // requested size is at least normal; otherwise, small
-                // is better than the default.
-                int mySL = (screenLayout & MASK_SCREENSIZE);
-                int oSL = (o.screenLayout & MASK_SCREENSIZE);
-                int fixedMySL = mySL;
-                int fixedOSL = oSL;
-                if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {
-                    if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;
-                    if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;
-                }
-                // For screen size, the best match is the one that is
-                // closest to the requested screen size, but not over
-                // (the not over part is dealt with in match() below).
-                if (fixedMySL == fixedOSL) {
-                    // If the two are the same, but 'this' is actually
-                    // undefined, then the other is really a better match.
-                    if (mySL == 0) return false;
-                    return true;
-                }
-                return fixedMySL >= fixedOSL;
-            }
-            if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
-                    && (requested->screenLayout & MASK_SCREENLONG)) {
-                return (screenLayout & MASK_SCREENLONG);
-            }
-        }
-
-        if ((orientation != o.orientation) && requested->orientation) {
-            return (orientation);
-        }
-
-        if (uiMode || o.uiMode) {
-            if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0
-                    && (requested->uiMode & MASK_UI_MODE_TYPE)) {
-                return (uiMode & MASK_UI_MODE_TYPE);
-            }
-            if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0
-                    && (requested->uiMode & MASK_UI_MODE_NIGHT)) {
-                return (uiMode & MASK_UI_MODE_NIGHT);
-            }
-        }
-
-        if (screenType || o.screenType) {
-            if (density != o.density) {
-                // density is tough.  Any density is potentially useful
-                // because the system will scale it.  Scaling down
-                // is generally better than scaling up.
-                // Default density counts as 160dpi (the system default)
-                // TODO - remove 160 constants
-                int h = (density?density:160);
-                int l = (o.density?o.density:160);
-                bool bImBigger = true;
-                if (l > h) {
-                    int t = h;
-                    h = l;
-                    l = t;
-                    bImBigger = false;
-                }
-
-                int reqValue = (requested->density?requested->density:160);
-                if (reqValue >= h) {
-                    // requested value higher than both l and h, give h
-                    return bImBigger;
-                }
-                if (l >= reqValue) {
-                    // requested value lower than both l and h, give l
-                    return !bImBigger;
-                }
-                // saying that scaling down is 2x better than up
-                if (((2 * l) - reqValue) * h > reqValue * reqValue) {
-                    return !bImBigger;
-                } else {
-                    return bImBigger;
-                }
-            }
-
-            if ((touchscreen != o.touchscreen) && requested->touchscreen) {
-                return (touchscreen);
-            }
-        }
-
-        if (input || o.input) {
-            const int keysHidden = inputFlags & MASK_KEYSHIDDEN;
-            const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;
-            if (keysHidden != oKeysHidden) {
-                const int reqKeysHidden =
-                        requested->inputFlags & MASK_KEYSHIDDEN;
-                if (reqKeysHidden) {
-
-                    if (!keysHidden) return false;
-                    if (!oKeysHidden) return true;
-                    // For compatibility, we count KEYSHIDDEN_NO as being
-                    // the same as KEYSHIDDEN_SOFT.  Here we disambiguate
-                    // these by making an exact match more specific.
-                    if (reqKeysHidden == keysHidden) return true;
-                    if (reqKeysHidden == oKeysHidden) return false;
-                }
-            }
-
-            const int navHidden = inputFlags & MASK_NAVHIDDEN;
-            const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;
-            if (navHidden != oNavHidden) {
-                const int reqNavHidden =
-                        requested->inputFlags & MASK_NAVHIDDEN;
-                if (reqNavHidden) {
-
-                    if (!navHidden) return false;
-                    if (!oNavHidden) return true;
-                }
-            }
-
-            if ((keyboard != o.keyboard) && requested->keyboard) {
-                return (keyboard);
-            }
-
-            if ((navigation != o.navigation) && requested->navigation) {
-                return (navigation);
-            }
-        }
-
-        if (screenSize || o.screenSize) {
-            // "Better" is based on the sum of the difference between both
-            // width and height from the requested dimensions.  We are
-            // assuming the invalid configs (with smaller sizes) have
-            // already been filtered.  Note that if a particular dimension
-            // is unspecified, we will end up with a large value (the
-            // difference between 0 and the requested dimension), which is
-            // good since we will prefer a config that has specified a
-            // size value.
-            int myDelta = 0, otherDelta = 0;
-            if (requested->screenWidth) {
-                myDelta += requested->screenWidth - screenWidth;
-                otherDelta += requested->screenWidth - o.screenWidth;
-            }
-            if (requested->screenHeight) {
-                myDelta += requested->screenHeight - screenHeight;
-                otherDelta += requested->screenHeight - o.screenHeight;
-            }
-            return (myDelta <= otherDelta);
-        }
-
-        if (version || o.version) {
-            if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {
-                return (sdkVersion > o.sdkVersion);
-            }
-
-            if ((minorVersion != o.minorVersion) &&
-                    requested->minorVersion) {
-                return (minorVersion);
-            }
-        }
-
-        return false;
-    }
-    return isMoreSpecificThan(o);
-}
-
-bool ResTable_config::match(const ResTable_config& settings) const {
-    if (imsi != 0) {
-        if (mcc != 0 && mcc != settings.mcc) {
-            return false;
-        }
-        if (mnc != 0 && mnc != settings.mnc) {
-            return false;
-        }
-    }
-    if (locale != 0) {
-        if (language[0] != 0
-            && (language[0] != settings.language[0]
-                || language[1] != settings.language[1])) {
-            return false;
-        }
-        if (country[0] != 0
-            && (country[0] != settings.country[0]
-                || country[1] != settings.country[1])) {
-            return false;
-        }
-    }
-    if (screenConfig != 0) {
-        const int screenSize = screenLayout&MASK_SCREENSIZE;
-        const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
-        // Any screen sizes for larger screens than the setting do not
-        // match.
-        if (screenSize != 0 && screenSize > setScreenSize) {
-            return false;
-        }
-
-        const int screenLong = screenLayout&MASK_SCREENLONG;
-        const int setScreenLong = settings.screenLayout&MASK_SCREENLONG;
-        if (screenLong != 0 && screenLong != setScreenLong) {
-            return false;
-        }
-
-        const int uiModeType = uiMode&MASK_UI_MODE_TYPE;
-        const int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE;
-        if (uiModeType != 0 && uiModeType != setUiModeType) {
-            return false;
-        }
-
-        const int uiModeNight = uiMode&MASK_UI_MODE_NIGHT;
-        const int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT;
-        if (uiModeNight != 0 && uiModeNight != setUiModeNight) {
-            return false;
-        }
-
-        if (smallestScreenWidthDp != 0
-                && smallestScreenWidthDp > settings.smallestScreenWidthDp) {
-            return false;
-        }
-    }
-    if (screenSizeDp != 0) {
-        if (screenWidthDp != 0 && screenWidthDp > settings.screenWidthDp) {
-            //ALOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp);
-            return false;
-        }
-        if (screenHeightDp != 0 && screenHeightDp > settings.screenHeightDp) {
-            //ALOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp);
-            return false;
-        }
-    }
-    if (screenType != 0) {
-        if (orientation != 0 && orientation != settings.orientation) {
-            return false;
-        }
-        // density always matches - we can scale it.  See isBetterThan
-        if (touchscreen != 0 && touchscreen != settings.touchscreen) {
-            return false;
-        }
-    }
-    if (input != 0) {
-        const int keysHidden = inputFlags&MASK_KEYSHIDDEN;
-        const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;
-        if (keysHidden != 0 && keysHidden != setKeysHidden) {
-            // For compatibility, we count a request for KEYSHIDDEN_NO as also
-            // matching the more recent KEYSHIDDEN_SOFT.  Basically
-            // KEYSHIDDEN_NO means there is some kind of keyboard available.
-            //ALOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden);
-            if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) {
-                //ALOGI("No match!");
-                return false;
-            }
-        }
-        const int navHidden = inputFlags&MASK_NAVHIDDEN;
-        const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN;
-        if (navHidden != 0 && navHidden != setNavHidden) {
-            return false;
-        }
-        if (keyboard != 0 && keyboard != settings.keyboard) {
-            return false;
-        }
-        if (navigation != 0 && navigation != settings.navigation) {
-            return false;
-        }
-    }
-    if (screenSize != 0) {
-        if (screenWidth != 0 && screenWidth > settings.screenWidth) {
-            return false;
-        }
-        if (screenHeight != 0 && screenHeight > settings.screenHeight) {
-            return false;
-        }
-    }
-    if (version != 0) {
-        if (sdkVersion != 0 && sdkVersion > settings.sdkVersion) {
-            return false;
-        }
-        if (minorVersion != 0 && minorVersion != settings.minorVersion) {
-            return false;
-        }
-    }
-    return true;
-}
-
-void ResTable_config::getLocale(char str[6]) const {
-    memset(str, 0, 6);
-    if (language[0]) {
-        str[0] = language[0];
-        str[1] = language[1];
-        if (country[0]) {
-            str[2] = '_';
-            str[3] = country[0];
-            str[4] = country[1];
-        }
-    }
-}
-
-String8 ResTable_config::toString() const {
-    String8 res;
-
-    if (mcc != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("%dmcc", dtohs(mcc));
-    }
-    if (mnc != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("%dmnc", dtohs(mnc));
-    }
-    if (language[0] != 0) {
-        if (res.size() > 0) res.append("-");
-        res.append(language, 2);
-    }
-    if (country[0] != 0) {
-        if (res.size() > 0) res.append("-");
-        res.append(country, 2);
-    }
-    if (smallestScreenWidthDp != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("sw%ddp", dtohs(smallestScreenWidthDp));
-    }
-    if (screenWidthDp != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("w%ddp", dtohs(screenWidthDp));
-    }
-    if (screenHeightDp != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("h%ddp", dtohs(screenHeightDp));
-    }
-    if ((screenLayout&MASK_SCREENSIZE) != SCREENSIZE_ANY) {
-        if (res.size() > 0) res.append("-");
-        switch (screenLayout&ResTable_config::MASK_SCREENSIZE) {
-            case ResTable_config::SCREENSIZE_SMALL:
-                res.append("small");
-                break;
-            case ResTable_config::SCREENSIZE_NORMAL:
-                res.append("normal");
-                break;
-            case ResTable_config::SCREENSIZE_LARGE:
-                res.append("large");
-                break;
-            case ResTable_config::SCREENSIZE_XLARGE:
-                res.append("xlarge");
-                break;
-            default:
-                res.appendFormat("screenLayoutSize=%d",
-                        dtohs(screenLayout&ResTable_config::MASK_SCREENSIZE));
-                break;
-        }
-    }
-    if ((screenLayout&MASK_SCREENLONG) != 0) {
-        if (res.size() > 0) res.append("-");
-        switch (screenLayout&ResTable_config::MASK_SCREENLONG) {
-            case ResTable_config::SCREENLONG_NO:
-                res.append("notlong");
-                break;
-            case ResTable_config::SCREENLONG_YES:
-                res.append("long");
-                break;
-            default:
-                res.appendFormat("screenLayoutLong=%d",
-                        dtohs(screenLayout&ResTable_config::MASK_SCREENLONG));
-                break;
-        }
-    }
-    if (orientation != ORIENTATION_ANY) {
-        if (res.size() > 0) res.append("-");
-        switch (orientation) {
-            case ResTable_config::ORIENTATION_PORT:
-                res.append("port");
-                break;
-            case ResTable_config::ORIENTATION_LAND:
-                res.append("land");
-                break;
-            case ResTable_config::ORIENTATION_SQUARE:
-                res.append("square");
-                break;
-            default:
-                res.appendFormat("orientation=%d", dtohs(orientation));
-                break;
-        }
-    }
-    if ((uiMode&MASK_UI_MODE_TYPE) != UI_MODE_TYPE_ANY) {
-        if (res.size() > 0) res.append("-");
-        switch (uiMode&ResTable_config::MASK_UI_MODE_TYPE) {
-            case ResTable_config::UI_MODE_TYPE_DESK:
-                res.append("desk");
-                break;
-            case ResTable_config::UI_MODE_TYPE_CAR:
-                res.append("car");
-                break;
-            case ResTable_config::UI_MODE_TYPE_TELEVISION:
-                res.append("television");
-                break;
-            case ResTable_config::UI_MODE_TYPE_APPLIANCE:
-                res.append("appliance");
-                break;
-            default:
-                res.appendFormat("uiModeType=%d",
-                        dtohs(screenLayout&ResTable_config::MASK_UI_MODE_TYPE));
-                break;
-        }
-    }
-    if ((uiMode&MASK_UI_MODE_NIGHT) != 0) {
-        if (res.size() > 0) res.append("-");
-        switch (uiMode&ResTable_config::MASK_UI_MODE_NIGHT) {
-            case ResTable_config::UI_MODE_NIGHT_NO:
-                res.append("notnight");
-                break;
-            case ResTable_config::UI_MODE_NIGHT_YES:
-                res.append("night");
-                break;
-            default:
-                res.appendFormat("uiModeNight=%d",
-                        dtohs(uiMode&MASK_UI_MODE_NIGHT));
-                break;
-        }
-    }
-    if (density != DENSITY_DEFAULT) {
-        if (res.size() > 0) res.append("-");
-        switch (density) {
-            case ResTable_config::DENSITY_LOW:
-                res.append("ldpi");
-                break;
-            case ResTable_config::DENSITY_MEDIUM:
-                res.append("mdpi");
-                break;
-            case ResTable_config::DENSITY_TV:
-                res.append("tvdpi");
-                break;
-            case ResTable_config::DENSITY_HIGH:
-                res.append("hdpi");
-                break;
-            case ResTable_config::DENSITY_XHIGH:
-                res.append("xhdpi");
-                break;
-            case ResTable_config::DENSITY_XXHIGH:
-                res.append("xxhdpi");
-                break;
-            case ResTable_config::DENSITY_NONE:
-                res.append("nodpi");
-                break;
-            default:
-                res.appendFormat("density=%d", dtohs(density));
-                break;
-        }
-    }
-    if (touchscreen != TOUCHSCREEN_ANY) {
-        if (res.size() > 0) res.append("-");
-        switch (touchscreen) {
-            case ResTable_config::TOUCHSCREEN_NOTOUCH:
-                res.append("notouch");
-                break;
-            case ResTable_config::TOUCHSCREEN_FINGER:
-                res.append("finger");
-                break;
-            case ResTable_config::TOUCHSCREEN_STYLUS:
-                res.append("stylus");
-                break;
-            default:
-                res.appendFormat("touchscreen=%d", dtohs(touchscreen));
-                break;
-        }
-    }
-    if (keyboard != KEYBOARD_ANY) {
-        if (res.size() > 0) res.append("-");
-        switch (keyboard) {
-            case ResTable_config::KEYBOARD_NOKEYS:
-                res.append("nokeys");
-                break;
-            case ResTable_config::KEYBOARD_QWERTY:
-                res.append("qwerty");
-                break;
-            case ResTable_config::KEYBOARD_12KEY:
-                res.append("12key");
-                break;
-            default:
-                res.appendFormat("keyboard=%d", dtohs(keyboard));
-                break;
-        }
-    }
-    if ((inputFlags&MASK_KEYSHIDDEN) != 0) {
-        if (res.size() > 0) res.append("-");
-        switch (inputFlags&MASK_KEYSHIDDEN) {
-            case ResTable_config::KEYSHIDDEN_NO:
-                res.append("keysexposed");
-                break;
-            case ResTable_config::KEYSHIDDEN_YES:
-                res.append("keyshidden");
-                break;
-            case ResTable_config::KEYSHIDDEN_SOFT:
-                res.append("keyssoft");
-                break;
-        }
-    }
-    if (navigation != NAVIGATION_ANY) {
-        if (res.size() > 0) res.append("-");
-        switch (navigation) {
-            case ResTable_config::NAVIGATION_NONAV:
-                res.append("nonav");
-                break;
-            case ResTable_config::NAVIGATION_DPAD:
-                res.append("dpad");
-                break;
-            case ResTable_config::NAVIGATION_TRACKBALL:
-                res.append("trackball");
-                break;
-            case ResTable_config::NAVIGATION_WHEEL:
-                res.append("wheel");
-                break;
-            default:
-                res.appendFormat("navigation=%d", dtohs(navigation));
-                break;
-        }
-    }
-    if ((inputFlags&MASK_NAVHIDDEN) != 0) {
-        if (res.size() > 0) res.append("-");
-        switch (inputFlags&MASK_NAVHIDDEN) {
-            case ResTable_config::NAVHIDDEN_NO:
-                res.append("navsexposed");
-                break;
-            case ResTable_config::NAVHIDDEN_YES:
-                res.append("navhidden");
-                break;
-            default:
-                res.appendFormat("inputFlagsNavHidden=%d",
-                        dtohs(inputFlags&MASK_NAVHIDDEN));
-                break;
-        }
-    }
-    if (screenSize != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("%dx%d", dtohs(screenWidth), dtohs(screenHeight));
-    }
-    if (version != 0) {
-        if (res.size() > 0) res.append("-");
-        res.appendFormat("v%d", dtohs(sdkVersion));
-        if (minorVersion != 0) {
-            res.appendFormat(".%d", dtohs(minorVersion));
-        }
-    }
-
-    return res;
-}
-
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-// --------------------------------------------------------------------
-
-struct ResTable::Header
-{
-    Header(ResTable* _owner) : owner(_owner), ownedData(NULL), header(NULL),
-        resourceIDMap(NULL), resourceIDMapSize(0) { }
-
-    ~Header()
-    {
-        free(resourceIDMap);
-    }
-
-    ResTable* const                 owner;
-    void*                           ownedData;
-    const ResTable_header*          header;
-    size_t                          size;
-    const uint8_t*                  dataEnd;
-    size_t                          index;
-    void*                           cookie;
-
-    ResStringPool                   values;
-    uint32_t*                       resourceIDMap;
-    size_t                          resourceIDMapSize;
-};
-
-struct ResTable::Type
-{
-    Type(const Header* _header, const Package* _package, size_t count)
-        : header(_header), package(_package), entryCount(count),
-          typeSpec(NULL), typeSpecFlags(NULL) { }
-    const Header* const             header;
-    const Package* const            package;
-    const size_t                    entryCount;
-    const ResTable_typeSpec*        typeSpec;
-    const uint32_t*                 typeSpecFlags;
-    Vector<const ResTable_type*>    configs;
-};
-
-struct ResTable::Package
-{
-    Package(ResTable* _owner, const Header* _header, const ResTable_package* _package)
-        : owner(_owner), header(_header), package(_package) { }
-    ~Package()
-    {
-        size_t i = types.size();
-        while (i > 0) {
-            i--;
-            delete types[i];
-        }
-    }
-    
-    ResTable* const                 owner;
-    const Header* const             header;
-    const ResTable_package* const   package;
-    Vector<Type*>                   types;
-
-    ResStringPool                   typeStrings;
-    ResStringPool                   keyStrings;
-    
-    const Type* getType(size_t idx) const {
-        return idx < types.size() ? types[idx] : NULL;
-    }
-};
-
-// A group of objects describing a particular resource package.
-// The first in 'package' is always the root object (from the resource
-// table that defined the package); the ones after are skins on top of it.
-struct ResTable::PackageGroup
-{
-    PackageGroup(ResTable* _owner, const String16& _name, uint32_t _id)
-        : owner(_owner), name(_name), id(_id), typeCount(0), bags(NULL) { }
-    ~PackageGroup() {
-        clearBagCache();
-        const size_t N = packages.size();
-        for (size_t i=0; i<N; i++) {
-            Package* pkg = packages[i];
-            if (pkg->owner == owner) {
-                delete pkg;
-            }
-        }
-    }
-
-    void clearBagCache() {
-        if (bags) {
-            TABLE_NOISY(printf("bags=%p\n", bags));
-            Package* pkg = packages[0];
-            TABLE_NOISY(printf("typeCount=%x\n", typeCount));
-            for (size_t i=0; i<typeCount; i++) {
-                TABLE_NOISY(printf("type=%d\n", i));
-                const Type* type = pkg->getType(i);
-                if (type != NULL) {
-                    bag_set** typeBags = bags[i];
-                    TABLE_NOISY(printf("typeBags=%p\n", typeBags));
-                    if (typeBags) {
-                        TABLE_NOISY(printf("type->entryCount=%x\n", type->entryCount));
-                        const size_t N = type->entryCount;
-                        for (size_t j=0; j<N; j++) {
-                            if (typeBags[j] && typeBags[j] != (bag_set*)0xFFFFFFFF)
-                                free(typeBags[j]);
-                        }
-                        free(typeBags);
-                    }
-                }
-            }
-            free(bags);
-            bags = NULL;
-        }
-    }
-    
-    ResTable* const                 owner;
-    String16 const                  name;
-    uint32_t const                  id;
-    Vector<Package*>                packages;
-    
-    // This is for finding typeStrings and other common package stuff.
-    Package*                        basePackage;
-
-    // For quick access.
-    size_t                          typeCount;
-    
-    // Computed attribute bags, first indexed by the type and second
-    // by the entry in that type.
-    bag_set***                      bags;
-};
-
-struct ResTable::bag_set
-{
-    size_t numAttrs;    // number in array
-    size_t availAttrs;  // total space in array
-    uint32_t typeSpecFlags;
-    // Followed by 'numAttr' bag_entry structures.
-};
-
-ResTable::Theme::Theme(const ResTable& table)
-    : mTable(table)
-{
-    memset(mPackages, 0, sizeof(mPackages));
-}
-
-ResTable::Theme::~Theme()
-{
-    for (size_t i=0; i<Res_MAXPACKAGE; i++) {
-        package_info* pi = mPackages[i];
-        if (pi != NULL) {
-            free_package(pi);
-        }
-    }
-}
-
-void ResTable::Theme::free_package(package_info* pi)
-{
-    for (size_t j=0; j<pi->numTypes; j++) {
-        theme_entry* te = pi->types[j].entries;
-        if (te != NULL) {
-            free(te);
-        }
-    }
-    free(pi);
-}
-
-ResTable::Theme::package_info* ResTable::Theme::copy_package(package_info* pi)
-{
-    package_info* newpi = (package_info*)malloc(
-        sizeof(package_info) + (pi->numTypes*sizeof(type_info)));
-    newpi->numTypes = pi->numTypes;
-    for (size_t j=0; j<newpi->numTypes; j++) {
-        size_t cnt = pi->types[j].numEntries;
-        newpi->types[j].numEntries = cnt;
-        theme_entry* te = pi->types[j].entries;
-        if (te != NULL) {
-            theme_entry* newte = (theme_entry*)malloc(cnt*sizeof(theme_entry));
-            newpi->types[j].entries = newte;
-            memcpy(newte, te, cnt*sizeof(theme_entry));
-        } else {
-            newpi->types[j].entries = NULL;
-        }
-    }
-    return newpi;
-}
-
-status_t ResTable::Theme::applyStyle(uint32_t resID, bool force)
-{
-    const bag_entry* bag;
-    uint32_t bagTypeSpecFlags = 0;
-    mTable.lock();
-    const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags);
-    TABLE_NOISY(LOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
-    if (N < 0) {
-        mTable.unlock();
-        return N;
-    }
-
-    uint32_t curPackage = 0xffffffff;
-    ssize_t curPackageIndex = 0;
-    package_info* curPI = NULL;
-    uint32_t curType = 0xffffffff;
-    size_t numEntries = 0;
-    theme_entry* curEntries = NULL;
-
-    const bag_entry* end = bag + N;
-    while (bag < end) {
-        const uint32_t attrRes = bag->map.name.ident;
-        const uint32_t p = Res_GETPACKAGE(attrRes);
-        const uint32_t t = Res_GETTYPE(attrRes);
-        const uint32_t e = Res_GETENTRY(attrRes);
-
-        if (curPackage != p) {
-            const ssize_t pidx = mTable.getResourcePackageIndex(attrRes);
-            if (pidx < 0) {
-                ALOGE("Style contains key with bad package: 0x%08x\n", attrRes);
-                bag++;
-                continue;
-            }
-            curPackage = p;
-            curPackageIndex = pidx;
-            curPI = mPackages[pidx];
-            if (curPI == NULL) {
-                PackageGroup* const grp = mTable.mPackageGroups[pidx];
-                int cnt = grp->typeCount;
-                curPI = (package_info*)malloc(
-                    sizeof(package_info) + (cnt*sizeof(type_info)));
-                curPI->numTypes = cnt;
-                memset(curPI->types, 0, cnt*sizeof(type_info));
-                mPackages[pidx] = curPI;
-            }
-            curType = 0xffffffff;
-        }
-        if (curType != t) {
-            if (t >= curPI->numTypes) {
-                ALOGE("Style contains key with bad type: 0x%08x\n", attrRes);
-                bag++;
-                continue;
-            }
-            curType = t;
-            curEntries = curPI->types[t].entries;
-            if (curEntries == NULL) {
-                PackageGroup* const grp = mTable.mPackageGroups[curPackageIndex];
-                const Type* type = grp->packages[0]->getType(t);
-                int cnt = type != NULL ? type->entryCount : 0;
-                curEntries = (theme_entry*)malloc(cnt*sizeof(theme_entry));
-                memset(curEntries, Res_value::TYPE_NULL, cnt*sizeof(theme_entry));
-                curPI->types[t].numEntries = cnt;
-                curPI->types[t].entries = curEntries;
-            }
-            numEntries = curPI->types[t].numEntries;
-        }
-        if (e >= numEntries) {
-            ALOGE("Style contains key with bad entry: 0x%08x\n", attrRes);
-            bag++;
-            continue;
-        }
-        theme_entry* curEntry = curEntries + e;
-        TABLE_NOISY(LOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
-                   attrRes, bag->map.value.dataType, bag->map.value.data,
-             curEntry->value.dataType));
-        if (force || curEntry->value.dataType == Res_value::TYPE_NULL) {
-            curEntry->stringBlock = bag->stringBlock;
-            curEntry->typeSpecFlags |= bagTypeSpecFlags;
-            curEntry->value = bag->map.value;
-        }
-
-        bag++;
-    }
-
-    mTable.unlock();
-
-    //ALOGI("Applying style 0x%08x (force=%d)  theme %p...\n", resID, force, this);
-    //dumpToLog();
-    
-    return NO_ERROR;
-}
-
-status_t ResTable::Theme::setTo(const Theme& other)
-{
-    //ALOGI("Setting theme %p from theme %p...\n", this, &other);
-    //dumpToLog();
-    //other.dumpToLog();
-    
-    if (&mTable == &other.mTable) {
-        for (size_t i=0; i<Res_MAXPACKAGE; i++) {
-            if (mPackages[i] != NULL) {
-                free_package(mPackages[i]);
-            }
-            if (other.mPackages[i] != NULL) {
-                mPackages[i] = copy_package(other.mPackages[i]);
-            } else {
-                mPackages[i] = NULL;
-            }
-        }
-    } else {
-        // @todo: need to really implement this, not just copy
-        // the system package (which is still wrong because it isn't
-        // fixing up resource references).
-        for (size_t i=0; i<Res_MAXPACKAGE; i++) {
-            if (mPackages[i] != NULL) {
-                free_package(mPackages[i]);
-            }
-            if (i == 0 && other.mPackages[i] != NULL) {
-                mPackages[i] = copy_package(other.mPackages[i]);
-            } else {
-                mPackages[i] = NULL;
-            }
-        }
-    }
-
-    //ALOGI("Final theme:");
-    //dumpToLog();
-    
-    return NO_ERROR;
-}
-
-ssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue,
-        uint32_t* outTypeSpecFlags) const
-{
-    int cnt = 20;
-
-    if (outTypeSpecFlags != NULL) *outTypeSpecFlags = 0;
-    
-    do {
-        const ssize_t p = mTable.getResourcePackageIndex(resID);
-        const uint32_t t = Res_GETTYPE(resID);
-        const uint32_t e = Res_GETENTRY(resID);
-
-        TABLE_THEME(LOGI("Looking up attr 0x%08x in theme %p", resID, this));
-
-        if (p >= 0) {
-            const package_info* const pi = mPackages[p];
-            TABLE_THEME(LOGI("Found package: %p", pi));
-            if (pi != NULL) {
-                TABLE_THEME(LOGI("Desired type index is %ld in avail %d", t, pi->numTypes));
-                if (t < pi->numTypes) {
-                    const type_info& ti = pi->types[t];
-                    TABLE_THEME(LOGI("Desired entry index is %ld in avail %d", e, ti.numEntries));
-                    if (e < ti.numEntries) {
-                        const theme_entry& te = ti.entries[e];
-                        if (outTypeSpecFlags != NULL) {
-                            *outTypeSpecFlags |= te.typeSpecFlags;
-                        }
-                        TABLE_THEME(LOGI("Theme value: type=0x%x, data=0x%08x",
-                                te.value.dataType, te.value.data));
-                        const uint8_t type = te.value.dataType;
-                        if (type == Res_value::TYPE_ATTRIBUTE) {
-                            if (cnt > 0) {
-                                cnt--;
-                                resID = te.value.data;
-                                continue;
-                            }
-                            ALOGW("Too many attribute references, stopped at: 0x%08x\n", resID);
-                            return BAD_INDEX;
-                        } else if (type != Res_value::TYPE_NULL) {
-                            *outValue = te.value;
-                            return te.stringBlock;
-                        }
-                        return BAD_INDEX;
-                    }
-                }
-            }
-        }
-        break;
-
-    } while (true);
-
-    return BAD_INDEX;
-}
-
-ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,
-        ssize_t blockIndex, uint32_t* outLastRef,
-        uint32_t* inoutTypeSpecFlags, ResTable_config* inoutConfig) const
-{
-    //printf("Resolving type=0x%x\n", inOutValue->dataType);
-    if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
-        uint32_t newTypeSpecFlags;
-        blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags);
-        TABLE_THEME(LOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\n",
-             (int)blockIndex, (int)inOutValue->dataType, (void*)inOutValue->data));
-        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags;
-        //printf("Retrieved attribute new type=0x%x\n", inOutValue->dataType);
-        if (blockIndex < 0) {
-            return blockIndex;
-        }
-    }
-    return mTable.resolveReference(inOutValue, blockIndex, outLastRef,
-            inoutTypeSpecFlags, inoutConfig);
-}
-
-void ResTable::Theme::dumpToLog() const
-{
-    ALOGI("Theme %p:\n", this);
-    for (size_t i=0; i<Res_MAXPACKAGE; i++) {
-        package_info* pi = mPackages[i];
-        if (pi == NULL) continue;
-        
-        ALOGI("  Package #0x%02x:\n", (int)(i+1));
-        for (size_t j=0; j<pi->numTypes; j++) {
-            type_info& ti = pi->types[j];
-            if (ti.numEntries == 0) continue;
-            
-            ALOGI("    Type #0x%02x:\n", (int)(j+1));
-            for (size_t k=0; k<ti.numEntries; k++) {
-                theme_entry& te = ti.entries[k];
-                if (te.value.dataType == Res_value::TYPE_NULL) continue;
-                ALOGI("      0x%08x: t=0x%x, d=0x%08x (block=%d)\n",
-                     (int)Res_MAKEID(i, j, k),
-                     te.value.dataType, (int)te.value.data, (int)te.stringBlock);
-            }
-        }
-    }
-}
-
-ResTable::ResTable()
-    : mError(NO_INIT)
-{
-    memset(&mParams, 0, sizeof(mParams));
-    memset(mPackageMap, 0, sizeof(mPackageMap));
-    //ALOGI("Creating ResTable %p\n", this);
-}
-
-ResTable::ResTable(const void* data, size_t size, void* cookie, bool copyData)
-    : mError(NO_INIT)
-{
-    memset(&mParams, 0, sizeof(mParams));
-    memset(mPackageMap, 0, sizeof(mPackageMap));
-    add(data, size, cookie, copyData);
-    LOG_FATAL_IF(mError != NO_ERROR, "Error parsing resource table");
-    //ALOGI("Creating ResTable %p\n", this);
-}
-
-ResTable::~ResTable()
-{
-    //ALOGI("Destroying ResTable in %p\n", this);
-    uninit();
-}
-
-inline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const
-{
-    return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1;
-}
-
-status_t ResTable::add(const void* data, size_t size, void* cookie, bool copyData,
-                       const void* idmap)
-{
-    return add(data, size, cookie, NULL, copyData, reinterpret_cast<const Asset*>(idmap));
-}
-
-status_t ResTable::add(Asset* asset, void* cookie, bool copyData, const void* idmap)
-{
-    const void* data = asset->getBuffer(true);
-    if (data == NULL) {
-        ALOGW("Unable to get buffer of resource asset file");
-        return UNKNOWN_ERROR;
-    }
-    size_t size = (size_t)asset->getLength();
-    return add(data, size, cookie, asset, copyData, reinterpret_cast<const Asset*>(idmap));
-}
-
-status_t ResTable::add(ResTable* src)
-{
-    mError = src->mError;
-    
-    for (size_t i=0; i<src->mHeaders.size(); i++) {
-        mHeaders.add(src->mHeaders[i]);
-    }
-    
-    for (size_t i=0; i<src->mPackageGroups.size(); i++) {
-        PackageGroup* srcPg = src->mPackageGroups[i];
-        PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id);
-        for (size_t j=0; j<srcPg->packages.size(); j++) {
-            pg->packages.add(srcPg->packages[j]);
-        }
-        pg->basePackage = srcPg->basePackage;
-        pg->typeCount = srcPg->typeCount;
-        mPackageGroups.add(pg);
-    }
-    
-    memcpy(mPackageMap, src->mPackageMap, sizeof(mPackageMap));
-    
-    return mError;
-}
-
-status_t ResTable::add(const void* data, size_t size, void* cookie,
-                       Asset* asset, bool copyData, const Asset* idmap)
-{
-    if (!data) return NO_ERROR;
-    Header* header = new Header(this);
-    header->index = mHeaders.size();
-    header->cookie = cookie;
-    if (idmap != NULL) {
-        const size_t idmap_size = idmap->getLength();
-        const void* idmap_data = const_cast<Asset*>(idmap)->getBuffer(true);
-        header->resourceIDMap = (uint32_t*)malloc(idmap_size);
-        if (header->resourceIDMap == NULL) {
-            delete header;
-            return (mError = NO_MEMORY);
-        }
-        memcpy((void*)header->resourceIDMap, idmap_data, idmap_size);
-        header->resourceIDMapSize = idmap_size;
-    }
-    mHeaders.add(header);
-
-    const bool notDeviceEndian = htods(0xf0) != 0xf0;
-
-    LOAD_TABLE_NOISY(
-        ALOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%p, asset=%p, copy=%d "
-             "idmap=%p\n", data, size, cookie, asset, copyData, idmap));
-    
-    if (copyData || notDeviceEndian) {
-        header->ownedData = malloc(size);
-        if (header->ownedData == NULL) {
-            return (mError=NO_MEMORY);
-        }
-        memcpy(header->ownedData, data, size);
-        data = header->ownedData;
-    }
-
-    header->header = (const ResTable_header*)data;
-    header->size = dtohl(header->header->header.size);
-    //ALOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header->size,
-    //     dtohl(header->header->header.size), header->header->header.size);
-    LOAD_TABLE_NOISY(LOGV("Loading ResTable @%p:\n", header->header));
-    LOAD_TABLE_NOISY(printHexData(2, header->header, header->size < 256 ? header->size : 256,
-                                  16, 16, 0, false, printToLogFunc));
-    if (dtohs(header->header->header.headerSize) > header->size
-            || header->size > size) {
-        ALOGW("Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\n",
-             (int)dtohs(header->header->header.headerSize),
-             (int)header->size, (int)size);
-        return (mError=BAD_TYPE);
-    }
-    if (((dtohs(header->header->header.headerSize)|header->size)&0x3) != 0) {
-        ALOGW("Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\n",
-             (int)dtohs(header->header->header.headerSize),
-             (int)header->size);
-        return (mError=BAD_TYPE);
-    }
-    header->dataEnd = ((const uint8_t*)header->header) + header->size;
-
-    // Iterate through all chunks.
-    size_t curPackage = 0;
-
-    const ResChunk_header* chunk =
-        (const ResChunk_header*)(((const uint8_t*)header->header)
-                                 + dtohs(header->header->header.headerSize));
-    while (((const uint8_t*)chunk) <= (header->dataEnd-sizeof(ResChunk_header)) &&
-           ((const uint8_t*)chunk) <= (header->dataEnd-dtohl(chunk->size))) {
-        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), header->dataEnd, "ResTable");
-        if (err != NO_ERROR) {
-            return (mError=err);
-        }
-        TABLE_NOISY(LOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
-                     dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
-                     (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
-        const size_t csize = dtohl(chunk->size);
-        const uint16_t ctype = dtohs(chunk->type);
-        if (ctype == RES_STRING_POOL_TYPE) {
-            if (header->values.getError() != NO_ERROR) {
-                // Only use the first string chunk; ignore any others that
-                // may appear.
-                status_t err = header->values.setTo(chunk, csize);
-                if (err != NO_ERROR) {
-                    return (mError=err);
-                }
-            } else {
-                ALOGW("Multiple string chunks found in resource table.");
-            }
-        } else if (ctype == RES_TABLE_PACKAGE_TYPE) {
-            if (curPackage >= dtohl(header->header->packageCount)) {
-                ALOGW("More package chunks were found than the %d declared in the header.",
-                     dtohl(header->header->packageCount));
-                return (mError=BAD_TYPE);
-            }
-            uint32_t idmap_id = 0;
-            if (idmap != NULL) {
-                uint32_t tmp;
-                if (getIdmapPackageId(header->resourceIDMap,
-                                      header->resourceIDMapSize,
-                                      &tmp) == NO_ERROR) {
-                    idmap_id = tmp;
-                }
-            }
-            if (parsePackage((ResTable_package*)chunk, header, idmap_id) != NO_ERROR) {
-                return mError;
-            }
-            curPackage++;
-        } else {
-            ALOGW("Unknown chunk type %p in table at %p.\n",
-                 (void*)(int)(ctype),
-                 (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)));
-        }
-        chunk = (const ResChunk_header*)
-            (((const uint8_t*)chunk) + csize);
-    }
-
-    if (curPackage < dtohl(header->header->packageCount)) {
-        ALOGW("Fewer package chunks (%d) were found than the %d declared in the header.",
-             (int)curPackage, dtohl(header->header->packageCount));
-        return (mError=BAD_TYPE);
-    }
-    mError = header->values.getError();
-    if (mError != NO_ERROR) {
-        ALOGW("No string values found in resource table!");
-    }
-
-    TABLE_NOISY(LOGV("Returning from add with mError=%d\n", mError));
-    return mError;
-}
-
-status_t ResTable::getError() const
-{
-    return mError;
-}
-
-void ResTable::uninit()
-{
-    mError = NO_INIT;
-    size_t N = mPackageGroups.size();
-    for (size_t i=0; i<N; i++) {
-        PackageGroup* g = mPackageGroups[i];
-        delete g;
-    }
-    N = mHeaders.size();
-    for (size_t i=0; i<N; i++) {
-        Header* header = mHeaders[i];
-        if (header->owner == this) {
-            if (header->ownedData) {
-                free(header->ownedData);
-            }
-            delete header;
-        }
-    }
-
-    mPackageGroups.clear();
-    mHeaders.clear();
-}
-
-bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const
-{
-    if (mError != NO_ERROR) {
-        return false;
-    }
-
-    const ssize_t p = getResourcePackageIndex(resID);
-    const int t = Res_GETTYPE(resID);
-    const int e = Res_GETENTRY(resID);
-
-    if (p < 0) {
-        if (Res_GETPACKAGE(resID)+1 == 0) {
-            ALOGW("No package identifier when getting name for resource number 0x%08x", resID);
-        } else {
-            ALOGW("No known package when getting name for resource number 0x%08x", resID);
-        }
-        return false;
-    }
-    if (t < 0) {
-        ALOGW("No type identifier when getting name for resource number 0x%08x", resID);
-        return false;
-    }
-
-    const PackageGroup* const grp = mPackageGroups[p];
-    if (grp == NULL) {
-        ALOGW("Bad identifier when getting name for resource number 0x%08x", resID);
-        return false;
-    }
-    if (grp->packages.size() > 0) {
-        const Package* const package = grp->packages[0];
-
-        const ResTable_type* type;
-        const ResTable_entry* entry;
-        ssize_t offset = getEntry(package, t, e, NULL, &type, &entry, NULL);
-        if (offset <= 0) {
-            return false;
-        }
-
-        outName->package = grp->name.string();
-        outName->packageLen = grp->name.size();
-        outName->type = grp->basePackage->typeStrings.stringAt(t, &outName->typeLen);
-        outName->name = grp->basePackage->keyStrings.stringAt(
-            dtohl(entry->key.index), &outName->nameLen);
-
-        // If we have a bad index for some reason, we should abort.
-        if (outName->type == NULL || outName->name == NULL) {
-            return false;
-        }
-
-        return true;
-    }
-
-    return false;
-}
-
-ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag, uint16_t density,
-        uint32_t* outSpecFlags, ResTable_config* outConfig) const
-{
-    if (mError != NO_ERROR) {
-        return mError;
-    }
-
-    const ssize_t p = getResourcePackageIndex(resID);
-    const int t = Res_GETTYPE(resID);
-    const int e = Res_GETENTRY(resID);
-
-    if (p < 0) {
-        if (Res_GETPACKAGE(resID)+1 == 0) {
-            ALOGW("No package identifier when getting value for resource number 0x%08x", resID);
-        } else {
-            ALOGW("No known package when getting value for resource number 0x%08x", resID);
-        }
-        return BAD_INDEX;
-    }
-    if (t < 0) {
-        ALOGW("No type identifier when getting value for resource number 0x%08x", resID);
-        return BAD_INDEX;
-    }
-
-    const Res_value* bestValue = NULL;
-    const Package* bestPackage = NULL;
-    ResTable_config bestItem;
-    memset(&bestItem, 0, sizeof(bestItem)); // make the compiler shut up
-
-    if (outSpecFlags != NULL) *outSpecFlags = 0;
-
-    // Look through all resource packages, starting with the most
-    // recently added.
-    const PackageGroup* const grp = mPackageGroups[p];
-    if (grp == NULL) {
-        ALOGW("Bad identifier when getting value for resource number 0x%08x", resID);
-        return BAD_INDEX;
-    }
-
-    // Allow overriding density
-    const ResTable_config* desiredConfig = &mParams;
-    ResTable_config* overrideConfig = NULL;
-    if (density > 0) {
-        overrideConfig = (ResTable_config*) malloc(sizeof(ResTable_config));
-        if (overrideConfig == NULL) {
-            ALOGE("Couldn't malloc ResTable_config for overrides: %s", strerror(errno));
-            return BAD_INDEX;
-        }
-        memcpy(overrideConfig, &mParams, sizeof(ResTable_config));
-        overrideConfig->density = density;
-        desiredConfig = overrideConfig;
-    }
-
-    ssize_t rc = BAD_VALUE;
-    size_t ip = grp->packages.size();
-    while (ip > 0) {
-        ip--;
-        int T = t;
-        int E = e;
-
-        const Package* const package = grp->packages[ip];
-        if (package->header->resourceIDMap) {
-            uint32_t overlayResID = 0x0;
-            status_t retval = idmapLookup(package->header->resourceIDMap,
-                                          package->header->resourceIDMapSize,
-                                          resID, &overlayResID);
-            if (retval == NO_ERROR && overlayResID != 0x0) {
-                // for this loop iteration, this is the type and entry we really want
-                ALOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID);
-                T = Res_GETTYPE(overlayResID);
-                E = Res_GETENTRY(overlayResID);
-            } else {
-                // resource not present in overlay package, continue with the next package
-                continue;
-            }
-        }
-
-        const ResTable_type* type;
-        const ResTable_entry* entry;
-        const Type* typeClass;
-        ssize_t offset = getEntry(package, T, E, desiredConfig, &type, &entry, &typeClass);
-        if (offset <= 0) {
-            // No {entry, appropriate config} pair found in package. If this
-            // package is an overlay package (ip != 0), this simply means the
-            // overlay package did not specify a default.
-            // Non-overlay packages are still required to provide a default.
-            if (offset < 0 && ip == 0) {
-                ALOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %zd (error %d)\n",
-                        resID, T, E, ip, (int)offset);
-                rc = offset;
-                goto out;
-            }
-            continue;
-        }
-
-        if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) != 0) {
-            if (!mayBeBag) {
-                ALOGW("Requesting resource %p failed because it is complex\n",
-                     (void*)resID);
-            }
-            continue;
-        }
-
-        TABLE_NOISY(aout << "Resource type data: "
-              << HexDump(type, dtohl(type->header.size)) << endl);
-
-        if ((size_t)offset > (dtohl(type->header.size)-sizeof(Res_value))) {
-            ALOGW("ResTable_item at %d is beyond type chunk data %d",
-                 (int)offset, dtohl(type->header.size));
-            rc = BAD_TYPE;
-            goto out;
-        }
-
-        const Res_value* item =
-            (const Res_value*)(((const uint8_t*)type) + offset);
-        ResTable_config thisConfig;
-        thisConfig.copyFromDtoH(type->config);
-
-        if (outSpecFlags != NULL) {
-            if (typeClass->typeSpecFlags != NULL) {
-                *outSpecFlags |= dtohl(typeClass->typeSpecFlags[E]);
-            } else {
-                *outSpecFlags = -1;
-            }
-        }
-
-        if (bestPackage != NULL &&
-            (bestItem.isMoreSpecificThan(thisConfig) || bestItem.diff(thisConfig) == 0)) {
-            // Discard thisConfig not only if bestItem is more specific, but also if the two configs
-            // are identical (diff == 0), or overlay packages will not take effect.
-            continue;
-        }
-        
-        bestItem = thisConfig;
-        bestValue = item;
-        bestPackage = package;
-    }
-
-    TABLE_NOISY(printf("Found result: package %p\n", bestPackage));
-
-    if (bestValue) {
-        outValue->size = dtohs(bestValue->size);
-        outValue->res0 = bestValue->res0;
-        outValue->dataType = bestValue->dataType;
-        outValue->data = dtohl(bestValue->data);
-        if (outConfig != NULL) {
-            *outConfig = bestItem;
-        }
-        TABLE_NOISY(size_t len;
-              printf("Found value: pkg=%d, type=%d, str=%s, int=%d\n",
-                     bestPackage->header->index,
-                     outValue->dataType,
-                     outValue->dataType == bestValue->TYPE_STRING
-                     ? String8(bestPackage->header->values.stringAt(
-                         outValue->data, &len)).string()
-                     : "",
-                     outValue->data));
-        rc = bestPackage->header->index;
-        goto out;
-    }
-
-out:
-    if (overrideConfig != NULL) {
-        free(overrideConfig);
-    }
-
-    return rc;
-}
-
-ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
-        uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags,
-        ResTable_config* outConfig) const
-{
-    int count=0;
-    while (blockIndex >= 0 && value->dataType == value->TYPE_REFERENCE
-           && value->data != 0 && count < 20) {
-        if (outLastRef) *outLastRef = value->data;
-        uint32_t lastRef = value->data;
-        uint32_t newFlags = 0;
-        const ssize_t newIndex = getResource(value->data, value, true, 0, &newFlags,
-                outConfig);
-        if (newIndex == BAD_INDEX) {
-            return BAD_INDEX;
-        }
-        TABLE_THEME(LOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n",
-             (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data));
-        //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);
-        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags;
-        if (newIndex < 0) {
-            // This can fail if the resource being referenced is a style...
-            // in this case, just return the reference, and expect the
-            // caller to deal with.
-            return blockIndex;
-        }
-        blockIndex = newIndex;
-        count++;
-    }
-    return blockIndex;
-}
-
-const char16_t* ResTable::valueToString(
-    const Res_value* value, size_t stringBlock,
-    char16_t tmpBuffer[TMP_BUFFER_SIZE], size_t* outLen)
-{
-    if (!value) {
-        return NULL;
-    }
-    if (value->dataType == value->TYPE_STRING) {
-        return getTableStringBlock(stringBlock)->stringAt(value->data, outLen);
-    }
-    // XXX do int to string conversions.
-    return NULL;
-}
-
-ssize_t ResTable::lockBag(uint32_t resID, const bag_entry** outBag) const
-{
-    mLock.lock();
-    ssize_t err = getBagLocked(resID, outBag);
-    if (err < NO_ERROR) {
-        //printf("*** get failed!  unlocking\n");
-        mLock.unlock();
-    }
-    return err;
-}
-
-void ResTable::unlockBag(const bag_entry* bag) const
-{
-    //printf("<<< unlockBag %p\n", this);
-    mLock.unlock();
-}
-
-void ResTable::lock() const
-{
-    mLock.lock();
-}
-
-void ResTable::unlock() const
-{
-    mLock.unlock();
-}
-
-ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
-        uint32_t* outTypeSpecFlags) const
-{
-    if (mError != NO_ERROR) {
-        return mError;
-    }
-
-    const ssize_t p = getResourcePackageIndex(resID);
-    const int t = Res_GETTYPE(resID);
-    const int e = Res_GETENTRY(resID);
-
-    if (p < 0) {
-        ALOGW("Invalid package identifier when getting bag for resource number 0x%08x", resID);
-        return BAD_INDEX;
-    }
-    if (t < 0) {
-        ALOGW("No type identifier when getting bag for resource number 0x%08x", resID);
-        return BAD_INDEX;
-    }
-
-    //printf("Get bag: id=0x%08x, p=%d, t=%d\n", resID, p, t);
-    PackageGroup* const grp = mPackageGroups[p];
-    if (grp == NULL) {
-        ALOGW("Bad identifier when getting bag for resource number 0x%08x", resID);
-        return false;
-    }
-
-    if (t >= (int)grp->typeCount) {
-        ALOGW("Type identifier 0x%x is larger than type count 0x%x",
-             t+1, (int)grp->typeCount);
-        return BAD_INDEX;
-    }
-
-    const Package* const basePackage = grp->packages[0];
-
-    const Type* const typeConfigs = basePackage->getType(t);
-
-    const size_t NENTRY = typeConfigs->entryCount;
-    if (e >= (int)NENTRY) {
-        ALOGW("Entry identifier 0x%x is larger than entry count 0x%x",
-             e, (int)typeConfigs->entryCount);
-        return BAD_INDEX;
-    }
-
-    // First see if we've already computed this bag...
-    if (grp->bags) {
-        bag_set** typeSet = grp->bags[t];
-        if (typeSet) {
-            bag_set* set = typeSet[e];
-            if (set) {
-                if (set != (bag_set*)0xFFFFFFFF) {
-                    if (outTypeSpecFlags != NULL) {
-                        *outTypeSpecFlags = set->typeSpecFlags;
-                    }
-                    *outBag = (bag_entry*)(set+1);
-                    //ALOGI("Found existing bag for: %p\n", (void*)resID);
-                    return set->numAttrs;
-                }
-                ALOGW("Attempt to retrieve bag 0x%08x which is invalid or in a cycle.",
-                     resID);
-                return BAD_INDEX;
-            }
-        }
-    }
-
-    // Bag not found, we need to compute it!
-    if (!grp->bags) {
-        grp->bags = (bag_set***)calloc(grp->typeCount, sizeof(bag_set*));
-        if (!grp->bags) return NO_MEMORY;
-    }
-
-    bag_set** typeSet = grp->bags[t];
-    if (!typeSet) {
-        typeSet = (bag_set**)calloc(NENTRY, sizeof(bag_set*));
-        if (!typeSet) return NO_MEMORY;
-        grp->bags[t] = typeSet;
-    }
-
-    // Mark that we are currently working on this one.
-    typeSet[e] = (bag_set*)0xFFFFFFFF;
-
-    // This is what we are building.
-    bag_set* set = NULL;
-
-    TABLE_NOISY(LOGI("Building bag: %p\n", (void*)resID));
-    
-    ResTable_config bestConfig;
-    memset(&bestConfig, 0, sizeof(bestConfig));
-
-    // Now collect all bag attributes from all packages.
-    size_t ip = grp->packages.size();
-    while (ip > 0) {
-        ip--;
-        int T = t;
-        int E = e;
-
-        const Package* const package = grp->packages[ip];
-        if (package->header->resourceIDMap) {
-            uint32_t overlayResID = 0x0;
-            status_t retval = idmapLookup(package->header->resourceIDMap,
-                                          package->header->resourceIDMapSize,
-                                          resID, &overlayResID);
-            if (retval == NO_ERROR && overlayResID != 0x0) {
-                // for this loop iteration, this is the type and entry we really want
-                ALOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID);
-                T = Res_GETTYPE(overlayResID);
-                E = Res_GETENTRY(overlayResID);
-            } else {
-                // resource not present in overlay package, continue with the next package
-                continue;
-            }
-        }
-
-        const ResTable_type* type;
-        const ResTable_entry* entry;
-        const Type* typeClass;
-        ALOGV("Getting entry pkg=%p, t=%d, e=%d\n", package, T, E);
-        ssize_t offset = getEntry(package, T, E, &mParams, &type, &entry, &typeClass);
-        ALOGV("Resulting offset=%d\n", offset);
-        if (offset <= 0) {
-            // No {entry, appropriate config} pair found in package. If this
-            // package is an overlay package (ip != 0), this simply means the
-            // overlay package did not specify a default.
-            // Non-overlay packages are still required to provide a default.
-            if (offset < 0 && ip == 0) {
-                if (set) free(set);
-                return offset;
-            }
-            continue;
-        }
-
-        if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) == 0) {
-            ALOGW("Skipping entry %p in package table %d because it is not complex!\n",
-                 (void*)resID, (int)ip);
-            continue;
-        }
-
-        if (set != NULL && !type->config.isBetterThan(bestConfig, NULL)) {
-            continue;
-        }
-        bestConfig = type->config;
-        if (set) {
-            free(set);
-            set = NULL;
-        }
-
-        const uint16_t entrySize = dtohs(entry->size);
-        const uint32_t parent = entrySize >= sizeof(ResTable_map_entry)
-            ? dtohl(((const ResTable_map_entry*)entry)->parent.ident) : 0;
-        const uint32_t count = entrySize >= sizeof(ResTable_map_entry)
-            ? dtohl(((const ResTable_map_entry*)entry)->count) : 0;
-        
-        size_t N = count;
-
-        TABLE_NOISY(LOGI("Found map: size=%p parent=%p count=%d\n",
-                         entrySize, parent, count));
-
-        // If this map inherits from another, we need to start
-        // with its parent's values.  Otherwise start out empty.
-        TABLE_NOISY(printf("Creating new bag, entrySize=0x%08x, parent=0x%08x\n",
-                           entrySize, parent));
-        if (parent) {
-            const bag_entry* parentBag;
-            uint32_t parentTypeSpecFlags = 0;
-            const ssize_t NP = getBagLocked(parent, &parentBag, &parentTypeSpecFlags);
-            const size_t NT = ((NP >= 0) ? NP : 0) + N;
-            set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*NT);
-            if (set == NULL) {
-                return NO_MEMORY;
-            }
-            if (NP > 0) {
-                memcpy(set+1, parentBag, NP*sizeof(bag_entry));
-                set->numAttrs = NP;
-                TABLE_NOISY(LOGI("Initialized new bag with %d inherited attributes.\n", NP));
-            } else {
-                TABLE_NOISY(LOGI("Initialized new bag with no inherited attributes.\n"));
-                set->numAttrs = 0;
-            }
-            set->availAttrs = NT;
-            set->typeSpecFlags = parentTypeSpecFlags;
-        } else {
-            set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*N);
-            if (set == NULL) {
-                return NO_MEMORY;
-            }
-            set->numAttrs = 0;
-            set->availAttrs = N;
-            set->typeSpecFlags = 0;
-        }
-
-        if (typeClass->typeSpecFlags != NULL) {
-            set->typeSpecFlags |= dtohl(typeClass->typeSpecFlags[E]);
-        } else {
-            set->typeSpecFlags = -1;
-        }
-        
-        // Now merge in the new attributes...
-        ssize_t curOff = offset;
-        const ResTable_map* map;
-        bag_entry* entries = (bag_entry*)(set+1);
-        size_t curEntry = 0;
-        uint32_t pos = 0;
-        TABLE_NOISY(LOGI("Starting with set %p, entries=%p, avail=%d\n",
-                     set, entries, set->availAttrs));
-        while (pos < count) {
-            TABLE_NOISY(printf("Now at %p\n", (void*)curOff));
-
-            if ((size_t)curOff > (dtohl(type->header.size)-sizeof(ResTable_map))) {
-                ALOGW("ResTable_map at %d is beyond type chunk data %d",
-                     (int)curOff, dtohl(type->header.size));
-                return BAD_TYPE;
-            }
-            map = (const ResTable_map*)(((const uint8_t*)type) + curOff);
-            N++;
-
-            const uint32_t newName = htodl(map->name.ident);
-            bool isInside;
-            uint32_t oldName = 0;
-            while ((isInside=(curEntry < set->numAttrs))
-                    && (oldName=entries[curEntry].map.name.ident) < newName) {
-                TABLE_NOISY(printf("#%d: Keeping existing attribute: 0x%08x\n",
-                             curEntry, entries[curEntry].map.name.ident));
-                curEntry++;
-            }
-
-            if ((!isInside) || oldName != newName) {
-                // This is a new attribute...  figure out what to do with it.
-                if (set->numAttrs >= set->availAttrs) {
-                    // Need to alloc more memory...
-                    const size_t newAvail = set->availAttrs+N;
-                    set = (bag_set*)realloc(set,
-                                            sizeof(bag_set)
-                                            + sizeof(bag_entry)*newAvail);
-                    if (set == NULL) {
-                        return NO_MEMORY;
-                    }
-                    set->availAttrs = newAvail;
-                    entries = (bag_entry*)(set+1);
-                    TABLE_NOISY(printf("Reallocated set %p, entries=%p, avail=%d\n",
-                                 set, entries, set->availAttrs));
-                }
-                if (isInside) {
-                    // Going in the middle, need to make space.
-                    memmove(entries+curEntry+1, entries+curEntry,
-                            sizeof(bag_entry)*(set->numAttrs-curEntry));
-                    set->numAttrs++;
-                }
-                TABLE_NOISY(printf("#%d: Inserting new attribute: 0x%08x\n",
-                             curEntry, newName));
-            } else {
-                TABLE_NOISY(printf("#%d: Replacing existing attribute: 0x%08x\n",
-                             curEntry, oldName));
-            }
-
-            bag_entry* cur = entries+curEntry;
-
-            cur->stringBlock = package->header->index;
-            cur->map.name.ident = newName;
-            cur->map.value.copyFrom_dtoh(map->value);
-            TABLE_NOISY(printf("Setting entry #%d %p: block=%d, name=0x%08x, type=%d, data=0x%08x\n",
-                         curEntry, cur, cur->stringBlock, cur->map.name.ident,
-                         cur->map.value.dataType, cur->map.value.data));
-
-            // On to the next!
-            curEntry++;
-            pos++;
-            const size_t size = dtohs(map->value.size);
-            curOff += size + sizeof(*map)-sizeof(map->value);
-        };
-        if (curEntry > set->numAttrs) {
-            set->numAttrs = curEntry;
-        }
-    }
-
-    // And this is it...
-    typeSet[e] = set;
-    if (set) {
-        if (outTypeSpecFlags != NULL) {
-            *outTypeSpecFlags = set->typeSpecFlags;
-        }
-        *outBag = (bag_entry*)(set+1);
-        TABLE_NOISY(LOGI("Returning %d attrs\n", set->numAttrs));
-        return set->numAttrs;
-    }
-    return BAD_INDEX;
-}
-
-void ResTable::setParameters(const ResTable_config* params)
-{
-    mLock.lock();
-    TABLE_GETENTRY(LOGI("Setting parameters: imsi:%d/%d lang:%c%c cnt:%c%c "
-                        "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d sw%ddp w%ddp h%ddp\n",
-                       params->mcc, params->mnc,
-                       params->language[0] ? params->language[0] : '-',
-                       params->language[1] ? params->language[1] : '-',
-                       params->country[0] ? params->country[0] : '-',
-                       params->country[1] ? params->country[1] : '-',
-                       params->orientation,
-                       params->touchscreen,
-                       params->density,
-                       params->keyboard,
-                       params->inputFlags,
-                       params->navigation,
-                       params->screenWidth,
-                       params->screenHeight,
-                       params->smallestScreenWidthDp,
-                       params->screenWidthDp,
-                       params->screenHeightDp));
-    mParams = *params;
-    for (size_t i=0; i<mPackageGroups.size(); i++) {
-        TABLE_NOISY(LOGI("CLEARING BAGS FOR GROUP %d!", i));
-        mPackageGroups[i]->clearBagCache();
-    }
-    mLock.unlock();
-}
-
-void ResTable::getParameters(ResTable_config* params) const
-{
-    mLock.lock();
-    *params = mParams;
-    mLock.unlock();
-}
-
-struct id_name_map {
-    uint32_t id;
-    size_t len;
-    char16_t name[6];
-};
-
-const static id_name_map ID_NAMES[] = {
-    { ResTable_map::ATTR_TYPE,  5, { '^', 't', 'y', 'p', 'e' } },
-    { ResTable_map::ATTR_L10N,  5, { '^', 'l', '1', '0', 'n' } },
-    { ResTable_map::ATTR_MIN,   4, { '^', 'm', 'i', 'n' } },
-    { ResTable_map::ATTR_MAX,   4, { '^', 'm', 'a', 'x' } },
-    { ResTable_map::ATTR_OTHER, 6, { '^', 'o', 't', 'h', 'e', 'r' } },
-    { ResTable_map::ATTR_ZERO,  5, { '^', 'z', 'e', 'r', 'o' } },
-    { ResTable_map::ATTR_ONE,   4, { '^', 'o', 'n', 'e' } },
-    { ResTable_map::ATTR_TWO,   4, { '^', 't', 'w', 'o' } },
-    { ResTable_map::ATTR_FEW,   4, { '^', 'f', 'e', 'w' } },
-    { ResTable_map::ATTR_MANY,  5, { '^', 'm', 'a', 'n', 'y' } },
-};
-
-uint32_t ResTable::identifierForName(const char16_t* name, size_t nameLen,
-                                     const char16_t* type, size_t typeLen,
-                                     const char16_t* package,
-                                     size_t packageLen,
-                                     uint32_t* outTypeSpecFlags) const
-{
-    TABLE_SUPER_NOISY(printf("Identifier for name: error=%d\n", mError));
-
-    // Check for internal resource identifier as the very first thing, so
-    // that we will always find them even when there are no resources.
-    if (name[0] == '^') {
-        const int N = (sizeof(ID_NAMES)/sizeof(ID_NAMES[0]));
-        size_t len;
-        for (int i=0; i<N; i++) {
-            const id_name_map* m = ID_NAMES + i;
-            len = m->len;
-            if (len != nameLen) {
-                continue;
-            }
-            for (size_t j=1; j<len; j++) {
-                if (m->name[j] != name[j]) {
-                    goto nope;
-                }
-            }
-            if (outTypeSpecFlags) {
-                *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC;
-            }
-            return m->id;
-nope:
-            ;
-        }
-        if (nameLen > 7) {
-            if (name[1] == 'i' && name[2] == 'n'
-                && name[3] == 'd' && name[4] == 'e' && name[5] == 'x'
-                && name[6] == '_') {
-                int index = atoi(String8(name + 7, nameLen - 7).string());
-                if (Res_CHECKID(index)) {
-                    ALOGW("Array resource index: %d is too large.",
-                         index);
-                    return 0;
-                }
-                if (outTypeSpecFlags) {
-                    *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC;
-                }
-                return  Res_MAKEARRAY(index);
-            }
-        }
-        return 0;
-    }
-
-    if (mError != NO_ERROR) {
-        return 0;
-    }
-
-    bool fakePublic = false;
-
-    // Figure out the package and type we are looking in...
-
-    const char16_t* packageEnd = NULL;
-    const char16_t* typeEnd = NULL;
-    const char16_t* const nameEnd = name+nameLen;
-    const char16_t* p = name;
-    while (p < nameEnd) {
-        if (*p == ':') packageEnd = p;
-        else if (*p == '/') typeEnd = p;
-        p++;
-    }
-    if (*name == '@') {
-        name++;
-        if (*name == '*') {
-            fakePublic = true;
-            name++;
-        }
-    }
-    if (name >= nameEnd) {
-        return 0;
-    }
-
-    if (packageEnd) {
-        package = name;
-        packageLen = packageEnd-name;
-        name = packageEnd+1;
-    } else if (!package) {
-        return 0;
-    }
-
-    if (typeEnd) {
-        type = name;
-        typeLen = typeEnd-name;
-        name = typeEnd+1;
-    } else if (!type) {
-        return 0;
-    }
-
-    if (name >= nameEnd) {
-        return 0;
-    }
-    nameLen = nameEnd-name;
-
-    TABLE_NOISY(printf("Looking for identifier: type=%s, name=%s, package=%s\n",
-                 String8(type, typeLen).string(),
-                 String8(name, nameLen).string(),
-                 String8(package, packageLen).string()));
-
-    const size_t NG = mPackageGroups.size();
-    for (size_t ig=0; ig<NG; ig++) {
-        const PackageGroup* group = mPackageGroups[ig];
-
-        if (strzcmp16(package, packageLen,
-                      group->name.string(), group->name.size())) {
-            TABLE_NOISY(printf("Skipping package group: %s\n", String8(group->name).string()));
-            continue;
-        }
-
-        const ssize_t ti = group->basePackage->typeStrings.indexOfString(type, typeLen);
-        if (ti < 0) {
-            TABLE_NOISY(printf("Type not found in package %s\n", String8(group->name).string()));
-            continue;
-        }
-
-        const ssize_t ei = group->basePackage->keyStrings.indexOfString(name, nameLen);
-        if (ei < 0) {
-            TABLE_NOISY(printf("Name not found in package %s\n", String8(group->name).string()));
-            continue;
-        }
-
-        TABLE_NOISY(printf("Search indices: type=%d, name=%d\n", ti, ei));
-
-        const Type* const typeConfigs = group->packages[0]->getType(ti);
-        if (typeConfigs == NULL || typeConfigs->configs.size() <= 0) {
-            TABLE_NOISY(printf("Expected type structure not found in package %s for idnex %d\n",
-                               String8(group->name).string(), ti));
-        }
-        
-        size_t NTC = typeConfigs->configs.size();
-        for (size_t tci=0; tci<NTC; tci++) {
-            const ResTable_type* const ty = typeConfigs->configs[tci];
-            const uint32_t typeOffset = dtohl(ty->entriesStart);
-
-            const uint8_t* const end = ((const uint8_t*)ty) + dtohl(ty->header.size);
-            const uint32_t* const eindex = (const uint32_t*)
-                (((const uint8_t*)ty) + dtohs(ty->header.headerSize));
-
-            const size_t NE = dtohl(ty->entryCount);
-            for (size_t i=0; i<NE; i++) {
-                uint32_t offset = dtohl(eindex[i]);
-                if (offset == ResTable_type::NO_ENTRY) {
-                    continue;
-                }
-                
-                offset += typeOffset;
-                
-                if (offset > (dtohl(ty->header.size)-sizeof(ResTable_entry))) {
-                    ALOGW("ResTable_entry at %d is beyond type chunk data %d",
-                         offset, dtohl(ty->header.size));
-                    return 0;
-                }
-                if ((offset&0x3) != 0) {
-                    ALOGW("ResTable_entry at %d (pkg=%d type=%d ent=%d) is not on an integer boundary when looking for %s:%s/%s",
-                         (int)offset, (int)group->id, (int)ti+1, (int)i,
-                         String8(package, packageLen).string(),
-                         String8(type, typeLen).string(),
-                         String8(name, nameLen).string());
-                    return 0;
-                }
-                
-                const ResTable_entry* const entry = (const ResTable_entry*)
-                    (((const uint8_t*)ty) + offset);
-                if (dtohs(entry->size) < sizeof(*entry)) {
-                    ALOGW("ResTable_entry size %d is too small", dtohs(entry->size));
-                    return BAD_TYPE;
-                }
-
-                TABLE_SUPER_NOISY(printf("Looking at entry #%d: want str %d, have %d\n",
-                                         i, ei, dtohl(entry->key.index)));
-                if (dtohl(entry->key.index) == (size_t)ei) {
-                    if (outTypeSpecFlags) {
-                        *outTypeSpecFlags = typeConfigs->typeSpecFlags[i];
-                        if (fakePublic) {
-                            *outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC;
-                        }
-                    }
-                    return Res_MAKEID(group->id-1, ti, i);
-                }
-            }
-        }
-    }
-
-    return 0;
-}
-
-bool ResTable::expandResourceRef(const uint16_t* refStr, size_t refLen,
-                                 String16* outPackage,
-                                 String16* outType,
-                                 String16* outName,
-                                 const String16* defType,
-                                 const String16* defPackage,
-                                 const char** outErrorMsg,
-                                 bool* outPublicOnly)
-{
-    const char16_t* packageEnd = NULL;
-    const char16_t* typeEnd = NULL;
-    const char16_t* p = refStr;
-    const char16_t* const end = p + refLen;
-    while (p < end) {
-        if (*p == ':') packageEnd = p;
-        else if (*p == '/') {
-            typeEnd = p;
-            break;
-        }
-        p++;
-    }
-    p = refStr;
-    if (*p == '@') p++;
-
-    if (outPublicOnly != NULL) {
-        *outPublicOnly = true;
-    }
-    if (*p == '*') {
-        p++;
-        if (outPublicOnly != NULL) {
-            *outPublicOnly = false;
-        }
-    }
-
-    if (packageEnd) {
-        *outPackage = String16(p, packageEnd-p);
-        p = packageEnd+1;
-    } else {
-        if (!defPackage) {
-            if (outErrorMsg) {
-                *outErrorMsg = "No resource package specified";
-            }
-            return false;
-        }
-        *outPackage = *defPackage;
-    }
-    if (typeEnd) {
-        *outType = String16(p, typeEnd-p);
-        p = typeEnd+1;
-    } else {
-        if (!defType) {
-            if (outErrorMsg) {
-                *outErrorMsg = "No resource type specified";
-            }
-            return false;
-        }
-        *outType = *defType;
-    }
-    *outName = String16(p, end-p);
-    if(**outPackage == 0) {
-        if(outErrorMsg) {
-            *outErrorMsg = "Resource package cannot be an empty string";
-        }
-        return false;
-    }
-    if(**outType == 0) {
-        if(outErrorMsg) {
-            *outErrorMsg = "Resource type cannot be an empty string";
-        }
-        return false;
-    }
-    if(**outName == 0) {
-        if(outErrorMsg) {
-            *outErrorMsg = "Resource id cannot be an empty string";
-        }
-        return false;
-    }
-    return true;
-}
-
-static uint32_t get_hex(char c, bool* outError)
-{
-    if (c >= '0' && c <= '9') {
-        return c - '0';
-    } else if (c >= 'a' && c <= 'f') {
-        return c - 'a' + 0xa;
-    } else if (c >= 'A' && c <= 'F') {
-        return c - 'A' + 0xa;
-    }
-    *outError = true;
-    return 0;
-}
-
-struct unit_entry
-{
-    const char* name;
-    size_t len;
-    uint8_t type;
-    uint32_t unit;
-    float scale;
-};
-
-static const unit_entry unitNames[] = {
-    { "px", strlen("px"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PX, 1.0f },
-    { "dip", strlen("dip"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },
-    { "dp", strlen("dp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },
-    { "sp", strlen("sp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_SP, 1.0f },
-    { "pt", strlen("pt"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PT, 1.0f },
-    { "in", strlen("in"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_IN, 1.0f },
-    { "mm", strlen("mm"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_MM, 1.0f },
-    { "%", strlen("%"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION, 1.0f/100 },
-    { "%p", strlen("%p"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100 },
-    { NULL, 0, 0, 0, 0 }
-};
-
-static bool parse_unit(const char* str, Res_value* outValue,
-                       float* outScale, const char** outEnd)
-{
-    const char* end = str;
-    while (*end != 0 && !isspace((unsigned char)*end)) {
-        end++;
-    }
-    const size_t len = end-str;
-
-    const char* realEnd = end;
-    while (*realEnd != 0 && isspace((unsigned char)*realEnd)) {
-        realEnd++;
-    }
-    if (*realEnd != 0) {
-        return false;
-    }
-    
-    const unit_entry* cur = unitNames;
-    while (cur->name) {
-        if (len == cur->len && strncmp(cur->name, str, len) == 0) {
-            outValue->dataType = cur->type;
-            outValue->data = cur->unit << Res_value::COMPLEX_UNIT_SHIFT;
-            *outScale = cur->scale;
-            *outEnd = end;
-            //printf("Found unit %s for %s\n", cur->name, str);
-            return true;
-        }
-        cur++;
-    }
-
-    return false;
-}
-
-
-bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue)
-{
-    while (len > 0 && isspace16(*s)) {
-        s++;
-        len--;
-    }
-
-    if (len <= 0) {
-        return false;
-    }
-
-    size_t i = 0;
-    int32_t val = 0;
-    bool neg = false;
-
-    if (*s == '-') {
-        neg = true;
-        i++;
-    }
-
-    if (s[i] < '0' || s[i] > '9') {
-        return false;
-    }
-
-    // Decimal or hex?
-    if (s[i] == '0' && s[i+1] == 'x') {
-        if (outValue)
-            outValue->dataType = outValue->TYPE_INT_HEX;
-        i += 2;
-        bool error = false;
-        while (i < len && !error) {
-            val = (val*16) + get_hex(s[i], &error);
-            i++;
-        }
-        if (error) {
-            return false;
-        }
-    } else {
-        if (outValue)
-            outValue->dataType = outValue->TYPE_INT_DEC;
-        while (i < len) {
-            if (s[i] < '0' || s[i] > '9') {
-                return false;
-            }
-            val = (val*10) + s[i]-'0';
-            i++;
-        }
-    }
-
-    if (neg) val = -val;
-
-    while (i < len && isspace16(s[i])) {
-        i++;
-    }
-
-    if (i == len) {
-        if (outValue)
-            outValue->data = val;
-        return true;
-    }
-
-    return false;
-}
-
-bool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue)
-{
-    while (len > 0 && isspace16(*s)) {
-        s++;
-        len--;
-    }
-
-    if (len <= 0) {
-        return false;
-    }
-
-    char buf[128];
-    int i=0;
-    while (len > 0 && *s != 0 && i < 126) {
-        if (*s > 255) {
-            return false;
-        }
-        buf[i++] = *s++;
-        len--;
-    }
-
-    if (len > 0) {
-        return false;
-    }
-    if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') {
-        return false;
-    }
-
-    buf[i] = 0;
-    const char* end;
-    float f = strtof(buf, (char**)&end);
-
-    if (*end != 0 && !isspace((unsigned char)*end)) {
-        // Might be a unit...
-        float scale;
-        if (parse_unit(end, outValue, &scale, &end)) {
-            f *= scale;
-            const bool neg = f < 0;
-            if (neg) f = -f;
-            uint64_t bits = (uint64_t)(f*(1<<23)+.5f);
-            uint32_t radix;
-            uint32_t shift;
-            if ((bits&0x7fffff) == 0) {
-                // Always use 23p0 if there is no fraction, just to make
-                // things easier to read.
-                radix = Res_value::COMPLEX_RADIX_23p0;
-                shift = 23;
-            } else if ((bits&0xffffffffff800000LL) == 0) {
-                // Magnitude is zero -- can fit in 0 bits of precision.
-                radix = Res_value::COMPLEX_RADIX_0p23;
-                shift = 0;
-            } else if ((bits&0xffffffff80000000LL) == 0) {
-                // Magnitude can fit in 8 bits of precision.
-                radix = Res_value::COMPLEX_RADIX_8p15;
-                shift = 8;
-            } else if ((bits&0xffffff8000000000LL) == 0) {
-                // Magnitude can fit in 16 bits of precision.
-                radix = Res_value::COMPLEX_RADIX_16p7;
-                shift = 16;
-            } else {
-                // Magnitude needs entire range, so no fractional part.
-                radix = Res_value::COMPLEX_RADIX_23p0;
-                shift = 23;
-            }
-            int32_t mantissa = (int32_t)(
-                (bits>>shift) & Res_value::COMPLEX_MANTISSA_MASK);
-            if (neg) {
-                mantissa = (-mantissa) & Res_value::COMPLEX_MANTISSA_MASK;
-            }
-            outValue->data |= 
-                (radix<<Res_value::COMPLEX_RADIX_SHIFT)
-                | (mantissa<<Res_value::COMPLEX_MANTISSA_SHIFT);
-            //printf("Input value: %f 0x%016Lx, mult: %f, radix: %d, shift: %d, final: 0x%08x\n",
-            //       f * (neg ? -1 : 1), bits, f*(1<<23),
-            //       radix, shift, outValue->data);
-            return true;
-        }
-        return false;
-    }
-
-    while (*end != 0 && isspace((unsigned char)*end)) {
-        end++;
-    }
-
-    if (*end == 0) {
-        if (outValue) {
-            outValue->dataType = outValue->TYPE_FLOAT;
-            *(float*)(&outValue->data) = f;
-            return true;
-        }
-    }
-
-    return false;
-}
-
-bool ResTable::stringToValue(Res_value* outValue, String16* outString,
-                             const char16_t* s, size_t len,
-                             bool preserveSpaces, bool coerceType,
-                             uint32_t attrID,
-                             const String16* defType,
-                             const String16* defPackage,
-                             Accessor* accessor,
-                             void* accessorCookie,
-                             uint32_t attrType,
-                             bool enforcePrivate) const
-{
-    bool localizationSetting = accessor != NULL && accessor->getLocalizationSetting();
-    const char* errorMsg = NULL;
-
-    outValue->size = sizeof(Res_value);
-    outValue->res0 = 0;
-
-    // First strip leading/trailing whitespace.  Do this before handling
-    // escapes, so they can be used to force whitespace into the string.
-    if (!preserveSpaces) {
-        while (len > 0 && isspace16(*s)) {
-            s++;
-            len--;
-        }
-        while (len > 0 && isspace16(s[len-1])) {
-            len--;
-        }
-        // If the string ends with '\', then we keep the space after it.
-        if (len > 0 && s[len-1] == '\\' && s[len] != 0) {
-            len++;
-        }
-    }
-
-    //printf("Value for: %s\n", String8(s, len).string());
-
-    uint32_t l10nReq = ResTable_map::L10N_NOT_REQUIRED;
-    uint32_t attrMin = 0x80000000, attrMax = 0x7fffffff;
-    bool fromAccessor = false;
-    if (attrID != 0 && !Res_INTERNALID(attrID)) {
-        const ssize_t p = getResourcePackageIndex(attrID);
-        const bag_entry* bag;
-        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
-        //printf("For attr 0x%08x got bag of %d\n", attrID, cnt);
-        if (cnt >= 0) {
-            while (cnt > 0) {
-                //printf("Entry 0x%08x = 0x%08x\n", bag->map.name.ident, bag->map.value.data);
-                switch (bag->map.name.ident) {
-                case ResTable_map::ATTR_TYPE:
-                    attrType = bag->map.value.data;
-                    break;
-                case ResTable_map::ATTR_MIN:
-                    attrMin = bag->map.value.data;
-                    break;
-                case ResTable_map::ATTR_MAX:
-                    attrMax = bag->map.value.data;
-                    break;
-                case ResTable_map::ATTR_L10N:
-                    l10nReq = bag->map.value.data;
-                    break;
-                }
-                bag++;
-                cnt--;
-            }
-            unlockBag(bag);
-        } else if (accessor && accessor->getAttributeType(attrID, &attrType)) {
-            fromAccessor = true;
-            if (attrType == ResTable_map::TYPE_ENUM
-                    || attrType == ResTable_map::TYPE_FLAGS
-                    || attrType == ResTable_map::TYPE_INTEGER) {
-                accessor->getAttributeMin(attrID, &attrMin);
-                accessor->getAttributeMax(attrID, &attrMax);
-            }
-            if (localizationSetting) {
-                l10nReq = accessor->getAttributeL10N(attrID);
-            }
-        }
-    }
-
-    const bool canStringCoerce =
-        coerceType && (attrType&ResTable_map::TYPE_STRING) != 0;
-
-    if (*s == '@') {
-        outValue->dataType = outValue->TYPE_REFERENCE;
-
-        // Note: we don't check attrType here because the reference can
-        // be to any other type; we just need to count on the client making
-        // sure the referenced type is correct.
-        
-        //printf("Looking up ref: %s\n", String8(s, len).string());
-
-        // It's a reference!
-        if (len == 5 && s[1]=='n' && s[2]=='u' && s[3]=='l' && s[4]=='l') {
-            outValue->data = 0;
-            return true;
-        } else {
-            bool createIfNotFound = false;
-            const char16_t* resourceRefName;
-            int resourceNameLen;
-            if (len > 2 && s[1] == '+') {
-                createIfNotFound = true;
-                resourceRefName = s + 2;
-                resourceNameLen = len - 2;
-            } else if (len > 2 && s[1] == '*') {
-                enforcePrivate = false;
-                resourceRefName = s + 2;
-                resourceNameLen = len - 2;
-            } else {
-                createIfNotFound = false;
-                resourceRefName = s + 1;
-                resourceNameLen = len - 1;
-            }
-            String16 package, type, name;
-            if (!expandResourceRef(resourceRefName,resourceNameLen, &package, &type, &name,
-                                   defType, defPackage, &errorMsg)) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, errorMsg);
-                }
-                return false;
-            }
-
-            uint32_t specFlags = 0;
-            uint32_t rid = identifierForName(name.string(), name.size(), type.string(),
-                    type.size(), package.string(), package.size(), &specFlags);
-            if (rid != 0) {
-                if (enforcePrivate) {
-                    if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
-                        if (accessor != NULL) {
-                            accessor->reportError(accessorCookie, "Resource is not public.");
-                        }
-                        return false;
-                    }
-                }
-                if (!accessor) {
-                    outValue->data = rid;
-                    return true;
-                }
-                rid = Res_MAKEID(
-                    accessor->getRemappedPackage(Res_GETPACKAGE(rid)),
-                    Res_GETTYPE(rid), Res_GETENTRY(rid));
-                TABLE_NOISY(printf("Incl %s:%s/%s: 0x%08x\n",
-                       String8(package).string(), String8(type).string(),
-                       String8(name).string(), rid));
-                outValue->data = rid;
-                return true;
-            }
-
-            if (accessor) {
-                uint32_t rid = accessor->getCustomResourceWithCreation(package, type, name,
-                                                                       createIfNotFound);
-                if (rid != 0) {
-                    TABLE_NOISY(printf("Pckg %s:%s/%s: 0x%08x\n",
-                           String8(package).string(), String8(type).string(),
-                           String8(name).string(), rid));
-                    outValue->data = rid;
-                    return true;
-                }
-            }
-        }
-
-        if (accessor != NULL) {
-            accessor->reportError(accessorCookie, "No resource found that matches the given name");
-        }
-        return false;
-    }
-
-    // if we got to here, and localization is required and it's not a reference,
-    // complain and bail.
-    if (l10nReq == ResTable_map::L10N_SUGGESTED) {
-        if (localizationSetting) {
-            if (accessor != NULL) {
-                accessor->reportError(accessorCookie, "This attribute must be localized.");
-            }
-        }
-    }
-    
-    if (*s == '#') {
-        // It's a color!  Convert to an integer of the form 0xaarrggbb.
-        uint32_t color = 0;
-        bool error = false;
-        if (len == 4) {
-            outValue->dataType = outValue->TYPE_INT_COLOR_RGB4;
-            color |= 0xFF000000;
-            color |= get_hex(s[1], &error) << 20;
-            color |= get_hex(s[1], &error) << 16;
-            color |= get_hex(s[2], &error) << 12;
-            color |= get_hex(s[2], &error) << 8;
-            color |= get_hex(s[3], &error) << 4;
-            color |= get_hex(s[3], &error);
-        } else if (len == 5) {
-            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB4;
-            color |= get_hex(s[1], &error) << 28;
-            color |= get_hex(s[1], &error) << 24;
-            color |= get_hex(s[2], &error) << 20;
-            color |= get_hex(s[2], &error) << 16;
-            color |= get_hex(s[3], &error) << 12;
-            color |= get_hex(s[3], &error) << 8;
-            color |= get_hex(s[4], &error) << 4;
-            color |= get_hex(s[4], &error);
-        } else if (len == 7) {
-            outValue->dataType = outValue->TYPE_INT_COLOR_RGB8;
-            color |= 0xFF000000;
-            color |= get_hex(s[1], &error) << 20;
-            color |= get_hex(s[2], &error) << 16;
-            color |= get_hex(s[3], &error) << 12;
-            color |= get_hex(s[4], &error) << 8;
-            color |= get_hex(s[5], &error) << 4;
-            color |= get_hex(s[6], &error);
-        } else if (len == 9) {
-            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB8;
-            color |= get_hex(s[1], &error) << 28;
-            color |= get_hex(s[2], &error) << 24;
-            color |= get_hex(s[3], &error) << 20;
-            color |= get_hex(s[4], &error) << 16;
-            color |= get_hex(s[5], &error) << 12;
-            color |= get_hex(s[6], &error) << 8;
-            color |= get_hex(s[7], &error) << 4;
-            color |= get_hex(s[8], &error);
-        } else {
-            error = true;
-        }
-        if (!error) {
-            if ((attrType&ResTable_map::TYPE_COLOR) == 0) {
-                if (!canStringCoerce) {
-                    if (accessor != NULL) {
-                        accessor->reportError(accessorCookie,
-                                "Color types not allowed");
-                    }
-                    return false;
-                }
-            } else {
-                outValue->data = color;
-                //printf("Color input=%s, output=0x%x\n", String8(s, len).string(), color);
-                return true;
-            }
-        } else {
-            if ((attrType&ResTable_map::TYPE_COLOR) != 0) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, "Color value not valid --"
-                            " must be #rgb, #argb, #rrggbb, or #aarrggbb");
-                }
-                #if 0
-                fprintf(stderr, "%s: Color ID %s value %s is not valid\n",
-                        "Resource File", //(const char*)in->getPrintableSource(),
-                        String8(*curTag).string(),
-                        String8(s, len).string());
-                #endif
-                return false;
-            }
-        }
-    }
-
-    if (*s == '?') {
-        outValue->dataType = outValue->TYPE_ATTRIBUTE;
-
-        // Note: we don't check attrType here because the reference can
-        // be to any other type; we just need to count on the client making
-        // sure the referenced type is correct.
-
-        //printf("Looking up attr: %s\n", String8(s, len).string());
-
-        static const String16 attr16("attr");
-        String16 package, type, name;
-        if (!expandResourceRef(s+1, len-1, &package, &type, &name,
-                               &attr16, defPackage, &errorMsg)) {
-            if (accessor != NULL) {
-                accessor->reportError(accessorCookie, errorMsg);
-            }
-            return false;
-        }
-
-        //printf("Pkg: %s, Type: %s, Name: %s\n",
-        //       String8(package).string(), String8(type).string(),
-        //       String8(name).string());
-        uint32_t specFlags = 0;
-        uint32_t rid = 
-            identifierForName(name.string(), name.size(),
-                              type.string(), type.size(),
-                              package.string(), package.size(), &specFlags);
-        if (rid != 0) {
-            if (enforcePrivate) {
-                if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
-                    if (accessor != NULL) {
-                        accessor->reportError(accessorCookie, "Attribute is not public.");
-                    }
-                    return false;
-                }
-            }
-            if (!accessor) {
-                outValue->data = rid;
-                return true;
-            }
-            rid = Res_MAKEID(
-                accessor->getRemappedPackage(Res_GETPACKAGE(rid)),
-                Res_GETTYPE(rid), Res_GETENTRY(rid));
-            //printf("Incl %s:%s/%s: 0x%08x\n",
-            //       String8(package).string(), String8(type).string(),
-            //       String8(name).string(), rid);
-            outValue->data = rid;
-            return true;
-        }
-
-        if (accessor) {
-            uint32_t rid = accessor->getCustomResource(package, type, name);
-            if (rid != 0) {
-                //printf("Mine %s:%s/%s: 0x%08x\n",
-                //       String8(package).string(), String8(type).string(),
-                //       String8(name).string(), rid);
-                outValue->data = rid;
-                return true;
-            }
-        }
-
-        if (accessor != NULL) {
-            accessor->reportError(accessorCookie, "No resource found that matches the given name");
-        }
-        return false;
-    }
-
-    if (stringToInt(s, len, outValue)) {
-        if ((attrType&ResTable_map::TYPE_INTEGER) == 0) {
-            // If this type does not allow integers, but does allow floats,
-            // fall through on this error case because the float type should
-            // be able to accept any integer value.
-            if (!canStringCoerce && (attrType&ResTable_map::TYPE_FLOAT) == 0) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, "Integer types not allowed");
-                }
-                return false;
-            }
-        } else {
-            if (((int32_t)outValue->data) < ((int32_t)attrMin)
-                    || ((int32_t)outValue->data) > ((int32_t)attrMax)) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, "Integer value out of range");
-                }
-                return false;
-            }
-            return true;
-        }
-    }
-
-    if (stringToFloat(s, len, outValue)) {
-        if (outValue->dataType == Res_value::TYPE_DIMENSION) {
-            if ((attrType&ResTable_map::TYPE_DIMENSION) != 0) {
-                return true;
-            }
-            if (!canStringCoerce) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, "Dimension types not allowed");
-                }
-                return false;
-            }
-        } else if (outValue->dataType == Res_value::TYPE_FRACTION) {
-            if ((attrType&ResTable_map::TYPE_FRACTION) != 0) {
-                return true;
-            }
-            if (!canStringCoerce) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, "Fraction types not allowed");
-                }
-                return false;
-            }
-        } else if ((attrType&ResTable_map::TYPE_FLOAT) == 0) {
-            if (!canStringCoerce) {
-                if (accessor != NULL) {
-                    accessor->reportError(accessorCookie, "Float types not allowed");
-                }
-                return false;
-            }
-        } else {
-            return true;
-        }
-    }
-
-    if (len == 4) {
-        if ((s[0] == 't' || s[0] == 'T') &&
-            (s[1] == 'r' || s[1] == 'R') &&
-            (s[2] == 'u' || s[2] == 'U') &&
-            (s[3] == 'e' || s[3] == 'E')) {
-            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {
-                if (!canStringCoerce) {
-                    if (accessor != NULL) {
-                        accessor->reportError(accessorCookie, "Boolean types not allowed");
-                    }
-                    return false;
-                }
-            } else {
-                outValue->dataType = outValue->TYPE_INT_BOOLEAN;
-                outValue->data = (uint32_t)-1;
-                return true;
-            }
-        }
-    }
-
-    if (len == 5) {
-        if ((s[0] == 'f' || s[0] == 'F') &&
-            (s[1] == 'a' || s[1] == 'A') &&
-            (s[2] == 'l' || s[2] == 'L') &&
-            (s[3] == 's' || s[3] == 'S') &&
-            (s[4] == 'e' || s[4] == 'E')) {
-            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {
-                if (!canStringCoerce) {
-                    if (accessor != NULL) {
-                        accessor->reportError(accessorCookie, "Boolean types not allowed");
-                    }
-                    return false;
-                }
-            } else {
-                outValue->dataType = outValue->TYPE_INT_BOOLEAN;
-                outValue->data = 0;
-                return true;
-            }
-        }
-    }
-
-    if ((attrType&ResTable_map::TYPE_ENUM) != 0) {
-        const ssize_t p = getResourcePackageIndex(attrID);
-        const bag_entry* bag;
-        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
-        //printf("Got %d for enum\n", cnt);
-        if (cnt >= 0) {
-            resource_name rname;
-            while (cnt > 0) {
-                if (!Res_INTERNALID(bag->map.name.ident)) {
-                    //printf("Trying attr #%08x\n", bag->map.name.ident);
-                    if (getResourceName(bag->map.name.ident, &rname)) {
-                        #if 0
-                        printf("Matching %s against %s (0x%08x)\n",
-                               String8(s, len).string(),
-                               String8(rname.name, rname.nameLen).string(),
-                               bag->map.name.ident);
-                        #endif
-                        if (strzcmp16(s, len, rname.name, rname.nameLen) == 0) {
-                            outValue->dataType = bag->map.value.dataType;
-                            outValue->data = bag->map.value.data;
-                            unlockBag(bag);
-                            return true;
-                        }
-                    }
-    
-                }
-                bag++;
-                cnt--;
-            }
-            unlockBag(bag);
-        }
-
-        if (fromAccessor) {
-            if (accessor->getAttributeEnum(attrID, s, len, outValue)) {
-                return true;
-            }
-        }
-    }
-
-    if ((attrType&ResTable_map::TYPE_FLAGS) != 0) {
-        const ssize_t p = getResourcePackageIndex(attrID);
-        const bag_entry* bag;
-        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
-        //printf("Got %d for flags\n", cnt);
-        if (cnt >= 0) {
-            bool failed = false;
-            resource_name rname;
-            outValue->dataType = Res_value::TYPE_INT_HEX;
-            outValue->data = 0;
-            const char16_t* end = s + len;
-            const char16_t* pos = s;
-            while (pos < end && !failed) {
-                const char16_t* start = pos;
-                pos++;
-                while (pos < end && *pos != '|') {
-                    pos++;
-                }
-                //printf("Looking for: %s\n", String8(start, pos-start).string());
-                const bag_entry* bagi = bag;
-                ssize_t i;
-                for (i=0; i<cnt; i++, bagi++) {
-                    if (!Res_INTERNALID(bagi->map.name.ident)) {
-                        //printf("Trying attr #%08x\n", bagi->map.name.ident);
-                        if (getResourceName(bagi->map.name.ident, &rname)) {
-                            #if 0
-                            printf("Matching %s against %s (0x%08x)\n",
-                                   String8(start,pos-start).string(),
-                                   String8(rname.name, rname.nameLen).string(),
-                                   bagi->map.name.ident);
-                            #endif
-                            if (strzcmp16(start, pos-start, rname.name, rname.nameLen) == 0) {
-                                outValue->data |= bagi->map.value.data;
-                                break;
-                            }
-                        }
-                    }
-                }
-                if (i >= cnt) {
-                    // Didn't find this flag identifier.
-                    failed = true;
-                }
-                if (pos < end) {
-                    pos++;
-                }
-            }
-            unlockBag(bag);
-            if (!failed) {
-                //printf("Final flag value: 0x%lx\n", outValue->data);
-                return true;
-            }
-        }
-
-
-        if (fromAccessor) {
-            if (accessor->getAttributeFlags(attrID, s, len, outValue)) {
-                //printf("Final flag value: 0x%lx\n", outValue->data);
-                return true;
-            }
-        }
-    }
-
-    if ((attrType&ResTable_map::TYPE_STRING) == 0) {
-        if (accessor != NULL) {
-            accessor->reportError(accessorCookie, "String types not allowed");
-        }
-        return false;
-    }
-
-    // Generic string handling...
-    outValue->dataType = outValue->TYPE_STRING;
-    if (outString) {
-        bool failed = collectString(outString, s, len, preserveSpaces, &errorMsg);
-        if (accessor != NULL) {
-            accessor->reportError(accessorCookie, errorMsg);
-        }
-        return failed;
-    }
-
-    return true;
-}
-
-bool ResTable::collectString(String16* outString,
-                             const char16_t* s, size_t len,
-                             bool preserveSpaces,
-                             const char** outErrorMsg,
-                             bool append)
-{
-    String16 tmp;
-
-    char quoted = 0;
-    const char16_t* p = s;
-    while (p < (s+len)) {
-        while (p < (s+len)) {
-            const char16_t c = *p;
-            if (c == '\\') {
-                break;
-            }
-            if (!preserveSpaces) {
-                if (quoted == 0 && isspace16(c)
-                    && (c != ' ' || isspace16(*(p+1)))) {
-                    break;
-                }
-                if (c == '"' && (quoted == 0 || quoted == '"')) {
-                    break;
-                }
-                if (c == '\'' && (quoted == 0 || quoted == '\'')) {
-                    /*
-                     * In practice, when people write ' instead of \'
-                     * in a string, they are doing it by accident
-                     * instead of really meaning to use ' as a quoting
-                     * character.  Warn them so they don't lose it.
-                     */
-                    if (outErrorMsg) {
-                        *outErrorMsg = "Apostrophe not preceded by \\";
-                    }
-                    return false;
-                }
-            }
-            p++;
-        }
-        if (p < (s+len)) {
-            if (p > s) {
-                tmp.append(String16(s, p-s));
-            }
-            if (!preserveSpaces && (*p == '"' || *p == '\'')) {
-                if (quoted == 0) {
-                    quoted = *p;
-                } else {
-                    quoted = 0;
-                }
-                p++;
-            } else if (!preserveSpaces && isspace16(*p)) {
-                // Space outside of a quote -- consume all spaces and
-                // leave a single plain space char.
-                tmp.append(String16(" "));
-                p++;
-                while (p < (s+len) && isspace16(*p)) {
-                    p++;
-                }
-            } else if (*p == '\\') {
-                p++;
-                if (p < (s+len)) {
-                    switch (*p) {
-                    case 't':
-                        tmp.append(String16("\t"));
-                        break;
-                    case 'n':
-                        tmp.append(String16("\n"));
-                        break;
-                    case '#':
-                        tmp.append(String16("#"));
-                        break;
-                    case '@':
-                        tmp.append(String16("@"));
-                        break;
-                    case '?':
-                        tmp.append(String16("?"));
-                        break;
-                    case '"':
-                        tmp.append(String16("\""));
-                        break;
-                    case '\'':
-                        tmp.append(String16("'"));
-                        break;
-                    case '\\':
-                        tmp.append(String16("\\"));
-                        break;
-                    case 'u':
-                    {
-                        char16_t chr = 0;
-                        int i = 0;
-                        while (i < 4 && p[1] != 0) {
-                            p++;
-                            i++;
-                            int c;
-                            if (*p >= '0' && *p <= '9') {
-                                c = *p - '0';
-                            } else if (*p >= 'a' && *p <= 'f') {
-                                c = *p - 'a' + 10;
-                            } else if (*p >= 'A' && *p <= 'F') {
-                                c = *p - 'A' + 10;
-                            } else {
-                                if (outErrorMsg) {
-                                    *outErrorMsg = "Bad character in \\u unicode escape sequence";
-                                }
-                                return false;
-                            }
-                            chr = (chr<<4) | c;
-                        }
-                        tmp.append(String16(&chr, 1));
-                    } break;
-                    default:
-                        // ignore unknown escape chars.
-                        break;
-                    }
-                    p++;
-                }
-            }
-            len -= (p-s);
-            s = p;
-        }
-    }
-
-    if (tmp.size() != 0) {
-        if (len > 0) {
-            tmp.append(String16(s, len));
-        }
-        if (append) {
-            outString->append(tmp);
-        } else {
-            outString->setTo(tmp);
-        }
-    } else {
-        if (append) {
-            outString->append(String16(s, len));
-        } else {
-            outString->setTo(s, len);
-        }
-    }
-
-    return true;
-}
-
-size_t ResTable::getBasePackageCount() const
-{
-    if (mError != NO_ERROR) {
-        return 0;
-    }
-    return mPackageGroups.size();
-}
-
-const char16_t* ResTable::getBasePackageName(size_t idx) const
-{
-    if (mError != NO_ERROR) {
-        return 0;
-    }
-    LOG_FATAL_IF(idx >= mPackageGroups.size(),
-                 "Requested package index %d past package count %d",
-                 (int)idx, (int)mPackageGroups.size());
-    return mPackageGroups[idx]->name.string();
-}
-
-uint32_t ResTable::getBasePackageId(size_t idx) const
-{
-    if (mError != NO_ERROR) {
-        return 0;
-    }
-    LOG_FATAL_IF(idx >= mPackageGroups.size(),
-                 "Requested package index %d past package count %d",
-                 (int)idx, (int)mPackageGroups.size());
-    return mPackageGroups[idx]->id;
-}
-
-size_t ResTable::getTableCount() const
-{
-    return mHeaders.size();
-}
-
-const ResStringPool* ResTable::getTableStringBlock(size_t index) const
-{
-    return &mHeaders[index]->values;
-}
-
-void* ResTable::getTableCookie(size_t index) const
-{
-    return mHeaders[index]->cookie;
-}
-
-void ResTable::getConfigurations(Vector<ResTable_config>* configs) const
-{
-    const size_t I = mPackageGroups.size();
-    for (size_t i=0; i<I; i++) {
-        const PackageGroup* packageGroup = mPackageGroups[i];
-        const size_t J = packageGroup->packages.size();
-        for (size_t j=0; j<J; j++) {
-            const Package* package = packageGroup->packages[j];
-            const size_t K = package->types.size();
-            for (size_t k=0; k<K; k++) {
-                const Type* type = package->types[k];
-                if (type == NULL) continue;
-                const size_t L = type->configs.size();
-                for (size_t l=0; l<L; l++) {
-                    const ResTable_type* config = type->configs[l];
-                    const ResTable_config* cfg = &config->config;
-                    // only insert unique
-                    const size_t M = configs->size();
-                    size_t m;
-                    for (m=0; m<M; m++) {
-                        if (0 == (*configs)[m].compare(*cfg)) {
-                            break;
-                        }
-                    }
-                    // if we didn't find it
-                    if (m == M) {
-                        configs->add(*cfg);
-                    }
-                }
-            }
-        }
-    }
-}
-
-void ResTable::getLocales(Vector<String8>* locales) const
-{
-    Vector<ResTable_config> configs;
-    ALOGV("calling getConfigurations");
-    getConfigurations(&configs);
-    ALOGV("called getConfigurations size=%d", (int)configs.size());
-    const size_t I = configs.size();
-    for (size_t i=0; i<I; i++) {
-        char locale[6];
-        configs[i].getLocale(locale);
-        const size_t J = locales->size();
-        size_t j;
-        for (j=0; j<J; j++) {
-            if (0 == strcmp(locale, (*locales)[j].string())) {
-                break;
-            }
-        }
-        if (j == J) {
-            locales->add(String8(locale));
-        }
-    }
-}
-
-ssize_t ResTable::getEntry(
-    const Package* package, int typeIndex, int entryIndex,
-    const ResTable_config* config,
-    const ResTable_type** outType, const ResTable_entry** outEntry,
-    const Type** outTypeClass) const
-{
-    ALOGV("Getting entry from package %p\n", package);
-    const ResTable_package* const pkg = package->package;
-
-    const Type* allTypes = package->getType(typeIndex);
-    ALOGV("allTypes=%p\n", allTypes);
-    if (allTypes == NULL) {
-        ALOGV("Skipping entry type index 0x%02x because type is NULL!\n", typeIndex);
-        return 0;
-    }
-
-    if ((size_t)entryIndex >= allTypes->entryCount) {
-        ALOGW("getEntry failing because entryIndex %d is beyond type entryCount %d",
-            entryIndex, (int)allTypes->entryCount);
-        return BAD_TYPE;
-    }
-        
-    const ResTable_type* type = NULL;
-    uint32_t offset = ResTable_type::NO_ENTRY;
-    ResTable_config bestConfig;
-    memset(&bestConfig, 0, sizeof(bestConfig)); // make the compiler shut up
-    
-    const size_t NT = allTypes->configs.size();
-    for (size_t i=0; i<NT; i++) {
-        const ResTable_type* const thisType = allTypes->configs[i];
-        if (thisType == NULL) continue;
-        
-        ResTable_config thisConfig;
-        thisConfig.copyFromDtoH(thisType->config);
-
-        TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): %s\n",
-                           entryIndex, typeIndex+1, dtohl(thisType->config.size),
-                           thisConfig.toString().string()));
-        
-        // Check to make sure this one is valid for the current parameters.
-        if (config && !thisConfig.match(*config)) {
-            TABLE_GETENTRY(LOGI("Does not match config!\n"));
-            continue;
-        }
-        
-        // Check if there is the desired entry in this type.
-        
-        const uint8_t* const end = ((const uint8_t*)thisType)
-            + dtohl(thisType->header.size);
-        const uint32_t* const eindex = (const uint32_t*)
-            (((const uint8_t*)thisType) + dtohs(thisType->header.headerSize));
-        
-        uint32_t thisOffset = dtohl(eindex[entryIndex]);
-        if (thisOffset == ResTable_type::NO_ENTRY) {
-            TABLE_GETENTRY(LOGI("Skipping because it is not defined!\n"));
-            continue;
-        }
-        
-        if (type != NULL) {
-            // Check if this one is less specific than the last found.  If so,
-            // we will skip it.  We check starting with things we most care
-            // about to those we least care about.
-            if (!thisConfig.isBetterThan(bestConfig, config)) {
-                TABLE_GETENTRY(LOGI("This config is worse than last!\n"));
-                continue;
-            }
-        }
-        
-        type = thisType;
-        offset = thisOffset;
-        bestConfig = thisConfig;
-        TABLE_GETENTRY(LOGI("Best entry so far -- using it!\n"));
-        if (!config) break;
-    }
-    
-    if (type == NULL) {
-        TABLE_GETENTRY(LOGI("No value found for requested entry!\n"));
-        return BAD_INDEX;
-    }
-    
-    offset += dtohl(type->entriesStart);
-    TABLE_NOISY(aout << "Looking in resource table " << package->header->header
-          << ", typeOff="
-          << (void*)(((const char*)type)-((const char*)package->header->header))
-          << ", offset=" << (void*)offset << endl);
-
-    if (offset > (dtohl(type->header.size)-sizeof(ResTable_entry))) {
-        ALOGW("ResTable_entry at 0x%x is beyond type chunk data 0x%x",
-             offset, dtohl(type->header.size));
-        return BAD_TYPE;
-    }
-    if ((offset&0x3) != 0) {
-        ALOGW("ResTable_entry at 0x%x is not on an integer boundary",
-             offset);
-        return BAD_TYPE;
-    }
-
-    const ResTable_entry* const entry = (const ResTable_entry*)
-        (((const uint8_t*)type) + offset);
-    if (dtohs(entry->size) < sizeof(*entry)) {
-        ALOGW("ResTable_entry size 0x%x is too small", dtohs(entry->size));
-        return BAD_TYPE;
-    }
-
-    *outType = type;
-    *outEntry = entry;
-    if (outTypeClass != NULL) {
-        *outTypeClass = allTypes;
-    }
-    return offset + dtohs(entry->size);
-}
-
-status_t ResTable::parsePackage(const ResTable_package* const pkg,
-                                const Header* const header, uint32_t idmap_id)
-{
-    const uint8_t* base = (const uint8_t*)pkg;
-    status_t err = validate_chunk(&pkg->header, sizeof(*pkg),
-                                  header->dataEnd, "ResTable_package");
-    if (err != NO_ERROR) {
-        return (mError=err);
-    }
-
-    const size_t pkgSize = dtohl(pkg->header.size);
-
-    if (dtohl(pkg->typeStrings) >= pkgSize) {
-        ALOGW("ResTable_package type strings at %p are past chunk size %p.",
-             (void*)dtohl(pkg->typeStrings), (void*)pkgSize);
-        return (mError=BAD_TYPE);
-    }
-    if ((dtohl(pkg->typeStrings)&0x3) != 0) {
-        ALOGW("ResTable_package type strings at %p is not on an integer boundary.",
-             (void*)dtohl(pkg->typeStrings));
-        return (mError=BAD_TYPE);
-    }
-    if (dtohl(pkg->keyStrings) >= pkgSize) {
-        ALOGW("ResTable_package key strings at %p are past chunk size %p.",
-             (void*)dtohl(pkg->keyStrings), (void*)pkgSize);
-        return (mError=BAD_TYPE);
-    }
-    if ((dtohl(pkg->keyStrings)&0x3) != 0) {
-        ALOGW("ResTable_package key strings at %p is not on an integer boundary.",
-             (void*)dtohl(pkg->keyStrings));
-        return (mError=BAD_TYPE);
-    }
-    
-    Package* package = NULL;
-    PackageGroup* group = NULL;
-    uint32_t id = idmap_id != 0 ? idmap_id : dtohl(pkg->id);
-    // If at this point id == 0, pkg is an overlay package without a
-    // corresponding idmap. During regular usage, overlay packages are
-    // always loaded alongside their idmaps, but during idmap creation
-    // the package is temporarily loaded by itself.
-    if (id < 256) {
-    
-        package = new Package(this, header, pkg);
-        if (package == NULL) {
-            return (mError=NO_MEMORY);
-        }
-        
-        size_t idx = mPackageMap[id];
-        if (idx == 0) {
-            idx = mPackageGroups.size()+1;
-
-            char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)];
-            strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t));
-            group = new PackageGroup(this, String16(tmpName), id);
-            if (group == NULL) {
-                delete package;
-                return (mError=NO_MEMORY);
-            }
-
-            err = package->typeStrings.setTo(base+dtohl(pkg->typeStrings),
-                                           header->dataEnd-(base+dtohl(pkg->typeStrings)));
-            if (err != NO_ERROR) {
-                delete group;
-                delete package;
-                return (mError=err);
-            }
-            err = package->keyStrings.setTo(base+dtohl(pkg->keyStrings),
-                                          header->dataEnd-(base+dtohl(pkg->keyStrings)));
-            if (err != NO_ERROR) {
-                delete group;
-                delete package;
-                return (mError=err);
-            }
-
-            //printf("Adding new package id %d at index %d\n", id, idx);
-            err = mPackageGroups.add(group);
-            if (err < NO_ERROR) {
-                return (mError=err);
-            }
-            group->basePackage = package;
-            
-            mPackageMap[id] = (uint8_t)idx;
-        } else {
-            group = mPackageGroups.itemAt(idx-1);
-            if (group == NULL) {
-                return (mError=UNKNOWN_ERROR);
-            }
-        }
-        err = group->packages.add(package);
-        if (err < NO_ERROR) {
-            return (mError=err);
-        }
-    } else {
-        LOG_ALWAYS_FATAL("Package id out of range");
-        return NO_ERROR;
-    }
-
-    
-    // Iterate through all chunks.
-    size_t curPackage = 0;
-    
-    const ResChunk_header* chunk =
-        (const ResChunk_header*)(((const uint8_t*)pkg)
-                                 + dtohs(pkg->header.headerSize));
-    const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size);
-    while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) &&
-           ((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) {
-        TABLE_NOISY(LOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
-                         dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
-                         (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
-        const size_t csize = dtohl(chunk->size);
-        const uint16_t ctype = dtohs(chunk->type);
-        if (ctype == RES_TABLE_TYPE_SPEC_TYPE) {
-            const ResTable_typeSpec* typeSpec = (const ResTable_typeSpec*)(chunk);
-            err = validate_chunk(&typeSpec->header, sizeof(*typeSpec),
-                                 endPos, "ResTable_typeSpec");
-            if (err != NO_ERROR) {
-                return (mError=err);
-            }
-            
-            const size_t typeSpecSize = dtohl(typeSpec->header.size);
-            
-            LOAD_TABLE_NOISY(printf("TypeSpec off %p: type=0x%x, headerSize=0x%x, size=%p\n",
-                                    (void*)(base-(const uint8_t*)chunk),
-                                    dtohs(typeSpec->header.type),
-                                    dtohs(typeSpec->header.headerSize),
-                                    (void*)typeSize));
-            // look for block overrun or int overflow when multiplying by 4
-            if ((dtohl(typeSpec->entryCount) > (INT32_MAX/sizeof(uint32_t))
-                    || dtohs(typeSpec->header.headerSize)+(sizeof(uint32_t)*dtohl(typeSpec->entryCount))
-                    > typeSpecSize)) {
-                ALOGW("ResTable_typeSpec entry index to %p extends beyond chunk end %p.",
-                     (void*)(dtohs(typeSpec->header.headerSize)
-                             +(sizeof(uint32_t)*dtohl(typeSpec->entryCount))),
-                     (void*)typeSpecSize);
-                return (mError=BAD_TYPE);
-            }
-            
-            if (typeSpec->id == 0) {
-                ALOGW("ResTable_type has an id of 0.");
-                return (mError=BAD_TYPE);
-            }
-            
-            while (package->types.size() < typeSpec->id) {
-                package->types.add(NULL);
-            }
-            Type* t = package->types[typeSpec->id-1];
-            if (t == NULL) {
-                t = new Type(header, package, dtohl(typeSpec->entryCount));
-                package->types.editItemAt(typeSpec->id-1) = t;
-            } else if (dtohl(typeSpec->entryCount) != t->entryCount) {
-                ALOGW("ResTable_typeSpec entry count inconsistent: given %d, previously %d",
-                    (int)dtohl(typeSpec->entryCount), (int)t->entryCount);
-                return (mError=BAD_TYPE);
-            }
-            t->typeSpecFlags = (const uint32_t*)(
-                    ((const uint8_t*)typeSpec) + dtohs(typeSpec->header.headerSize));
-            t->typeSpec = typeSpec;
-            
-        } else if (ctype == RES_TABLE_TYPE_TYPE) {
-            const ResTable_type* type = (const ResTable_type*)(chunk);
-            err = validate_chunk(&type->header, sizeof(*type)-sizeof(ResTable_config)+4,
-                                 endPos, "ResTable_type");
-            if (err != NO_ERROR) {
-                return (mError=err);
-            }
-            
-            const size_t typeSize = dtohl(type->header.size);
-            
-            LOAD_TABLE_NOISY(printf("Type off %p: type=0x%x, headerSize=0x%x, size=%p\n",
-                                    (void*)(base-(const uint8_t*)chunk),
-                                    dtohs(type->header.type),
-                                    dtohs(type->header.headerSize),
-                                    (void*)typeSize));
-            if (dtohs(type->header.headerSize)+(sizeof(uint32_t)*dtohl(type->entryCount))
-                > typeSize) {
-                ALOGW("ResTable_type entry index to %p extends beyond chunk end %p.",
-                     (void*)(dtohs(type->header.headerSize)
-                             +(sizeof(uint32_t)*dtohl(type->entryCount))),
-                     (void*)typeSize);
-                return (mError=BAD_TYPE);
-            }
-            if (dtohl(type->entryCount) != 0
-                && dtohl(type->entriesStart) > (typeSize-sizeof(ResTable_entry))) {
-                ALOGW("ResTable_type entriesStart at %p extends beyond chunk end %p.",
-                     (void*)dtohl(type->entriesStart), (void*)typeSize);
-                return (mError=BAD_TYPE);
-            }
-            if (type->id == 0) {
-                ALOGW("ResTable_type has an id of 0.");
-                return (mError=BAD_TYPE);
-            }
-            
-            while (package->types.size() < type->id) {
-                package->types.add(NULL);
-            }
-            Type* t = package->types[type->id-1];
-            if (t == NULL) {
-                t = new Type(header, package, dtohl(type->entryCount));
-                package->types.editItemAt(type->id-1) = t;
-            } else if (dtohl(type->entryCount) != t->entryCount) {
-                ALOGW("ResTable_type entry count inconsistent: given %d, previously %d",
-                    (int)dtohl(type->entryCount), (int)t->entryCount);
-                return (mError=BAD_TYPE);
-            }
-            
-            TABLE_GETENTRY(
-                ResTable_config thisConfig;
-                thisConfig.copyFromDtoH(type->config);
-                ALOGI("Adding config to type %d: %s\n",
-                      type->id, thisConfig.toString().string()));
-            t->configs.add(type);
-        } else {
-            status_t err = validate_chunk(chunk, sizeof(ResChunk_header),
-                                          endPos, "ResTable_package:unknown");
-            if (err != NO_ERROR) {
-                return (mError=err);
-            }
-        }
-        chunk = (const ResChunk_header*)
-            (((const uint8_t*)chunk) + csize);
-    }
-
-    if (group->typeCount == 0) {
-        group->typeCount = package->types.size();
-    }
-    
-    return NO_ERROR;
-}
-
-status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, uint32_t overlayCrc,
-                               void** outData, size_t* outSize) const
-{
-    // see README for details on the format of map
-    if (mPackageGroups.size() == 0) {
-        return UNKNOWN_ERROR;
-    }
-    if (mPackageGroups[0]->packages.size() == 0) {
-        return UNKNOWN_ERROR;
-    }
-
-    Vector<Vector<uint32_t> > map;
-    const PackageGroup* pg = mPackageGroups[0];
-    const Package* pkg = pg->packages[0];
-    size_t typeCount = pkg->types.size();
-    // starting size is header + first item (number of types in map)
-    *outSize = (IDMAP_HEADER_SIZE + 1) * sizeof(uint32_t);
-    const String16 overlayPackage(overlay.mPackageGroups[0]->packages[0]->package->name);
-    const uint32_t pkg_id = pkg->package->id << 24;
-
-    for (size_t typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
-        ssize_t offset = -1;
-        const Type* typeConfigs = pkg->getType(typeIndex);
-        ssize_t mapIndex = map.add();
-        if (mapIndex < 0) {
-            return NO_MEMORY;
-        }
-        Vector<uint32_t>& vector = map.editItemAt(mapIndex);
-        for (size_t entryIndex = 0; entryIndex < typeConfigs->entryCount; ++entryIndex) {
-            uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
-                | (0x00ff0000 & ((typeIndex+1)<<16))
-                | (0x0000ffff & (entryIndex));
-            resource_name resName;
-            if (!this->getResourceName(resID, &resName)) {
-                ALOGW("idmap: resource 0x%08x has spec but lacks values, skipping\n", resID);
-                continue;
-            }
-
-            const String16 overlayType(resName.type, resName.typeLen);
-            const String16 overlayName(resName.name, resName.nameLen);
-            uint32_t overlayResID = overlay.identifierForName(overlayName.string(),
-                                                              overlayName.size(),
-                                                              overlayType.string(),
-                                                              overlayType.size(),
-                                                              overlayPackage.string(),
-                                                              overlayPackage.size());
-            if (overlayResID != 0) {
-                // overlay package has package ID == 0, use original package's ID instead
-                overlayResID |= pkg_id;
-            }
-            vector.push(overlayResID);
-            if (overlayResID != 0 && offset == -1) {
-                offset = Res_GETENTRY(resID);
-            }
-#if 0
-            if (overlayResID != 0) {
-                ALOGD("%s/%s 0x%08x -> 0x%08x\n",
-                     String8(String16(resName.type)).string(),
-                     String8(String16(resName.name)).string(),
-                     resID, overlayResID);
-            }
-#endif
-        }
-
-        if (offset != -1) {
-            // shave off leading and trailing entries which lack overlay values
-            vector.removeItemsAt(0, offset);
-            vector.insertAt((uint32_t)offset, 0, 1);
-            while (vector.top() == 0) {
-                vector.pop();
-            }
-            // reserve space for number and offset of entries, and the actual entries
-            *outSize += (2 + vector.size()) * sizeof(uint32_t);
-        } else {
-            // no entries of current type defined in overlay package
-            vector.clear();
-            // reserve space for type offset
-            *outSize += 1 * sizeof(uint32_t);
-        }
-    }
-
-    if ((*outData = malloc(*outSize)) == NULL) {
-        return NO_MEMORY;
-    }
-    uint32_t* data = (uint32_t*)*outData;
-    *data++ = htodl(IDMAP_MAGIC);
-    *data++ = htodl(originalCrc);
-    *data++ = htodl(overlayCrc);
-    const size_t mapSize = map.size();
-    *data++ = htodl(mapSize);
-    size_t offset = mapSize;
-    for (size_t i = 0; i < mapSize; ++i) {
-        const Vector<uint32_t>& vector = map.itemAt(i);
-        const size_t N = vector.size();
-        if (N == 0) {
-            *data++ = htodl(0);
-        } else {
-            offset++;
-            *data++ = htodl(offset);
-            offset += N;
-        }
-    }
-    for (size_t i = 0; i < mapSize; ++i) {
-        const Vector<uint32_t>& vector = map.itemAt(i);
-        const size_t N = vector.size();
-        if (N == 0) {
-            continue;
-        }
-        *data++ = htodl(N - 1); // do not count the offset (which is vector's first element)
-        for (size_t j = 0; j < N; ++j) {
-            const uint32_t& overlayResID = vector.itemAt(j);
-            *data++ = htodl(overlayResID);
-        }
-    }
-
-    return NO_ERROR;
-}
-
-bool ResTable::getIdmapInfo(const void* idmap, size_t sizeBytes,
-                            uint32_t* pOriginalCrc, uint32_t* pOverlayCrc)
-{
-    const uint32_t* map = (const uint32_t*)idmap;
-    if (!assertIdmapHeader(map, sizeBytes)) {
-        return false;
-    }
-    *pOriginalCrc = map[1];
-    *pOverlayCrc = map[2];
-    return true;
-}
-
-
-#ifndef HAVE_ANDROID_OS
-#define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string())
-
-#define CHAR16_ARRAY_EQ(constant, var, len) \
-        ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len))))
-
-void print_complex(uint32_t complex, bool isFraction)
-{
-    const float MANTISSA_MULT =
-        1.0f / (1<<Res_value::COMPLEX_MANTISSA_SHIFT);
-    const float RADIX_MULTS[] = {
-        1.0f*MANTISSA_MULT, 1.0f/(1<<7)*MANTISSA_MULT,
-        1.0f/(1<<15)*MANTISSA_MULT, 1.0f/(1<<23)*MANTISSA_MULT
-    };
-
-    float value = (complex&(Res_value::COMPLEX_MANTISSA_MASK
-                   <<Res_value::COMPLEX_MANTISSA_SHIFT))
-            * RADIX_MULTS[(complex>>Res_value::COMPLEX_RADIX_SHIFT)
-                            & Res_value::COMPLEX_RADIX_MASK];
-    printf("%f", value);
-    
-    if (!isFraction) {
-        switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) {
-            case Res_value::COMPLEX_UNIT_PX: printf("px"); break;
-            case Res_value::COMPLEX_UNIT_DIP: printf("dp"); break;
-            case Res_value::COMPLEX_UNIT_SP: printf("sp"); break;
-            case Res_value::COMPLEX_UNIT_PT: printf("pt"); break;
-            case Res_value::COMPLEX_UNIT_IN: printf("in"); break;
-            case Res_value::COMPLEX_UNIT_MM: printf("mm"); break;
-            default: printf(" (unknown unit)"); break;
-        }
-    } else {
-        switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) {
-            case Res_value::COMPLEX_UNIT_FRACTION: printf("%%"); break;
-            case Res_value::COMPLEX_UNIT_FRACTION_PARENT: printf("%%p"); break;
-            default: printf(" (unknown unit)"); break;
-        }
-    }
-}
-
-// Normalize a string for output
-String8 ResTable::normalizeForOutput( const char *input )
-{
-    String8 ret;
-    char buff[2];
-    buff[1] = '\0';
-
-    while (*input != '\0') {
-        switch (*input) {
-            // All interesting characters are in the ASCII zone, so we are making our own lives
-            // easier by scanning the string one byte at a time.
-        case '\\':
-            ret += "\\\\";
-            break;
-        case '\n':
-            ret += "\\n";
-            break;
-        case '"':
-            ret += "\\\"";
-            break;
-        default:
-            buff[0] = *input;
-            ret += buff;
-            break;
-        }
-
-        input++;
-    }
-
-    return ret;
-}
-
-void ResTable::print_value(const Package* pkg, const Res_value& value) const
-{
-    if (value.dataType == Res_value::TYPE_NULL) {
-        printf("(null)\n");
-    } else if (value.dataType == Res_value::TYPE_REFERENCE) {
-        printf("(reference) 0x%08x\n", value.data);
-    } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) {
-        printf("(attribute) 0x%08x\n", value.data);
-    } else if (value.dataType == Res_value::TYPE_STRING) {
-        size_t len;
-        const char* str8 = pkg->header->values.string8At(
-                value.data, &len);
-        if (str8 != NULL) {
-            printf("(string8) \"%s\"\n", normalizeForOutput(str8).string());
-        } else {
-            const char16_t* str16 = pkg->header->values.stringAt(
-                    value.data, &len);
-            if (str16 != NULL) {
-                printf("(string16) \"%s\"\n",
-                    normalizeForOutput(String8(str16, len).string()).string());
-            } else {
-                printf("(string) null\n");
-            }
-        } 
-    } else if (value.dataType == Res_value::TYPE_FLOAT) {
-        printf("(float) %g\n", *(const float*)&value.data);
-    } else if (value.dataType == Res_value::TYPE_DIMENSION) {
-        printf("(dimension) ");
-        print_complex(value.data, false);
-        printf("\n");
-    } else if (value.dataType == Res_value::TYPE_FRACTION) {
-        printf("(fraction) ");
-        print_complex(value.data, true);
-        printf("\n");
-    } else if (value.dataType >= Res_value::TYPE_FIRST_COLOR_INT
-            || value.dataType <= Res_value::TYPE_LAST_COLOR_INT) {
-        printf("(color) #%08x\n", value.data);
-    } else if (value.dataType == Res_value::TYPE_INT_BOOLEAN) {
-        printf("(boolean) %s\n", value.data ? "true" : "false");
-    } else if (value.dataType >= Res_value::TYPE_FIRST_INT
-            || value.dataType <= Res_value::TYPE_LAST_INT) {
-        printf("(int) 0x%08x or %d\n", value.data, value.data);
-    } else {
-        printf("(unknown type) t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)\n",
-               (int)value.dataType, (int)value.data,
-               (int)value.size, (int)value.res0);
-    }
-}
-
-void ResTable::print(bool inclValues) const
-{
-    if (mError != 0) {
-        printf("mError=0x%x (%s)\n", mError, strerror(mError));
-    }
-#if 0
-    printf("mParams=%c%c-%c%c,\n",
-            mParams.language[0], mParams.language[1],
-            mParams.country[0], mParams.country[1]);
-#endif
-    size_t pgCount = mPackageGroups.size();
-    printf("Package Groups (%d)\n", (int)pgCount);
-    for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) {
-        const PackageGroup* pg = mPackageGroups[pgIndex];
-        printf("Package Group %d id=%d packageCount=%d name=%s\n",
-                (int)pgIndex, pg->id, (int)pg->packages.size(),
-                String8(pg->name).string());
-        
-        size_t pkgCount = pg->packages.size();
-        for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) {
-            const Package* pkg = pg->packages[pkgIndex];
-            size_t typeCount = pkg->types.size();
-            printf("  Package %d id=%d name=%s typeCount=%d\n", (int)pkgIndex,
-                    pkg->package->id, String8(String16(pkg->package->name)).string(),
-                    (int)typeCount);
-            for (size_t typeIndex=0; typeIndex<typeCount; typeIndex++) {
-                const Type* typeConfigs = pkg->getType(typeIndex);
-                if (typeConfigs == NULL) {
-                    printf("    type %d NULL\n", (int)typeIndex);
-                    continue;
-                }
-                const size_t NTC = typeConfigs->configs.size();
-                printf("    type %d configCount=%d entryCount=%d\n",
-                       (int)typeIndex, (int)NTC, (int)typeConfigs->entryCount);
-                if (typeConfigs->typeSpecFlags != NULL) {
-                    for (size_t entryIndex=0; entryIndex<typeConfigs->entryCount; entryIndex++) {
-                        uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
-                                    | (0x00ff0000 & ((typeIndex+1)<<16))
-                                    | (0x0000ffff & (entryIndex));
-                        resource_name resName;
-                        if (this->getResourceName(resID, &resName)) {
-                            printf("      spec resource 0x%08x %s:%s/%s: flags=0x%08x\n",
-                                resID,
-                                CHAR16_TO_CSTR(resName.package, resName.packageLen),
-                                CHAR16_TO_CSTR(resName.type, resName.typeLen),
-                                CHAR16_TO_CSTR(resName.name, resName.nameLen),
-                                dtohl(typeConfigs->typeSpecFlags[entryIndex]));
-                        } else {
-                            printf("      INVALID TYPE CONFIG FOR RESOURCE 0x%08x\n", resID);
-                        }
-                    }
-                }
-                for (size_t configIndex=0; configIndex<NTC; configIndex++) {
-                    const ResTable_type* type = typeConfigs->configs[configIndex];
-                    if ((((uint64_t)type)&0x3) != 0) {
-                        printf("      NON-INTEGER ResTable_type ADDRESS: %p\n", type);
-                        continue;
-                    }
-                    String8 configStr = type->config.toString();
-                    printf("      config %s:\n", configStr.size() > 0
-                            ? configStr.string() : "(default)");
-                    size_t entryCount = dtohl(type->entryCount);
-                    uint32_t entriesStart = dtohl(type->entriesStart);
-                    if ((entriesStart&0x3) != 0) {
-                        printf("      NON-INTEGER ResTable_type entriesStart OFFSET: %p\n", (void*)entriesStart);
-                        continue;
-                    }
-                    uint32_t typeSize = dtohl(type->header.size);
-                    if ((typeSize&0x3) != 0) {
-                        printf("      NON-INTEGER ResTable_type header.size: %p\n", (void*)typeSize);
-                        continue;
-                    }
-                    for (size_t entryIndex=0; entryIndex<entryCount; entryIndex++) {
-                        
-                        const uint8_t* const end = ((const uint8_t*)type)
-                            + dtohl(type->header.size);
-                        const uint32_t* const eindex = (const uint32_t*)
-                            (((const uint8_t*)type) + dtohs(type->header.headerSize));
-                        
-                        uint32_t thisOffset = dtohl(eindex[entryIndex]);
-                        if (thisOffset == ResTable_type::NO_ENTRY) {
-                            continue;
-                        }
-                        
-                        uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
-                                    | (0x00ff0000 & ((typeIndex+1)<<16))
-                                    | (0x0000ffff & (entryIndex));
-                        resource_name resName;
-                        if (this->getResourceName(resID, &resName)) {
-                            printf("        resource 0x%08x %s:%s/%s: ", resID,
-                                    CHAR16_TO_CSTR(resName.package, resName.packageLen),
-                                    CHAR16_TO_CSTR(resName.type, resName.typeLen),
-                                    CHAR16_TO_CSTR(resName.name, resName.nameLen));
-                        } else {
-                            printf("        INVALID RESOURCE 0x%08x: ", resID);
-                        }
-                        if ((thisOffset&0x3) != 0) {
-                            printf("NON-INTEGER OFFSET: %p\n", (void*)thisOffset);
-                            continue;
-                        }
-                        if ((thisOffset+sizeof(ResTable_entry)) > typeSize) {
-                            printf("OFFSET OUT OF BOUNDS: %p+%p (size is %p)\n",
-                                   (void*)entriesStart, (void*)thisOffset,
-                                   (void*)typeSize);
-                            continue;
-                        }
-                        
-                        const ResTable_entry* ent = (const ResTable_entry*)
-                            (((const uint8_t*)type) + entriesStart + thisOffset);
-                        if (((entriesStart + thisOffset)&0x3) != 0) {
-                            printf("NON-INTEGER ResTable_entry OFFSET: %p\n",
-                                 (void*)(entriesStart + thisOffset));
-                            continue;
-                        }
-                        
-                        uint16_t esize = dtohs(ent->size);
-                        if ((esize&0x3) != 0) {
-                            printf("NON-INTEGER ResTable_entry SIZE: %p\n", (void*)esize);
-                            continue;
-                        }
-                        if ((thisOffset+esize) > typeSize) {
-                            printf("ResTable_entry OUT OF BOUNDS: %p+%p+%p (size is %p)\n",
-                                   (void*)entriesStart, (void*)thisOffset,
-                                   (void*)esize, (void*)typeSize);
-                            continue;
-                        }
-                            
-                        const Res_value* valuePtr = NULL;
-                        const ResTable_map_entry* bagPtr = NULL;
-                        Res_value value;
-                        if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) {
-                            printf("<bag>");
-                            bagPtr = (const ResTable_map_entry*)ent;
-                        } else {
-                            valuePtr = (const Res_value*)
-                                (((const uint8_t*)ent) + esize);
-                            value.copyFrom_dtoh(*valuePtr);
-                            printf("t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)",
-                                   (int)value.dataType, (int)value.data,
-                                   (int)value.size, (int)value.res0);
-                        }
-                        
-                        if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) {
-                            printf(" (PUBLIC)");
-                        }
-                        printf("\n");
-                        
-                        if (inclValues) {
-                            if (valuePtr != NULL) {
-                                printf("          ");
-                                print_value(pkg, value);
-                            } else if (bagPtr != NULL) {
-                                const int N = dtohl(bagPtr->count);
-                                const uint8_t* baseMapPtr = (const uint8_t*)ent;
-                                size_t mapOffset = esize;
-                                const ResTable_map* mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);
-                                printf("          Parent=0x%08x, Count=%d\n",
-                                    dtohl(bagPtr->parent.ident), N);
-                                for (int i=0; i<N && mapOffset < (typeSize-sizeof(ResTable_map)); i++) {
-                                    printf("          #%i (Key=0x%08x): ",
-                                        i, dtohl(mapPtr->name.ident));
-                                    value.copyFrom_dtoh(mapPtr->value);
-                                    print_value(pkg, value);
-                                    const size_t size = dtohs(mapPtr->value.size);
-                                    mapOffset += size + sizeof(*mapPtr)-sizeof(mapPtr->value);
-                                    mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-#endif // HAVE_ANDROID_OS
-
-}   // namespace android
diff --git a/libs/utils/StreamingZipInflater.cpp b/libs/utils/StreamingZipInflater.cpp
deleted file mode 100644
index d3fb98d..0000000
--- a/libs/utils/StreamingZipInflater.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2010 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 "szipinf"
-#include <utils/Log.h>
-
-#include <androidfw/StreamingZipInflater.h>
-#include <utils/FileMap.h>
-#include <string.h>
-#include <stddef.h>
-#include <assert.h>
-
-static inline size_t min_of(size_t a, size_t b) { return (a < b) ? a : b; }
-
-using namespace android;
-
-/*
- * Streaming access to compressed asset data in an open fd
- */
-StreamingZipInflater::StreamingZipInflater(int fd, off64_t compDataStart,
-        size_t uncompSize, size_t compSize) {
-    mFd = fd;
-    mDataMap = NULL;
-    mInFileStart = compDataStart;
-    mOutTotalSize = uncompSize;
-    mInTotalSize = compSize;
-
-    mInBufSize = StreamingZipInflater::INPUT_CHUNK_SIZE;
-    mInBuf = new uint8_t[mInBufSize];
-
-    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;
-    mOutBuf = new uint8_t[mOutBufSize];
-
-    initInflateState();
-}
-
-/*
- * Streaming access to compressed data held in an mmapped region of memory
- */
-StreamingZipInflater::StreamingZipInflater(FileMap* dataMap, size_t uncompSize) {
-    mFd = -1;
-    mDataMap = dataMap;
-    mOutTotalSize = uncompSize;
-    mInTotalSize = dataMap->getDataLength();
-
-    mInBuf = (uint8_t*) dataMap->getDataPtr();
-    mInBufSize = mInTotalSize;
-
-    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;
-    mOutBuf = new uint8_t[mOutBufSize];
-
-    initInflateState();
-}
-
-StreamingZipInflater::~StreamingZipInflater() {
-    // tear down the in-flight zip state just in case
-    ::inflateEnd(&mInflateState);
-
-    if (mDataMap == NULL) {
-        delete [] mInBuf;
-    }
-    delete [] mOutBuf;
-}
-
-void StreamingZipInflater::initInflateState() {
-    ALOGV("Initializing inflate state");
-
-    memset(&mInflateState, 0, sizeof(mInflateState));
-    mInflateState.zalloc = Z_NULL;
-    mInflateState.zfree = Z_NULL;
-    mInflateState.opaque = Z_NULL;
-    mInflateState.next_in = (Bytef*)mInBuf;
-    mInflateState.next_out = (Bytef*) mOutBuf;
-    mInflateState.avail_out = mOutBufSize;
-    mInflateState.data_type = Z_UNKNOWN;
-
-    mOutLastDecoded = mOutDeliverable = mOutCurPosition = 0;
-    mInNextChunkOffset = 0;
-    mStreamNeedsInit = true;
-
-    if (mDataMap == NULL) {
-        ::lseek(mFd, mInFileStart, SEEK_SET);
-        mInflateState.avail_in = 0; // set when a chunk is read in
-    } else {
-        mInflateState.avail_in = mInBufSize;
-    }
-}
-
-/*
- * Basic approach:
- *
- * 1. If we have undelivered uncompressed data, send it.  At this point
- *    either we've satisfied the request, or we've exhausted the available
- *    output data in mOutBuf.
- *
- * 2. While we haven't sent enough data to satisfy the request:
- *    0. if the request is for more data than exists, bail.
- *    a. if there is no input data to decode, read some into the input buffer
- *       and readjust the z_stream input pointers
- *    b. point the output to the start of the output buffer and decode what we can
- *    c. deliver whatever output data we can
- */
-ssize_t StreamingZipInflater::read(void* outBuf, size_t count) {
-    uint8_t* dest = (uint8_t*) outBuf;
-    size_t bytesRead = 0;
-    size_t toRead = min_of(count, size_t(mOutTotalSize - mOutCurPosition));
-    while (toRead > 0) {
-        // First, write from whatever we already have decoded and ready to go
-        size_t deliverable = min_of(toRead, mOutLastDecoded - mOutDeliverable);
-        if (deliverable > 0) {
-            if (outBuf != NULL) memcpy(dest, mOutBuf + mOutDeliverable, deliverable);
-            mOutDeliverable += deliverable;
-            mOutCurPosition += deliverable;
-            dest += deliverable;
-            bytesRead += deliverable;
-            toRead -= deliverable;
-        }
-
-        // need more data?  time to decode some.
-        if (toRead > 0) {
-            // if we don't have any data to decode, read some in.  If we're working
-            // from mmapped data this won't happen, because the clipping to total size
-            // will prevent reading off the end of the mapped input chunk.
-            if (mInflateState.avail_in == 0) {
-                int err = readNextChunk();
-                if (err < 0) {
-                    ALOGE("Unable to access asset data: %d", err);
-                    if (!mStreamNeedsInit) {
-                        ::inflateEnd(&mInflateState);
-                        initInflateState();
-                    }
-                    return -1;
-                }
-            }
-            // we know we've drained whatever is in the out buffer now, so just
-            // start from scratch there, reading all the input we have at present.
-            mInflateState.next_out = (Bytef*) mOutBuf;
-            mInflateState.avail_out = mOutBufSize;
-
-            /*
-            ALOGV("Inflating to outbuf: avail_in=%u avail_out=%u next_in=%p next_out=%p",
-                    mInflateState.avail_in, mInflateState.avail_out,
-                    mInflateState.next_in, mInflateState.next_out);
-            */
-            int result = Z_OK;
-            if (mStreamNeedsInit) {
-                ALOGV("Initializing zlib to inflate");
-                result = inflateInit2(&mInflateState, -MAX_WBITS);
-                mStreamNeedsInit = false;
-            }
-            if (result == Z_OK) result = ::inflate(&mInflateState, Z_SYNC_FLUSH);
-            if (result < 0) {
-                // Whoops, inflation failed
-                ALOGE("Error inflating asset: %d", result);
-                ::inflateEnd(&mInflateState);
-                initInflateState();
-                return -1;
-            } else {
-                if (result == Z_STREAM_END) {
-                    // we know we have to have reached the target size here and will
-                    // not try to read any further, so just wind things up.
-                    ::inflateEnd(&mInflateState);
-                }
-
-                // Note how much data we got, and off we go
-                mOutDeliverable = 0;
-                mOutLastDecoded = mOutBufSize - mInflateState.avail_out;
-            }
-        }
-    }
-    return bytesRead;
-}
-
-int StreamingZipInflater::readNextChunk() {
-    assert(mDataMap == NULL);
-
-    if (mInNextChunkOffset < mInTotalSize) {
-        size_t toRead = min_of(mInBufSize, mInTotalSize - mInNextChunkOffset);
-        if (toRead > 0) {
-            ssize_t didRead = ::read(mFd, mInBuf, toRead);
-            //ALOGV("Reading input chunk, size %08x didread %08x", toRead, didRead);
-            if (didRead < 0) {
-                // TODO: error
-                ALOGE("Error reading asset data");
-                return didRead;
-            } else {
-                mInNextChunkOffset += didRead;
-                mInflateState.next_in = (Bytef*) mInBuf;
-                mInflateState.avail_in = didRead;
-            }
-        }
-    }
-    return 0;
-}
-
-// seeking backwards requires uncompressing fom the beginning, so is very
-// expensive.  seeking forwards only requires uncompressing from the current
-// position to the destination.
-off64_t StreamingZipInflater::seekAbsolute(off64_t absoluteInputPosition) {
-    if (absoluteInputPosition < mOutCurPosition) {
-        // rewind and reprocess the data from the beginning
-        if (!mStreamNeedsInit) {
-            ::inflateEnd(&mInflateState);
-        }
-        initInflateState();
-        read(NULL, absoluteInputPosition);
-    } else if (absoluteInputPosition > mOutCurPosition) {
-        read(NULL, absoluteInputPosition - mOutCurPosition);
-    }
-    // else if the target position *is* our current position, do nothing
-    return absoluteInputPosition;
-}
diff --git a/libs/utils/ZipFileCRO.cpp b/libs/utils/ZipFileCRO.cpp
deleted file mode 100644
index c8df845..0000000
--- a/libs/utils/ZipFileCRO.cpp
+++ /dev/null
@@ -1,54 +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 <androidfw/ZipFileCRO.h>
-#include <androidfw/ZipFileRO.h>
-
-using namespace android;
-
-ZipFileCRO ZipFileXRO_open(const char* path) {
-    ZipFileRO* zip = new ZipFileRO();
-    if (zip->open(path) == NO_ERROR) {
-        return (ZipFileCRO)zip;
-    }
-    return NULL;
-}
-
-void ZipFileCRO_destroy(ZipFileCRO zipToken) {
-    ZipFileRO* zip = (ZipFileRO*)zipToken;
-    delete zip;
-}
-
-ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zipToken,
-        const char* fileName) {
-    ZipFileRO* zip = (ZipFileRO*)zipToken;
-    return (ZipEntryCRO)zip->findEntryByName(fileName);
-}
-
-bool ZipFileCRO_getEntryInfo(ZipFileCRO zipToken, ZipEntryRO entryToken,
-        int* pMethod, size_t* pUncompLen,
-        size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) {
-    ZipFileRO* zip = (ZipFileRO*)zipToken;
-    ZipEntryRO entry = (ZipEntryRO)entryToken;
-    return zip->getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset,
-            pModWhen, pCrc32);
-}
-
-bool ZipFileCRO_uncompressEntry(ZipFileCRO zipToken, ZipEntryRO entryToken, int fd) {
-    ZipFileRO* zip = (ZipFileRO*)zipToken;
-    ZipEntryRO entry = (ZipEntryRO)entryToken;
-    return zip->uncompressEntry(entry, fd);
-}
diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp
deleted file mode 100644
index 4b7f1e7..0000000
--- a/libs/utils/ZipFileRO.cpp
+++ /dev/null
@@ -1,931 +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.
- */
-
-//
-// Read-only access to Zip archives, with minimal heap allocation.
-//
-#define LOG_TAG "zipro"
-//#define LOG_NDEBUG 0
-#include <androidfw/ZipFileRO.h>
-#include <utils/Log.h>
-#include <utils/misc.h>
-#include <utils/threads.h>
-
-#include <zlib.h>
-
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <assert.h>
-#include <unistd.h>
-
-#if HAVE_PRINTF_ZD
-#  define ZD "%zd"
-#  define ZD_TYPE ssize_t
-#else
-#  define ZD "%ld"
-#  define ZD_TYPE long
-#endif
-
-/*
- * We must open binary files using open(path, ... | O_BINARY) under Windows.
- * Otherwise strange read errors will happen.
- */
-#ifndef O_BINARY
-#  define O_BINARY  0
-#endif
-
-/*
- * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
- * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
- * not already defined, then define it here.
- */
-#ifndef TEMP_FAILURE_RETRY
-/* Used to retry syscalls that can return EINTR. */
-#define TEMP_FAILURE_RETRY(exp) ({         \
-    typeof (exp) _rc;                      \
-    do {                                   \
-        _rc = (exp);                       \
-    } while (_rc == -1 && errno == EINTR); \
-    _rc; })
-#endif
-
-using namespace android;
-
-/*
- * Zip file constants.
- */
-#define kEOCDSignature      0x06054b50
-#define kEOCDLen            22
-#define kEOCDNumEntries     8               // offset to #of entries in file
-#define kEOCDSize           12              // size of the central directory
-#define kEOCDFileOffset     16              // offset to central directory
-
-#define kMaxCommentLen      65535           // longest possible in ushort
-#define kMaxEOCDSearch      (kMaxCommentLen + kEOCDLen)
-
-#define kLFHSignature       0x04034b50
-#define kLFHLen             30              // excluding variable-len fields
-#define kLFHNameLen         26              // offset to filename length
-#define kLFHExtraLen        28              // offset to extra length
-
-#define kCDESignature       0x02014b50
-#define kCDELen             46              // excluding variable-len fields
-#define kCDEMethod          10              // offset to compression method
-#define kCDEModWhen         12              // offset to modification timestamp
-#define kCDECRC             16              // offset to entry CRC
-#define kCDECompLen         20              // offset to compressed length
-#define kCDEUncompLen       24              // offset to uncompressed length
-#define kCDENameLen         28              // offset to filename length
-#define kCDEExtraLen        30              // offset to extra length
-#define kCDECommentLen      32              // offset to comment length
-#define kCDELocalOffset     42              // offset to local hdr
-
-/*
- * The values we return for ZipEntryRO use 0 as an invalid value, so we
- * want to adjust the hash table index by a fixed amount.  Using a large
- * value helps insure that people don't mix & match arguments, e.g. to
- * findEntryByIndex().
- */
-#define kZipEntryAdj        10000
-
-ZipFileRO::~ZipFileRO() {
-    free(mHashTable);
-    if (mDirectoryMap)
-        mDirectoryMap->release();
-    if (mFd >= 0)
-        TEMP_FAILURE_RETRY(close(mFd));
-    if (mFileName)
-        free(mFileName);
-}
-
-/*
- * Convert a ZipEntryRO to a hash table index, verifying that it's in a
- * valid range.
- */
-int ZipFileRO::entryToIndex(const ZipEntryRO entry) const
-{
-    long ent = ((long) entry) - kZipEntryAdj;
-    if (ent < 0 || ent >= mHashTableSize || mHashTable[ent].name == NULL) {
-        ALOGW("Invalid ZipEntryRO %p (%ld)\n", entry, ent);
-        return -1;
-    }
-    return ent;
-}
-
-
-/*
- * Open the specified file read-only.  We memory-map the entire thing and
- * close the file before returning.
- */
-status_t ZipFileRO::open(const char* zipFileName)
-{
-    int fd = -1;
-
-    assert(mDirectoryMap == NULL);
-
-    /*
-     * Open and map the specified file.
-     */
-    fd = ::open(zipFileName, O_RDONLY | O_BINARY);
-    if (fd < 0) {
-        ALOGW("Unable to open zip '%s': %s\n", zipFileName, strerror(errno));
-        return NAME_NOT_FOUND;
-    }
-
-    mFileLength = lseek64(fd, 0, SEEK_END);
-    if (mFileLength < kEOCDLen) {
-        TEMP_FAILURE_RETRY(close(fd));
-        return UNKNOWN_ERROR;
-    }
-
-    if (mFileName != NULL) {
-        free(mFileName);
-    }
-    mFileName = strdup(zipFileName);
-
-    mFd = fd;
-
-    /*
-     * Find the Central Directory and store its size and number of entries.
-     */
-    if (!mapCentralDirectory()) {
-        goto bail;
-    }
-
-    /*
-     * Verify Central Directory and create data structures for fast access.
-     */
-    if (!parseZipArchive()) {
-        goto bail;
-    }
-
-    return OK;
-
-bail:
-    free(mFileName);
-    mFileName = NULL;
-    TEMP_FAILURE_RETRY(close(fd));
-    return UNKNOWN_ERROR;
-}
-
-/*
- * Parse the Zip archive, verifying its contents and initializing internal
- * data structures.
- */
-bool ZipFileRO::mapCentralDirectory(void)
-{
-    ssize_t readAmount = kMaxEOCDSearch;
-    if (readAmount > (ssize_t) mFileLength)
-        readAmount = mFileLength;
-
-    unsigned char* scanBuf = (unsigned char*) malloc(readAmount);
-    if (scanBuf == NULL) {
-        ALOGW("couldn't allocate scanBuf: %s", strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-    /*
-     * Make sure this is a Zip archive.
-     */
-    if (lseek64(mFd, 0, SEEK_SET) != 0) {
-        ALOGW("seek to start failed: %s", strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-    ssize_t actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, sizeof(int32_t)));
-    if (actual != (ssize_t) sizeof(int32_t)) {
-        ALOGI("couldn't read first signature from zip archive: %s", strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-    {
-        unsigned int header = get4LE(scanBuf);
-        if (header == kEOCDSignature) {
-            ALOGI("Found Zip archive, but it looks empty\n");
-            free(scanBuf);
-            return false;
-        } else if (header != kLFHSignature) {
-            ALOGV("Not a Zip archive (found 0x%08x)\n", header);
-            free(scanBuf);
-            return false;
-        }
-    }
-
-    /*
-     * Perform the traditional EOCD snipe hunt.
-     *
-     * We're searching for the End of Central Directory magic number,
-     * which appears at the start of the EOCD block.  It's followed by
-     * 18 bytes of EOCD stuff and up to 64KB of archive comment.  We
-     * need to read the last part of the file into a buffer, dig through
-     * it to find the magic number, parse some values out, and use those
-     * to determine the extent of the CD.
-     *
-     * We start by pulling in the last part of the file.
-     */
-    off64_t searchStart = mFileLength - readAmount;
-
-    if (lseek64(mFd, searchStart, SEEK_SET) != searchStart) {
-        ALOGW("seek %ld failed: %s\n",  (long) searchStart, strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-    actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, readAmount));
-    if (actual != (ssize_t) readAmount) {
-        ALOGW("Zip: read " ZD ", expected " ZD ". Failed: %s\n",
-            (ZD_TYPE) actual, (ZD_TYPE) readAmount, strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-    /*
-     * Scan backward for the EOCD magic.  In an archive without a trailing
-     * comment, we'll find it on the first try.  (We may want to consider
-     * doing an initial minimal read; if we don't find it, retry with a
-     * second read as above.)
-     */
-    int i;
-    for (i = readAmount - kEOCDLen; i >= 0; i--) {
-        if (scanBuf[i] == 0x50 && get4LE(&scanBuf[i]) == kEOCDSignature) {
-            ALOGV("+++ Found EOCD at buf+%d\n", i);
-            break;
-        }
-    }
-    if (i < 0) {
-        ALOGD("Zip: EOCD not found, %s is not zip\n", mFileName);
-        free(scanBuf);
-        return false;
-    }
-
-    off64_t eocdOffset = searchStart + i;
-    const unsigned char* eocdPtr = scanBuf + i;
-
-    assert(eocdOffset < mFileLength);
-
-    /*
-     * Grab the CD offset and size, and the number of entries in the
-     * archive. After that, we can release our EOCD hunt buffer.
-     */
-    unsigned int numEntries = get2LE(eocdPtr + kEOCDNumEntries);
-    unsigned int dirSize = get4LE(eocdPtr + kEOCDSize);
-    unsigned int dirOffset = get4LE(eocdPtr + kEOCDFileOffset);
-    free(scanBuf);
-
-    // Verify that they look reasonable.
-    if ((long long) dirOffset + (long long) dirSize > (long long) eocdOffset) {
-        ALOGW("bad offsets (dir %ld, size %u, eocd %ld)\n",
-            (long) dirOffset, dirSize, (long) eocdOffset);
-        return false;
-    }
-    if (numEntries == 0) {
-        ALOGW("empty archive?\n");
-        return false;
-    }
-
-    ALOGV("+++ numEntries=%d dirSize=%d dirOffset=%d\n",
-        numEntries, dirSize, dirOffset);
-
-    mDirectoryMap = new FileMap();
-    if (mDirectoryMap == NULL) {
-        ALOGW("Unable to create directory map: %s", strerror(errno));
-        return false;
-    }
-
-    if (!mDirectoryMap->create(mFileName, mFd, dirOffset, dirSize, true)) {
-        ALOGW("Unable to map '%s' (" ZD " to " ZD "): %s\n", mFileName,
-                (ZD_TYPE) dirOffset, (ZD_TYPE) (dirOffset + dirSize), strerror(errno));
-        return false;
-    }
-
-    mNumEntries = numEntries;
-    mDirectoryOffset = dirOffset;
-
-    return true;
-}
-
-bool ZipFileRO::parseZipArchive(void)
-{
-    bool result = false;
-    const unsigned char* cdPtr = (const unsigned char*) mDirectoryMap->getDataPtr();
-    size_t cdLength = mDirectoryMap->getDataLength();
-    int numEntries = mNumEntries;
-
-    /*
-     * Create hash table.  We have a minimum 75% load factor, possibly as
-     * low as 50% after we round off to a power of 2.
-     */
-    mHashTableSize = roundUpPower2(1 + (numEntries * 4) / 3);
-    mHashTable = (HashEntry*) calloc(mHashTableSize, sizeof(HashEntry));
-
-    /*
-     * Walk through the central directory, adding entries to the hash
-     * table.
-     */
-    const unsigned char* ptr = cdPtr;
-    for (int i = 0; i < numEntries; i++) {
-        if (get4LE(ptr) != kCDESignature) {
-            ALOGW("Missed a central dir sig (at %d)\n", i);
-            goto bail;
-        }
-        if (ptr + kCDELen > cdPtr + cdLength) {
-            ALOGW("Ran off the end (at %d)\n", i);
-            goto bail;
-        }
-
-        long localHdrOffset = (long) get4LE(ptr + kCDELocalOffset);
-        if (localHdrOffset >= mDirectoryOffset) {
-            ALOGW("bad LFH offset %ld at entry %d\n", localHdrOffset, i);
-            goto bail;
-        }
-
-        unsigned int fileNameLen, extraLen, commentLen, hash;
-
-        fileNameLen = get2LE(ptr + kCDENameLen);
-        extraLen = get2LE(ptr + kCDEExtraLen);
-        commentLen = get2LE(ptr + kCDECommentLen);
-
-        /* add the CDE filename to the hash table */
-        hash = computeHash((const char*)ptr + kCDELen, fileNameLen);
-        addToHash((const char*)ptr + kCDELen, fileNameLen, hash);
-
-        ptr += kCDELen + fileNameLen + extraLen + commentLen;
-        if ((size_t)(ptr - cdPtr) > cdLength) {
-            ALOGW("bad CD advance (%d vs " ZD ") at entry %d\n",
-                (int) (ptr - cdPtr), (ZD_TYPE) cdLength, i);
-            goto bail;
-        }
-    }
-    ALOGV("+++ zip good scan %d entries\n", numEntries);
-    result = true;
-
-bail:
-    return result;
-}
-
-/*
- * Simple string hash function for non-null-terminated strings.
- */
-/*static*/ unsigned int ZipFileRO::computeHash(const char* str, int len)
-{
-    unsigned int hash = 0;
-
-    while (len--)
-        hash = hash * 31 + *str++;
-
-    return hash;
-}
-
-/*
- * Add a new entry to the hash table.
- */
-void ZipFileRO::addToHash(const char* str, int strLen, unsigned int hash)
-{
-    int ent = hash & (mHashTableSize-1);
-
-    /*
-     * We over-allocate the table, so we're guaranteed to find an empty slot.
-     */
-    while (mHashTable[ent].name != NULL)
-        ent = (ent + 1) & (mHashTableSize-1);
-
-    mHashTable[ent].name = str;
-    mHashTable[ent].nameLen = strLen;
-}
-
-/*
- * Find a matching entry.
- *
- * Returns NULL if not found.
- */
-ZipEntryRO ZipFileRO::findEntryByName(const char* fileName) const
-{
-    /*
-     * If the ZipFileRO instance is not initialized, the entry number will
-     * end up being garbage since mHashTableSize is -1.
-     */
-    if (mHashTableSize <= 0) {
-        return NULL;
-    }
-
-    int nameLen = strlen(fileName);
-    unsigned int hash = computeHash(fileName, nameLen);
-    int ent = hash & (mHashTableSize-1);
-
-    while (mHashTable[ent].name != NULL) {
-        if (mHashTable[ent].nameLen == nameLen &&
-            memcmp(mHashTable[ent].name, fileName, nameLen) == 0)
-        {
-            /* match */
-            return (ZipEntryRO)(long)(ent + kZipEntryAdj);
-        }
-
-        ent = (ent + 1) & (mHashTableSize-1);
-    }
-
-    return NULL;
-}
-
-/*
- * Find the Nth entry.
- *
- * This currently involves walking through the sparse hash table, counting
- * non-empty entries.  If we need to speed this up we can either allocate
- * a parallel lookup table or (perhaps better) provide an iterator interface.
- */
-ZipEntryRO ZipFileRO::findEntryByIndex(int idx) const
-{
-    if (idx < 0 || idx >= mNumEntries) {
-        ALOGW("Invalid index %d\n", idx);
-        return NULL;
-    }
-
-    for (int ent = 0; ent < mHashTableSize; ent++) {
-        if (mHashTable[ent].name != NULL) {
-            if (idx-- == 0)
-                return (ZipEntryRO) (ent + kZipEntryAdj);
-        }
-    }
-
-    return NULL;
-}
-
-/*
- * Get the useful fields from the zip entry.
- *
- * Returns "false" if the offsets to the fields or the contents of the fields
- * appear to be bogus.
- */
-bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
-    size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const
-{
-    bool ret = false;
-
-    const int ent = entryToIndex(entry);
-    if (ent < 0)
-        return false;
-
-    HashEntry hashEntry = mHashTable[ent];
-
-    /*
-     * Recover the start of the central directory entry from the filename
-     * pointer.  The filename is the first entry past the fixed-size data,
-     * so we can just subtract back from that.
-     */
-    const unsigned char* ptr = (const unsigned char*) hashEntry.name;
-    off64_t cdOffset = mDirectoryOffset;
-
-    ptr -= kCDELen;
-
-    int method = get2LE(ptr + kCDEMethod);
-    if (pMethod != NULL)
-        *pMethod = method;
-
-    if (pModWhen != NULL)
-        *pModWhen = get4LE(ptr + kCDEModWhen);
-    if (pCrc32 != NULL)
-        *pCrc32 = get4LE(ptr + kCDECRC);
-
-    size_t compLen = get4LE(ptr + kCDECompLen);
-    if (pCompLen != NULL)
-        *pCompLen = compLen;
-    size_t uncompLen = get4LE(ptr + kCDEUncompLen);
-    if (pUncompLen != NULL)
-        *pUncompLen = uncompLen;
-
-    /*
-     * If requested, determine the offset of the start of the data.  All we
-     * have is the offset to the Local File Header, which is variable size,
-     * so we have to read the contents of the struct to figure out where
-     * the actual data starts.
-     *
-     * We also need to make sure that the lengths are not so large that
-     * somebody trying to map the compressed or uncompressed data runs
-     * off the end of the mapped region.
-     *
-     * Note we don't verify compLen/uncompLen if they don't request the
-     * dataOffset, because dataOffset is expensive to determine.  However,
-     * if they don't have the file offset, they're not likely to be doing
-     * anything with the contents.
-     */
-    if (pOffset != NULL) {
-        long localHdrOffset = get4LE(ptr + kCDELocalOffset);
-        if (localHdrOffset + kLFHLen >= cdOffset) {
-            ALOGE("ERROR: bad local hdr offset in zip\n");
-            return false;
-        }
-
-        unsigned char lfhBuf[kLFHLen];
-
-#ifdef HAVE_PREAD
-        /*
-         * This file descriptor might be from zygote's preloaded assets,
-         * so we need to do an pread64() instead of a lseek64() + read() to
-         * guarantee atomicity across the processes with the shared file
-         * descriptors.
-         */
-        ssize_t actual =
-                TEMP_FAILURE_RETRY(pread64(mFd, lfhBuf, sizeof(lfhBuf), localHdrOffset));
-
-        if (actual != sizeof(lfhBuf)) {
-            ALOGW("failed reading lfh from offset %ld\n", localHdrOffset);
-            return false;
-        }
-
-        if (get4LE(lfhBuf) != kLFHSignature) {
-            ALOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
-                    "got: data=0x%08lx\n",
-                    localHdrOffset, kLFHSignature, get4LE(lfhBuf));
-            return false;
-        }
-#else /* HAVE_PREAD */
-        /*
-         * For hosts don't have pread64() we cannot guarantee atomic reads from
-         * an offset in a file. Android should never run on those platforms.
-         * File descriptors inherited from a fork() share file offsets and
-         * there would be nothing to protect from two different processes
-         * calling lseek64() concurrently.
-         */
-
-        {
-            AutoMutex _l(mFdLock);
-
-            if (lseek64(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
-                ALOGW("failed seeking to lfh at offset %ld\n", localHdrOffset);
-                return false;
-            }
-
-            ssize_t actual =
-                    TEMP_FAILURE_RETRY(read(mFd, lfhBuf, sizeof(lfhBuf)));
-            if (actual != sizeof(lfhBuf)) {
-                ALOGW("failed reading lfh from offset %ld\n", localHdrOffset);
-                return false;
-            }
-
-            if (get4LE(lfhBuf) != kLFHSignature) {
-                off64_t actualOffset = lseek64(mFd, 0, SEEK_CUR);
-                ALOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
-                        "got: offset=" ZD " data=0x%08lx\n",
-                        localHdrOffset, kLFHSignature, (ZD_TYPE) actualOffset, get4LE(lfhBuf));
-                return false;
-            }
-        }
-#endif /* HAVE_PREAD */
-
-        off64_t dataOffset = localHdrOffset + kLFHLen
-            + get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);
-        if (dataOffset >= cdOffset) {
-            ALOGW("bad data offset %ld in zip\n", (long) dataOffset);
-            return false;
-        }
-
-        /* check lengths */
-        if ((off64_t)(dataOffset + compLen) > cdOffset) {
-            ALOGW("bad compressed length in zip (%ld + " ZD " > %ld)\n",
-                (long) dataOffset, (ZD_TYPE) compLen, (long) cdOffset);
-            return false;
-        }
-
-        if (method == kCompressStored &&
-            (off64_t)(dataOffset + uncompLen) > cdOffset)
-        {
-            ALOGE("ERROR: bad uncompressed length in zip (%ld + " ZD " > %ld)\n",
-                (long) dataOffset, (ZD_TYPE) uncompLen, (long) cdOffset);
-            return false;
-        }
-
-        *pOffset = dataOffset;
-    }
-
-    return true;
-}
-
-/*
- * Copy the entry's filename to the buffer.
- */
-int ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen)
-    const
-{
-    int ent = entryToIndex(entry);
-    if (ent < 0)
-        return -1;
-
-    int nameLen = mHashTable[ent].nameLen;
-    if (bufLen < nameLen+1)
-        return nameLen+1;
-
-    memcpy(buffer, mHashTable[ent].name, nameLen);
-    buffer[nameLen] = '\0';
-    return 0;
-}
-
-/*
- * Create a new FileMap object that spans the data in "entry".
- */
-FileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const
-{
-    /*
-     * TODO: the efficient way to do this is to modify FileMap to allow
-     * sub-regions of a file to be mapped.  A reference-counting scheme
-     * can manage the base memory mapping.  For now, we just create a brand
-     * new mapping off of the Zip archive file descriptor.
-     */
-
-    FileMap* newMap;
-    size_t compLen;
-    off64_t offset;
-
-    if (!getEntryInfo(entry, NULL, NULL, &compLen, &offset, NULL, NULL))
-        return NULL;
-
-    newMap = new FileMap();
-    if (!newMap->create(mFileName, mFd, offset, compLen, true)) {
-        newMap->release();
-        return NULL;
-    }
-
-    return newMap;
-}
-
-/*
- * Uncompress an entry, in its entirety, into the provided output buffer.
- *
- * This doesn't verify the data's CRC, which might be useful for
- * uncompressed data.  The caller should be able to manage it.
- */
-bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
-{
-    const size_t kSequentialMin = 32768;
-    bool result = false;
-    int ent = entryToIndex(entry);
-    if (ent < 0)
-        return -1;
-
-    int method;
-    size_t uncompLen, compLen;
-    off64_t offset;
-    const unsigned char* ptr;
-
-    getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
-
-    FileMap* file = createEntryFileMap(entry);
-    if (file == NULL) {
-        goto bail;
-    }
-
-    ptr = (const unsigned char*) file->getDataPtr();
-
-    /*
-     * Experiment with madvise hint.  When we want to uncompress a file,
-     * we pull some stuff out of the central dir entry and then hit a
-     * bunch of compressed or uncompressed data sequentially.  The CDE
-     * visit will cause a limited amount of read-ahead because it's at
-     * the end of the file.  We could end up doing lots of extra disk
-     * access if the file we're prying open is small.  Bottom line is we
-     * probably don't want to turn MADV_SEQUENTIAL on and leave it on.
-     *
-     * So, if the compressed size of the file is above a certain minimum
-     * size, temporarily boost the read-ahead in the hope that the extra
-     * pair of system calls are negated by a reduction in page faults.
-     */
-    if (compLen > kSequentialMin)
-        file->advise(FileMap::SEQUENTIAL);
-
-    if (method == kCompressStored) {
-        memcpy(buffer, ptr, uncompLen);
-    } else {
-        if (!inflateBuffer(buffer, ptr, uncompLen, compLen))
-            goto unmap;
-    }
-
-    if (compLen > kSequentialMin)
-        file->advise(FileMap::NORMAL);
-
-    result = true;
-
-unmap:
-    file->release();
-bail:
-    return result;
-}
-
-/*
- * Uncompress an entry, in its entirety, to an open file descriptor.
- *
- * This doesn't verify the data's CRC, but probably should.
- */
-bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
-{
-    bool result = false;
-    int ent = entryToIndex(entry);
-    if (ent < 0)
-        return -1;
-
-    int method;
-    size_t uncompLen, compLen;
-    off64_t offset;
-    const unsigned char* ptr;
-
-    getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
-
-    FileMap* file = createEntryFileMap(entry);
-    if (file == NULL) {
-        goto bail;
-    }
-
-    ptr = (const unsigned char*) file->getDataPtr();
-
-    if (method == kCompressStored) {
-        ssize_t actual = write(fd, ptr, uncompLen);
-        if (actual < 0) {
-            ALOGE("Write failed: %s\n", strerror(errno));
-            goto unmap;
-        } else if ((size_t) actual != uncompLen) {
-            ALOGE("Partial write during uncompress (" ZD " of " ZD ")\n",
-                (ZD_TYPE) actual, (ZD_TYPE) uncompLen);
-            goto unmap;
-        } else {
-            ALOGI("+++ successful write\n");
-        }
-    } else {
-        if (!inflateBuffer(fd, ptr, uncompLen, compLen))
-            goto unmap;
-    }
-
-    result = true;
-
-unmap:
-    file->release();
-bail:
-    return result;
-}
-
-/*
- * Uncompress "deflate" data from one buffer to another.
- */
-/*static*/ bool ZipFileRO::inflateBuffer(void* outBuf, const void* inBuf,
-    size_t uncompLen, size_t compLen)
-{
-    bool result = false;
-    z_stream zstream;
-    int zerr;
-
-    /*
-     * Initialize the zlib stream struct.
-     */
-    memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = (Bytef*)inBuf;
-    zstream.avail_in = compLen;
-    zstream.next_out = (Bytef*) outBuf;
-    zstream.avail_out = uncompLen;
-    zstream.data_type = Z_UNKNOWN;
-
-    /*
-     * Use the undocumented "negative window bits" feature to tell zlib
-     * that there's no zlib header waiting for it.
-     */
-    zerr = inflateInit2(&zstream, -MAX_WBITS);
-    if (zerr != Z_OK) {
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
-
-    /*
-     * Expand data.
-     */
-    zerr = inflate(&zstream, Z_FINISH);
-    if (zerr != Z_STREAM_END) {
-        ALOGW("Zip inflate failed, zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
-            zerr, zstream.next_in, zstream.avail_in,
-            zstream.next_out, zstream.avail_out);
-        goto z_bail;
-    }
-
-    /* paranoia */
-    if (zstream.total_out != uncompLen) {
-        ALOGW("Size mismatch on inflated file (%ld vs " ZD ")\n",
-            zstream.total_out, (ZD_TYPE) uncompLen);
-        goto z_bail;
-    }
-
-    result = true;
-
-z_bail:
-    inflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-    return result;
-}
-
-/*
- * Uncompress "deflate" data from one buffer to an open file descriptor.
- */
-/*static*/ bool ZipFileRO::inflateBuffer(int fd, const void* inBuf,
-    size_t uncompLen, size_t compLen)
-{
-    bool result = false;
-    const size_t kWriteBufSize = 32768;
-    unsigned char writeBuf[kWriteBufSize];
-    z_stream zstream;
-    int zerr;
-
-    /*
-     * Initialize the zlib stream struct.
-     */
-    memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = (Bytef*)inBuf;
-    zstream.avail_in = compLen;
-    zstream.next_out = (Bytef*) writeBuf;
-    zstream.avail_out = sizeof(writeBuf);
-    zstream.data_type = Z_UNKNOWN;
-
-    /*
-     * Use the undocumented "negative window bits" feature to tell zlib
-     * that there's no zlib header waiting for it.
-     */
-    zerr = inflateInit2(&zstream, -MAX_WBITS);
-    if (zerr != Z_OK) {
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
-
-    /*
-     * Loop while we have more to do.
-     */
-    do {
-        /*
-         * Expand data.
-         */
-        zerr = inflate(&zstream, Z_NO_FLUSH);
-        if (zerr != Z_OK && zerr != Z_STREAM_END) {
-            ALOGW("zlib inflate: zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
-                zerr, zstream.next_in, zstream.avail_in,
-                zstream.next_out, zstream.avail_out);
-            goto z_bail;
-        }
-
-        /* write when we're full or when we're done */
-        if (zstream.avail_out == 0 ||
-            (zerr == Z_STREAM_END && zstream.avail_out != sizeof(writeBuf)))
-        {
-            long writeSize = zstream.next_out - writeBuf;
-            int cc = write(fd, writeBuf, writeSize);
-            if (cc != (int) writeSize) {
-                ALOGW("write failed in inflate (%d vs %ld)\n", cc, writeSize);
-                goto z_bail;
-            }
-
-            zstream.next_out = writeBuf;
-            zstream.avail_out = sizeof(writeBuf);
-        }
-    } while (zerr == Z_OK);
-
-    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
-
-    /* paranoia */
-    if (zstream.total_out != uncompLen) {
-        ALOGW("Size mismatch on inflated file (%ld vs " ZD ")\n",
-            zstream.total_out, (ZD_TYPE) uncompLen);
-        goto z_bail;
-    }
-
-    result = true;
-
-z_bail:
-    inflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-    return result;
-}
diff --git a/libs/utils/ZipUtils.cpp b/libs/utils/ZipUtils.cpp
deleted file mode 100644
index db3479d..0000000
--- a/libs/utils/ZipUtils.cpp
+++ /dev/null
@@ -1,343 +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.
- */
-
-//
-// Misc zip/gzip utility functions.
-//
-
-#define LOG_TAG "ziputil"
-
-#include <androidfw/ZipUtils.h>
-#include <androidfw/ZipFileRO.h>
-#include <utils/Log.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <zlib.h>
-
-using namespace android;
-
-/*
- * Utility function that expands zip/gzip "deflate" compressed data
- * into a buffer.
- *
- * "fd" is an open file positioned at the start of the "deflate" data
- * "buf" must hold at least "uncompressedLen" bytes.
- */
-/*static*/ bool ZipUtils::inflateToBuffer(int fd, void* buf,
-    long uncompressedLen, long compressedLen)
-{
-    bool result = false;
-	const unsigned long kReadBufSize = 32768;
-	unsigned char* readBuf = NULL;
-    z_stream zstream;
-    int zerr;
-    unsigned long compRemaining;
-
-    assert(uncompressedLen >= 0);
-    assert(compressedLen >= 0);
-
-	readBuf = new unsigned char[kReadBufSize];
-	if (readBuf == NULL)
-        goto bail;
-    compRemaining = compressedLen;
-
-    /*
-     * Initialize the zlib stream.
-     */
-	memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = NULL;
-    zstream.avail_in = 0;
-    zstream.next_out = (Bytef*) buf;
-    zstream.avail_out = uncompressedLen;
-    zstream.data_type = Z_UNKNOWN;
-
-	/*
-	 * Use the undocumented "negative window bits" feature to tell zlib
-	 * that there's no zlib header waiting for it.
-	 */
-    zerr = inflateInit2(&zstream, -MAX_WBITS);
-    if (zerr != Z_OK) {
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
-
-    /*
-     * Loop while we have data.
-     */
-    do {
-        unsigned long getSize;
-
-        /* read as much as we can */
-        if (zstream.avail_in == 0) {
-            getSize = (compRemaining > kReadBufSize) ?
-                        kReadBufSize : compRemaining;
-            ALOGV("+++ reading %ld bytes (%ld left)\n",
-                getSize, compRemaining);
-
-            int cc = read(fd, readBuf, getSize);
-            if (cc != (int) getSize) {
-                ALOGD("inflate read failed (%d vs %ld)\n",
-                    cc, getSize);
-                goto z_bail;
-            }
-
-            compRemaining -= getSize;
-
-            zstream.next_in = readBuf;
-            zstream.avail_in = getSize;
-        }
-
-        /* uncompress the data */
-        zerr = inflate(&zstream, Z_NO_FLUSH);
-        if (zerr != Z_OK && zerr != Z_STREAM_END) {
-            ALOGD("zlib inflate call failed (zerr=%d)\n", zerr);
-            goto z_bail;
-        }
-
-		/* output buffer holds all, so no need to write the output */
-    } while (zerr == Z_OK);
-
-    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
-
-    if ((long) zstream.total_out != uncompressedLen) {
-        ALOGW("Size mismatch on inflated file (%ld vs %ld)\n",
-            zstream.total_out, uncompressedLen);
-        goto z_bail;
-    }
-
-    // success!
-    result = true;
-
-z_bail:
-    inflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-	delete[] readBuf;
-    return result;
-}
-
-/*
- * Utility function that expands zip/gzip "deflate" compressed data
- * into a buffer.
- *
- * (This is a clone of the previous function, but it takes a FILE* instead
- * of an fd.  We could pass fileno(fd) to the above, but we can run into
- * trouble when "fp" has a different notion of what fd's file position is.)
- *
- * "fp" is an open file positioned at the start of the "deflate" data
- * "buf" must hold at least "uncompressedLen" bytes.
- */
-/*static*/ bool ZipUtils::inflateToBuffer(FILE* fp, void* buf,
-    long uncompressedLen, long compressedLen)
-{
-    bool result = false;
-	const unsigned long kReadBufSize = 32768;
-	unsigned char* readBuf = NULL;
-    z_stream zstream;
-    int zerr;
-    unsigned long compRemaining;
-
-    assert(uncompressedLen >= 0);
-    assert(compressedLen >= 0);
-
-	readBuf = new unsigned char[kReadBufSize];
-	if (readBuf == NULL)
-        goto bail;
-    compRemaining = compressedLen;
-
-    /*
-     * Initialize the zlib stream.
-     */
-	memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = NULL;
-    zstream.avail_in = 0;
-    zstream.next_out = (Bytef*) buf;
-    zstream.avail_out = uncompressedLen;
-    zstream.data_type = Z_UNKNOWN;
-
-	/*
-	 * Use the undocumented "negative window bits" feature to tell zlib
-	 * that there's no zlib header waiting for it.
-	 */
-    zerr = inflateInit2(&zstream, -MAX_WBITS);
-    if (zerr != Z_OK) {
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
-
-    /*
-     * Loop while we have data.
-     */
-    do {
-        unsigned long getSize;
-
-        /* read as much as we can */
-        if (zstream.avail_in == 0) {
-            getSize = (compRemaining > kReadBufSize) ?
-                        kReadBufSize : compRemaining;
-            ALOGV("+++ reading %ld bytes (%ld left)\n",
-                getSize, compRemaining);
-
-            int cc = fread(readBuf, 1, getSize, fp);
-            if (cc != (int) getSize) {
-                ALOGD("inflate read failed (%d vs %ld)\n",
-                    cc, getSize);
-                goto z_bail;
-            }
-
-            compRemaining -= getSize;
-
-            zstream.next_in = readBuf;
-            zstream.avail_in = getSize;
-        }
-
-        /* uncompress the data */
-        zerr = inflate(&zstream, Z_NO_FLUSH);
-        if (zerr != Z_OK && zerr != Z_STREAM_END) {
-            ALOGD("zlib inflate call failed (zerr=%d)\n", zerr);
-            goto z_bail;
-        }
-
-		/* output buffer holds all, so no need to write the output */
-    } while (zerr == Z_OK);
-
-    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
-
-    if ((long) zstream.total_out != uncompressedLen) {
-        ALOGW("Size mismatch on inflated file (%ld vs %ld)\n",
-            zstream.total_out, uncompressedLen);
-        goto z_bail;
-    }
-
-    // success!
-    result = true;
-
-z_bail:
-    inflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-	delete[] readBuf;
-    return result;
-}
-
-/*
- * Look at the contents of a gzip archive.  We want to know where the
- * data starts, and how long it will be after it is uncompressed.
- *
- * We expect to find the CRC and length as the last 8 bytes on the file.
- * This is a pretty reasonable thing to expect for locally-compressed
- * files, but there's a small chance that some extra padding got thrown
- * on (the man page talks about compressed data written to tape).  We
- * don't currently deal with that here.  If "gzip -l" whines, we're going
- * to fail too.
- *
- * On exit, "fp" is pointing at the start of the compressed data.
- */
-/*static*/ bool ZipUtils::examineGzip(FILE* fp, int* pCompressionMethod,
-    long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32)
-{
-    enum {  // flags
-        FTEXT       = 0x01,
-        FHCRC       = 0x02,
-        FEXTRA      = 0x04,
-        FNAME       = 0x08,
-        FCOMMENT    = 0x10,
-    };
-    int ic;
-    int method, flags;
-    int i;
-
-    ic = getc(fp);
-    if (ic != 0x1f || getc(fp) != 0x8b)
-        return false;       // not gzip
-    method = getc(fp);
-    flags = getc(fp);
-
-    /* quick sanity checks */
-    if (method == EOF || flags == EOF)
-        return false;
-    if (method != ZipFileRO::kCompressDeflated)
-        return false;
-
-    /* skip over 4 bytes of mod time, 1 byte XFL, 1 byte OS */
-    for (i = 0; i < 6; i++)
-        (void) getc(fp);
-    /* consume "extra" field, if present */
-    if ((flags & FEXTRA) != 0) {
-        int len;
-
-        len = getc(fp);
-        len |= getc(fp) << 8;
-        while (len-- && getc(fp) != EOF)
-            ;
-    }
-    /* consume filename, if present */
-    if ((flags & FNAME) != 0) {
-        do {
-            ic = getc(fp);
-        } while (ic != 0 && ic != EOF);
-    }
-    /* consume comment, if present */
-    if ((flags & FCOMMENT) != 0) {
-        do {
-            ic = getc(fp);
-        } while (ic != 0 && ic != EOF);
-    }
-    /* consume 16-bit header CRC, if present */
-    if ((flags & FHCRC) != 0) {
-        (void) getc(fp);
-        (void) getc(fp);
-    }
-
-    if (feof(fp) || ferror(fp))
-        return false;
-
-    /* seek to the end; CRC and length are in the last 8 bytes */
-    long curPosn = ftell(fp);
-    unsigned char buf[8];
-    fseek(fp, -8, SEEK_END);
-    *pCompressedLen = ftell(fp) - curPosn;
-
-    if (fread(buf, 1, 8, fp) != 8)
-        return false;
-    /* seek back to start of compressed data */
-    fseek(fp, curPosn, SEEK_SET);
-
-    *pCompressionMethod = method;
-    *pCRC32 = ZipFileRO::get4LE(&buf[0]);
-    *pUncompressedLen = ZipFileRO::get4LE(&buf[4]);
-
-    return true;
-}
diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk
index 58230f4..a6811fc 100644
--- a/libs/utils/tests/Android.mk
+++ b/libs/utils/tests/Android.mk
@@ -7,10 +7,8 @@
 	BasicHashtable_test.cpp \
 	BlobCache_test.cpp \
 	Looper_test.cpp \
-	ObbFile_test.cpp \
 	String8_test.cpp \
 	Unicode_test.cpp \
-	ZipFileRO_test.cpp \
 
 shared_libraries := \
 	libz \
diff --git a/libs/utils/tests/ObbFile_test.cpp b/libs/utils/tests/ObbFile_test.cpp
deleted file mode 100644
index 09d4d7d..0000000
--- a/libs/utils/tests/ObbFile_test.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2010 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 "ObbFile_test"
-#include <androidfw/ObbFile.h>
-#include <utils/Log.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-
-#include <gtest/gtest.h>
-
-#include <fcntl.h>
-#include <string.h>
-
-namespace android {
-
-#define TEST_FILENAME "/test.obb"
-
-class ObbFileTest : public testing::Test {
-protected:
-    sp<ObbFile> mObbFile;
-    char* mExternalStorage;
-    char* mFileName;
-
-    virtual void SetUp() {
-        mObbFile = new ObbFile();
-        mExternalStorage = getenv("EXTERNAL_STORAGE");
-
-        const int totalLen = strlen(mExternalStorage) + strlen(TEST_FILENAME) + 1;
-        mFileName = new char[totalLen];
-        snprintf(mFileName, totalLen, "%s%s", mExternalStorage, TEST_FILENAME);
-
-        int fd = ::open(mFileName, O_CREAT | O_TRUNC);
-        if (fd < 0) {
-            FAIL() << "Couldn't create " << mFileName << " for tests";
-        }
-    }
-
-    virtual void TearDown() {
-    }
-};
-
-TEST_F(ObbFileTest, ReadFailure) {
-    EXPECT_FALSE(mObbFile->readFrom(-1))
-            << "No failure on invalid file descriptor";
-}
-
-TEST_F(ObbFileTest, WriteThenRead) {
-    const char* packageName = "com.example.obbfile";
-    const int32_t versionNum = 1;
-
-    mObbFile->setPackageName(String8(packageName));
-    mObbFile->setVersion(versionNum);
-#define SALT_SIZE 8
-    unsigned char salt[SALT_SIZE] = {0x01, 0x10, 0x55, 0xAA, 0xFF, 0x00, 0x5A, 0xA5};
-    EXPECT_TRUE(mObbFile->setSalt(salt, SALT_SIZE))
-            << "Salt should be successfully set";
-
-    EXPECT_TRUE(mObbFile->writeTo(mFileName))
-            << "couldn't write to fake .obb file";
-
-    mObbFile = new ObbFile();
-
-    EXPECT_TRUE(mObbFile->readFrom(mFileName))
-            << "couldn't read from fake .obb file";
-
-    EXPECT_EQ(versionNum, mObbFile->getVersion())
-            << "version didn't come out the same as it went in";
-    const char* currentPackageName = mObbFile->getPackageName().string();
-    EXPECT_STREQ(packageName, currentPackageName)
-            << "package name didn't come out the same as it went in";
-
-    size_t saltLen;
-    const unsigned char* newSalt = mObbFile->getSalt(&saltLen);
-
-    EXPECT_EQ(sizeof(salt), saltLen)
-            << "salt sizes were not the same";
-
-    for (int i = 0; i < sizeof(salt); i++) {
-        EXPECT_EQ(salt[i], newSalt[i])
-                << "salt character " << i << " should be equal";
-    }
-    EXPECT_TRUE(memcmp(newSalt, salt, sizeof(salt)) == 0)
-            << "salts should be the same";
-}
-
-}
diff --git a/libs/utils/tests/ZipFileRO_test.cpp b/libs/utils/tests/ZipFileRO_test.cpp
deleted file mode 100644
index 344f974..0000000
--- a/libs/utils/tests/ZipFileRO_test.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 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 "ZipFileRO_test"
-#include <androidfw/ZipFileRO.h>
-#include <utils/Log.h>
-
-#include <gtest/gtest.h>
-
-#include <fcntl.h>
-#include <string.h>
-
-namespace android {
-
-class ZipFileROTest : public testing::Test {
-protected:
-    virtual void SetUp() {
-    }
-
-    virtual void TearDown() {
-    }
-};
-
-TEST_F(ZipFileROTest, ZipTimeConvertSuccess) {
-    struct tm t;
-
-    // 2011-06-29 14:40:40
-    long when = 0x3EDD7514;
-
-    ZipFileRO::zipTimeToTimespec(when, &t);
-
-    EXPECT_EQ(2011, t.tm_year + 1900)
-            << "Year was improperly converted.";
-
-    EXPECT_EQ(6, t.tm_mon)
-            << "Month was improperly converted.";
-
-    EXPECT_EQ(29, t.tm_mday)
-            << "Day was improperly converted.";
-
-    EXPECT_EQ(14, t.tm_hour)
-            << "Hour was improperly converted.";
-
-    EXPECT_EQ(40, t.tm_min)
-            << "Minute was improperly converted.";
-
-    EXPECT_EQ(40, t.tm_sec)
-            << "Second was improperly converted.";
-}
-
-}
