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