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 */
configureInitialState(const char * pathName,PowerState * powerState)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 */
freeState(PowerState * powerState)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 */
readPower(FakeDev * dev,int fd,void * buf,size_t count)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 */
writePower(FakeDev * dev,int fd,const void * buf,size_t count)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 */
closePower(FakeDev * dev,int fd)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 */
wsOpenSysPower(const char * pathName,int flags)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