auto import from //depot/cupcake/@135843
diff --git a/simulator/wrapsim/DevPower.c b/simulator/wrapsim/DevPower.c
new file mode 100644
index 0000000..b44231b
--- /dev/null
+++ b/simulator/wrapsim/DevPower.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2007 The Android Open Source Project
+ *
+ * Magic entries in /sys/class/power_supply/.
+ */
+#include "Common.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+/*
+ * Map filename to device index.
+ *
+ * [ not using DeviceIndex -- would be useful if we need to return something
+ * other than a static string ]
+ */
+static const struct {
+ const char* name;
+ //DeviceIndex idx;
+ const char* data;
+} gDeviceMap[] = {
+ { "ac/online",
+ "0\n" },
+
+ { "battery/batt_temp",
+ "281\n", },
+ { "battery/batt_vol",
+ "4170\n" },
+ { "battery/capacity",
+ "100\n" },
+ { "battery/health",
+ "Good\n" },
+ { "battery/present",
+ "0\n" },
+ { "battery/status",
+ "Full" },
+ { "battery/technology",
+ "Li-ion\n" },
+
+ { "usb/online",
+ "1\n" },
+};
+
+/*
+ * Power driver state.
+ *
+ * Right now we just ignore everything written.
+ */
+typedef struct PowerState {
+ int which;
+} PowerState;
+
+
+/*
+ * Figure out who we are, based on "pathName".
+ */
+static void configureInitialState(const char* pathName, PowerState* powerState)
+{
+ const char* cp = pathName + strlen("/sys/class/power_supply/");
+ int i;
+
+ powerState->which = -1;
+ for (i = 0; i < (int) (sizeof(gDeviceMap) / sizeof(gDeviceMap[0])); i++) {
+ if (strcmp(cp, gDeviceMap[i].name) == 0) {
+ powerState->which = i;
+ break;
+ }
+ }
+
+ if (powerState->which == -1) {
+ wsLog("Warning: access to unknown power device '%s'\n", pathName);
+ return;
+ }
+}
+
+/*
+ * Free up the state structure.
+ */
+static void freeState(PowerState* powerState)
+{
+ free(powerState);
+}
+
+/*
+ * Read data from the device.
+ *
+ * We don't try to keep track of how much was read -- existing clients just
+ * try to read into a large buffer.
+ */
+static ssize_t readPower(FakeDev* dev, int fd, void* buf, size_t count)
+{
+ PowerState* state = (PowerState*) dev->state;
+ int dataLen;
+
+ wsLog("%s: read %d\n", dev->debugName, count);
+
+ if (state->which < 0 ||
+ state->which >= (int) (sizeof(gDeviceMap)/sizeof(gDeviceMap[0])))
+ {
+ return 0;
+ }
+
+ const char* data = gDeviceMap[state->which].data;
+ size_t strLen = strlen(data);
+
+ while(strLen == 0)
+ sleep(10); // block forever
+
+ ssize_t copyCount = (strLen < count) ? strLen : count;
+ memcpy(buf, data, copyCount);
+ return copyCount;
+}
+
+/*
+ * Ignore the request.
+ */
+static ssize_t writePower(FakeDev* dev, int fd, const void* buf, size_t count)
+{
+ wsLog("%s: write %d bytes\n", dev->debugName, count);
+ return count;
+}
+
+/*
+ * Our Java classes want to be able to do ioctl(FIONREAD) on files. The
+ * battery power manager is blowing up if we get an error other than
+ * ENOTTY (meaning a device that doesn't understand buffering).
+ */
+static int ioctlPower(FakeDev* dev, int fd, int request, void* argp)
+{
+ if (request == FIONREAD) {
+ wsLog("%s: ioctl(FIONREAD, %p)\n", dev->debugName, argp);
+ errno = ENOTTY;
+ return -1;
+ } else {
+ wsLog("%s: ioctl(0x%08x, %p) ??\n", dev->debugName, request, argp);
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+/*
+ * Free up our state before closing down the fake descriptor.
+ */
+static int closePower(FakeDev* dev, int fd)
+{
+ freeState((PowerState*)dev->state);
+ dev->state = NULL;
+ return 0;
+}
+
+/*
+ * Open a power device.
+ */
+FakeDev* wsOpenDevPower(const char* pathName, int flags)
+{
+ FakeDev* newDev = wsCreateFakeDev(pathName);
+ if (newDev != NULL) {
+ newDev->read = readPower;
+ newDev->write = writePower;
+ newDev->ioctl = ioctlPower;
+ newDev->close = closePower;
+
+ PowerState* powerState = calloc(1, sizeof(PowerState));
+
+ configureInitialState(pathName, powerState);
+ newDev->state = powerState;
+ }
+
+ return newDev;
+}
+