blob: fa7ae0ad3c80c79887bd4a7f1ba6d10bb603a968 [file] [log] [blame]
Marco Nelissen1b2bd1d2009-04-30 14:11:03 -07001/*
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 */
18static 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 */
36typedef struct PowerState {
37 int which;
38} PowerState;
39
40
41/*
42 * Figure out who we are, based on "pathName".
43 */
44static 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 */
66static 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 */
77static 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 */
104static 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 */
113static 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 */
123FakeDev* 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