• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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