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