1 /*
2 * Copyright (C) 2015-2019 Alibaba Group Holding Limited
3 */
4
5 #include <stdio.h>
6 #include <string.h>
7
8 #include "amp_config.h"
9 #include "amp_defines.h"
10 #include "aos_system.h"
11 #include "be_inl.h"
12
13
14 #define MOD_STR "PM"
15
16 enum {
17 PM_AUTOSLEEP_MODE_NEVER = 0,
18 PM_AUTOSLEEP_MODE_SLEEP,
19 PM_AUTOSLEEP_MODE_DEEP_SLEEP,
20 };
21
22 static void *pm_wakelock;
23 static int pm_autosleep_mode;
24 static int pm_sleep_mode;
25 static int pm_pwrkey_cb_ref;
26
__pm_pwrkey_state_notify(void * args)27 static void __pm_pwrkey_state_notify(void *args)
28 {
29 duk_context *ctx;
30 int state = (int)args;
31 ctx = be_get_context();
32 be_push_ref(ctx, pm_pwrkey_cb_ref);
33 duk_push_int(ctx, state);
34 if (duk_pcall(ctx, 1) != DUK_EXEC_SUCCESS) {
35 amp_console("%s", duk_safe_to_stacktrace(ctx, -1));
36 }
37 duk_pop(ctx);
38 duk_gc(ctx, 0);
39 }
40
__pm_pwrkey_state_cb(int state)41 static void __pm_pwrkey_state_cb(int state)
42 {
43 duk_context *ctx;
44 amp_task_schedule_call(__pm_pwrkey_state_notify, state);
45 }
46
native_pm_autosleep_mode_get(duk_context * ctx)47 static duk_ret_t native_pm_autosleep_mode_get(duk_context *ctx)
48 {
49 duk_push_int(ctx, pm_autosleep_mode);
50 return 1;
51 }
52
native_pm_autosleep_mode_set(duk_context * ctx)53 static duk_ret_t native_pm_autosleep_mode_set(duk_context *ctx)
54 {
55 int ret = -1;
56 int mode;
57
58 if (!duk_is_number(ctx, 0)) {
59 amp_error(MOD_STR, "parameter not number");
60 goto out;
61 }
62
63 mode = duk_get_int(ctx, 0);
64
65 if (aos_system_autosleep(mode) < 0) {
66 amp_error(MOD_STR, "set autosleep mode %d fail", mode);
67 goto out;
68 }
69 pm_autosleep_mode = mode;
70 ret = 0;
71
72 out:
73 duk_push_int(ctx, ret);
74 return 1;
75 }
76
native_pm_sleep(duk_context * ctx)77 static duk_ret_t native_pm_sleep(duk_context *ctx)
78 {
79 int ret = -1;
80
81 if (aos_system_sleep()) {
82 amp_error(MOD_STR, "pm suspend fail");
83 goto out;
84 }
85 ret = 0;
86
87 out:
88 duk_push_int(ctx, ret);
89 return 1;
90 }
91
native_pm_wakelock_lock(duk_context * ctx)92 static duk_ret_t native_pm_wakelock_lock(duk_context *ctx)
93 {
94 int ret = -1;
95 void *w = pm_wakelock;
96
97 if (!w) {
98 goto out;
99 }
100
101 if (aos_wakelock_lock(w) < 0) {
102 amp_error(MOD_STR, "wakelock lock fail");
103 goto out;
104 }
105 ret = 0;
106
107 out:
108 duk_push_int(ctx, ret);
109 return 1;
110 }
111
native_pm_wakelock_timedlock(duk_context * ctx)112 static duk_ret_t native_pm_wakelock_timedlock(duk_context *ctx)
113 {
114 int ret = -1;
115 void *w = pm_wakelock;
116 int msec;
117
118 if (!w) {
119 goto out;
120 }
121
122 if (!duk_is_number(ctx, 0)) {
123 amp_error(MOD_STR, "parameter must be (number)");
124 goto out;
125 }
126
127 msec = duk_get_uint(ctx, 0);
128
129 if (aos_wakelock_timedlock(w, msec) < 0) {
130 amp_error(MOD_STR, "wakelock timedlock fail");
131 goto out;
132 }
133 ret = 0;
134
135 out:
136 duk_push_int(ctx, ret);
137 return 1;
138 }
139
native_pm_wakelock_unlock(duk_context * ctx)140 static duk_ret_t native_pm_wakelock_unlock(duk_context *ctx)
141 {
142 int ret = -1;
143 void *w = pm_wakelock;
144
145 if (!w) {
146 goto out;
147 }
148
149 if (aos_wakelock_unlock(w) < 0) {
150 amp_error(MOD_STR, "wakelock unlock fail");
151 goto out;
152 }
153 ret = 0;
154
155 out:
156 duk_push_int(ctx, ret);
157 return 1;
158 }
159
native_pm_pwrkey_on(duk_context * ctx)160 static duk_ret_t native_pm_pwrkey_on(duk_context *ctx)
161 {
162 int ret = -1;
163
164 if (!duk_is_function(ctx, 0)) {
165 amp_warn(MOD_STR, "parameter must be (function)");
166 goto out;
167 }
168
169 duk_dup(ctx, 0);
170 pm_pwrkey_cb_ref = be_ref(ctx);
171
172 if (aos_pwrkey_notify_register(__pm_pwrkey_state_cb)) {
173 amp_error(MOD_STR, "register event fail");
174 goto out;
175 }
176
177 ret = 0;
178 out:
179 duk_push_int(ctx, ret);
180 return 1;
181 }
182
native_pm_power_down(duk_context * ctx)183 static duk_ret_t native_pm_power_down(duk_context *ctx)
184 {
185 duk_push_int(ctx, 0);
186 aos_power_down();
187 return 1;
188 }
189
native_pm_power_reset(duk_context * ctx)190 static duk_ret_t native_pm_power_reset(duk_context *ctx)
191 {
192 aos_power_reset();
193 duk_push_int(ctx, 0);
194 return 1;
195 }
196
module_pm_register(void)197 void module_pm_register(void)
198 {
199 duk_context *ctx = be_get_context();
200 duk_push_object(ctx);
201
202 pm_wakelock = aos_wakelock_create("PM.wakelock");
203 if (!pm_wakelock) {
204 amp_debug(MOD_STR, "wakelock unsupport");
205 }
206
207 pm_autosleep_mode = PM_AUTOSLEEP_MODE_NEVER;
208
209 AMP_ADD_FUNCTION("setAutosleepMode", native_pm_autosleep_mode_set, 1);
210 AMP_ADD_FUNCTION("getAutosleepMode", native_pm_autosleep_mode_get, 0);
211 AMP_ADD_FUNCTION("sleep", native_pm_sleep, 0);
212 AMP_ADD_FUNCTION("powerDown", native_pm_power_down, 0);
213 AMP_ADD_FUNCTION("powerReset", native_pm_power_reset, 0);
214 AMP_ADD_FUNCTION("wakelockLock", native_pm_wakelock_lock, 0);
215 AMP_ADD_FUNCTION("wakelockUnlock", native_pm_wakelock_unlock, 0);
216 AMP_ADD_FUNCTION("wakelockTimedlock", native_pm_wakelock_timedlock, 1);
217 AMP_ADD_FUNCTION("onPwrkey", native_pm_pwrkey_on, 1);
218
219 duk_put_prop_string(ctx, -2, "PM");
220 }
221
222