Home | History | Annotate | Download | only in wrapsim
      1 /*
      2  * Copyright 2009 The Android Open Source Project
      3  *
      4  * Magic entries in /sys/power/.
      5  */
      6 #include "Common.h"
      7 
      8 #include <stdlib.h>
      9 #include <string.h>
     10 #include <ctype.h>
     11 
     12 /*
     13  * Map filename to device index.
     14  *
     15  * [ not using DeviceIndex -- would be useful if we need to return something
     16  * other than a static string ]
     17  */
     18 static const struct {
     19     const char*     name;
     20     //DeviceIndex     idx;
     21     const char*     data;
     22 } gDeviceMap[] = {
     23     { "state",
     24         "mem\n" },
     25     { "wake_lock",
     26         "\n" },
     27     { "wake_unlock",
     28         "KeyEvents PowerManagerService radio-interface\n" },
     29 };
     30 
     31 /*
     32  * Power driver state.
     33  *
     34  * Right now we just ignore everything written.
     35  */
     36 typedef struct PowerState {
     37     int         which;
     38 } PowerState;
     39 
     40 
     41 /*
     42  * Figure out who we are, based on "pathName".
     43  */
     44 static void configureInitialState(const char* pathName, PowerState* powerState)
     45 {
     46     const char* cp = pathName + strlen("/sys/power/");
     47     int i;
     48 
     49     powerState->which = -1;
     50     for (i = 0; i < (int) (sizeof(gDeviceMap) / sizeof(gDeviceMap[0])); i++) {
     51         if (strcmp(cp, gDeviceMap[i].name) == 0) {
     52             powerState->which = i;
     53             break;
     54         }
     55     }
     56 
     57     if (powerState->which == -1) {
     58         wsLog("Warning: access to unknown power device '%s'\n", pathName);
     59         return;
     60     }
     61 }
     62 
     63 /*
     64  * Free up the state structure.
     65  */
     66 static void freeState(PowerState* powerState)
     67 {
     68     free(powerState);
     69 }
     70 
     71 /*
     72  * Read data from the device.
     73  *
     74  * We don't try to keep track of how much was read -- existing clients just
     75  * try to read into a large buffer.
     76  */
     77 static ssize_t readPower(FakeDev* dev, int fd, void* buf, size_t count)
     78 {
     79     PowerState* state = (PowerState*) dev->state;
     80     int dataLen;
     81 
     82     wsLog("%s: read %d\n", dev->debugName, count);
     83 
     84     if (state->which < 0 ||
     85         state->which >= (int) (sizeof(gDeviceMap)/sizeof(gDeviceMap[0])))
     86     {
     87         return 0;
     88     }
     89 
     90     const char* data = gDeviceMap[state->which].data;
     91     size_t strLen = strlen(data);
     92 
     93     while(strLen == 0)
     94         sleep(10); // block forever
     95 
     96     ssize_t copyCount = (strLen < count) ? strLen : count;
     97     memcpy(buf, data, copyCount);
     98     return copyCount;
     99 }
    100 
    101 /*
    102  * Ignore the request.
    103  */
    104 static ssize_t writePower(FakeDev* dev, int fd, const void* buf, size_t count)
    105 {
    106     wsLog("%s: write %d bytes\n", dev->debugName, count);
    107     return count;
    108 }
    109 
    110 /*
    111  * Free up our state before closing down the fake descriptor.
    112  */
    113 static int closePower(FakeDev* dev, int fd)
    114 {
    115     freeState((PowerState*)dev->state);
    116     dev->state = NULL;
    117     return 0;
    118 }
    119 
    120 /*
    121  * Open a power device.
    122  */
    123 FakeDev* wsOpenSysPower(const char* pathName, int flags)
    124 {
    125     FakeDev* newDev = wsCreateFakeDev(pathName);
    126     if (newDev != NULL) {
    127         newDev->read = readPower;
    128         newDev->write = writePower;
    129         newDev->ioctl = NULL;
    130         newDev->close = closePower;
    131 
    132         PowerState* powerState = calloc(1, sizeof(PowerState));
    133 
    134         configureInitialState(pathName, powerState);
    135         newDev->state = powerState;
    136     }
    137 
    138     return newDev;
    139 }
    140 
    141