power: Remove duplicate operation
[platform/core/system/deviced.git] / src / power / power.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <stdio.h>
20 #include <stdint.h>
21 #include <assert.h>
22 #include <inttypes.h>
23 #include <linux/input.h>
24 #include <libsyscommon/libgdbus.h>
25 #include <libsyscommon/list.h>
26 #include <libsyscommon/proc.h>
27 #include <device/power-internal.h>
28
29 #include "shared/devices.h"
30 #include "shared/device-notifier.h"
31 #include "shared/log.h"
32 #include "shared/common.h"
33 #include "power.h"
34 #include "power-suspend.h"
35 #include "power-dbus.h"
36 #include "power-boot.h"
37 #include "power-off.h"
38 #include "power-event-lock.h"
39
40 #define POWER_CONF_FILE              "/etc/deviced/power.conf"
41 #define DEFAULT_MAX_WAIT_SECOND      5 /* second */
42 #define MAX_DESC_LEN                 256
43 #define TRANSITION_CONFIRM           0
44 #define TRANSITION_CANCEL            1
45
46 static int delayed_init_done = 0;
47 static uint64_t current = DEVICED_POWER_STATE_START; /* current power state */
48 static int max_wait_timeout = DEFAULT_MAX_WAIT_SECOND;
49 static GQueue *transition_queue;
50 static struct {
51         uint64_t id;
52         int ongoing;
53         struct syscommon_plugin_deviced_power_trans_info ti;
54         GList *waitings;
55         int transient_step;
56         int max_wait_timer;
57         /**
58          * If the cancel is set during a transition,
59          * undo the transition instead of doing action
60          * on reaching the destination state.
61          */
62         int cancel;
63 } transition_context;
64
65 struct proc_info {
66         pid_t pid;
67         char comm[128];
68         guint64 state_bitmap;
69 };
70 static GList *proc_list;
71
72 struct change_state_wait {
73         struct proc_info *pi;
74         guint64 transition_id;
75         int state;
76 };
77
78 static const uint64_t transient_scenario_suspending[] = {
79         DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_EARLY,
80         DEVICED_POWER_TRANSIENT_STATE_SUSPENDING,
81         DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_LATE,
82 };
83
84 static const uint64_t transient_scenario_resuming[] = {
85         DEVICED_POWER_TRANSIENT_STATE_RESUMING_EARLY,
86         DEVICED_POWER_TRANSIENT_STATE_RESUMING,
87         DEVICED_POWER_TRANSIENT_STATE_RESUMING_LATE,
88 };
89
90 static const struct {
91         int max_step;
92         const uint64_t *scenario;
93 } transient[DEVICED_POWER_STATE_MAX_INDEX][DEVICED_POWER_STATE_MAX_INDEX] = {
94         [DEVICED_POWER_STATE_START_INDEX][DEVICED_POWER_STATE_SLEEP_INDEX] = {
95                 .max_step = ARRAY_SIZE(transient_scenario_suspending),
96                 .scenario = transient_scenario_suspending,
97         },
98         [DEVICED_POWER_STATE_NORMAL_INDEX][DEVICED_POWER_STATE_SLEEP_INDEX] = {
99                 .max_step = ARRAY_SIZE(transient_scenario_suspending),
100                 .scenario = transient_scenario_suspending,
101         },
102         [DEVICED_POWER_STATE_SLEEP_INDEX][DEVICED_POWER_STATE_NORMAL_INDEX] = {
103                 .max_step = ARRAY_SIZE(transient_scenario_resuming),
104                 .scenario = transient_scenario_resuming,
105         },
106 };
107
108 static int transition_request_callback(void *data);
109 static void prepare_transition(const struct syscommon_plugin_deviced_power_trans_info *ti);
110 static void action_transition(void);
111 static uint64_t get_next_state(void);
112
113 static void pre_action_normal(const void *data);
114 static void pre_action_poweroff(const void *data);
115 static void (*const pre_action_state[DEVICED_POWER_STATE_MAX_INDEX]) (const void *) = {
116         [DEVICED_POWER_STATE_NORMAL_INDEX]   = pre_action_normal,
117         [DEVICED_POWER_STATE_POWEROFF_INDEX] = pre_action_poweroff,
118         [DEVICED_POWER_STATE_REBOOT_INDEX]   = pre_action_poweroff,
119         [DEVICED_POWER_STATE_EXIT_INDEX]     = pre_action_poweroff,
120 };
121
122 static void post_action_sleep(const void *data);
123 static void post_action_poweroff(const void *data);
124 static void (*const post_action_state[DEVICED_POWER_STATE_MAX_INDEX]) (const void *) = {
125         [DEVICED_POWER_STATE_SLEEP_INDEX]    = post_action_sleep,
126         [DEVICED_POWER_STATE_POWEROFF_INDEX] = post_action_poweroff,
127         [DEVICED_POWER_STATE_REBOOT_INDEX]   = post_action_poweroff,
128         [DEVICED_POWER_STATE_EXIT_INDEX]     = post_action_poweroff,
129 };
130
131
132 uint64_t power_get_state(void)
133 {
134         return current;
135 }
136
137 static void cleanup_waiting_list(gpointer data)
138 {
139         struct change_state_wait *csw = (struct change_state_wait *) data;
140
141         _E("%s(pid=%d) hasn't confirmed id=%"PRIu64"(%s)",
142                 csw->pi->comm, csw->pi->pid, csw->transition_id, state_name(csw->state));
143
144         if (kill(csw->pi->pid, 0) != 0) {
145                 _E("cleanup not existing process: %s(pid=%d)", csw->pi->comm, csw->pi->pid);
146                 proc_list = g_list_remove(proc_list, csw->pi);
147                 free(csw->pi);
148         }
149
150         free(csw);
151 }
152
153 static gboolean max_wait_expired_cb(void *data)
154 {
155         transition_context.max_wait_timer = 0;
156
157         g_list_free_full(g_steal_pointer(&transition_context.waitings), cleanup_waiting_list);
158
159         action_transition();
160
161         return G_SOURCE_REMOVE;
162 }
163
164 static gint find_pi_by_pid(gconstpointer data, gconstpointer udata)
165 {
166         const struct proc_info *pi = (const struct proc_info *) data;
167         const pid_t pid = *(const pid_t *) udata;
168
169         if (pi->pid == pid)
170                 return 0;
171
172         return -1;
173 }
174
175 int add_change_state_wait(pid_t pid, guint64 state)
176 {
177         struct proc_info *pi = NULL;
178         GList *l = NULL;
179
180         l = g_list_find_custom(proc_list, &pid, find_pi_by_pid);
181         if (l && l->data) {
182                 pi = l->data;
183                 pi->state_bitmap |= state;
184                 _D("pid=%d(%s) updated csw for %#"PRIx64, pi->pid, pi->comm, state);
185                 return 0;
186         }
187
188         pi = calloc(1, sizeof(struct proc_info));
189         if (!pi)
190                 return -ENOMEM;
191
192         pi->pid = pid;
193         pi->state_bitmap = state;
194         syscommon_proc_get_comm(pid, pi->comm, sizeof(pi->comm));
195         proc_list = g_list_append(proc_list, pi);
196
197         _D("pid=%d(%s) added csw for %#"PRIx64, pid, pi->comm, state);
198
199         return 0;
200 }
201
202 void remove_change_state_wait(pid_t pid, guint64 state)
203 {
204         struct proc_info *pi = NULL;
205         GList *l = NULL;
206
207         l = g_list_find_custom(proc_list, &pid, find_pi_by_pid);
208         if (!l)
209                 return;
210
211         if (!l->data)
212                 return;
213
214         pi = l->data;
215
216         _D("pid=%d(%s) removed csw for %#"PRIx64, pi->pid, pi->comm, state);
217
218         pi->state_bitmap &= ~state;
219         if (pi->state_bitmap == 0) {
220                 proc_list = g_list_remove_link(proc_list, l);
221                 free(g_steal_pointer(&l->data));
222                 g_list_free(l);
223         }
224 }
225
226 static gint find_csw_by_pid_id(gconstpointer data, gconstpointer udata)
227 {
228         const struct change_state_wait *csw = (const struct change_state_wait *) data;
229         const struct change_state_wait *target = (const struct change_state_wait *) udata;
230
231         if (csw->pi->pid == target->pi->pid && csw->transition_id == target->transition_id)
232                 return 0;
233
234         return -1;
235 }
236
237 static int handle_change_state_wait(pid_t pid, guint64 transition_id, int transition_cancel)
238 {
239         struct proc_info target_pi = { .pid = pid };
240         struct change_state_wait target_csw = { .pi = &target_pi, .transition_id = transition_id };
241         struct change_state_wait *csw = NULL;
242         GList *l = NULL;
243
244         l = g_list_find_custom(transition_context.waitings, &target_csw, find_csw_by_pid_id);
245         if (!l)
246                 return 0;
247
248         if (!l->data)
249                 return 0;
250
251         csw = l->data;
252         if (transition_cancel == TRANSITION_CANCEL)
253                 CRITICAL_LOG("pid=%d(%s) cancelled id=%"PRIu64"(%s)", csw->pi->pid, csw->pi->comm, csw->transition_id, state_name(csw->state));
254         else
255                 _D("pid=%d(%s) confirmed id=%"PRIu64"(%s)", csw->pi->pid, csw->pi->comm, csw->transition_id, state_name(csw->state));
256
257         transition_context.waitings = g_list_remove_link(transition_context.waitings, l);
258         free(g_steal_pointer(&l->data));
259         g_list_free(l);
260
261         // continue waiting
262         if (g_list_length(transition_context.waitings) != 0)
263                 return 0;
264
265         // the last csw is cleared
266         g_source_remove(transition_context.max_wait_timer);
267         transition_context.max_wait_timer = 0;
268
269         action_transition();
270
271         return 0;
272 }
273
274 int confirm_change_state_wait(pid_t pid, guint64 transition_id)
275 {
276         return handle_change_state_wait(pid, transition_id, TRANSITION_CONFIRM);
277 }
278
279 int cancel_change_state_wait(pid_t pid, guint64 transition_id)
280 {
281         /* do not allow cancelling poweroff transition */
282         if (is_poweroff_state(transition_context.ti.next))
283                 return handle_change_state_wait(pid, transition_id, TRANSITION_CONFIRM);
284
285         transition_context.cancel = 1;
286
287         return handle_change_state_wait(pid, transition_id, TRANSITION_CANCEL);
288 }
289
290 static uint64_t alloc_unique_id(void)
291 {
292         static uint64_t id = 0;
293
294         return ++id;
295 }
296
297 static void pre_action_normal(const void *udata)
298 {
299         if (transition_context.ti.curr == DEVICED_POWER_STATE_SLEEP)
300                 power_resume(transition_context.ti.reason);
301 }
302
303 static void post_action_sleep(const void *udata)
304 {
305         power_suspend(transition_context.ti.reason);
306 }
307
308 static void pre_action_poweroff(const void *data)
309 {
310         // do not transition anymore after poweroff
311         syscommon_notifier_unsubscribe_notify(DEVICED_NOTIFIER_REQUEST_TRANSITION_STATE, transition_request_callback);
312         poweroff_prepare(current);
313 }
314
315 static void post_action_poweroff(const void *data)
316 {
317         poweroff_main((void *)(intptr_t) current);
318 }
319
320 static void broadcast_transition_info(void)
321 {
322         uint64_t curr = DEVICED_POWER_STATE_INDEX(transition_context.ti.curr);
323         uint64_t next = DEVICED_POWER_STATE_INDEX(get_next_state());
324
325         assert(DEVICED_POWER_STATE_MIN_INDEX <= curr && curr < DEVICED_POWER_TRANSIENT_STATE_MAX_INDEX);
326         assert(DEVICED_POWER_STATE_MIN_INDEX <= next && next < DEVICED_POWER_TRANSIENT_STATE_MAX_INDEX);
327
328         static const char* mapping_signame[DEVICED_POWER_TRANSIENT_STATE_MAX_INDEX] = {
329                 [DEVICED_POWER_STATE_START_INDEX]    = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_START,
330                 [DEVICED_POWER_STATE_NORMAL_INDEX]   = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_NORMAL,
331                 [DEVICED_POWER_STATE_SLEEP_INDEX]    = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_SLEEP,
332                 [DEVICED_POWER_STATE_POWEROFF_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_POWEROFF,
333                 [DEVICED_POWER_STATE_REBOOT_INDEX]   = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_REBOOT,
334                 [DEVICED_POWER_STATE_EXIT_INDEX]     = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_EXIT,
335                 [DEVICED_POWER_TRANSIENT_STATE_RESUMING_EARLY_INDEX]   = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_RESUMING_EARLY,
336                 [DEVICED_POWER_TRANSIENT_STATE_RESUMING_INDEX]         = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_RESUMING,
337                 [DEVICED_POWER_TRANSIENT_STATE_RESUMING_LATE_INDEX]    = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_RESUMING_LATE,
338                 [DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_EARLY_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_SUSPENDING_EARLY,
339                 [DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_INDEX]       = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_SUSPENDING,
340                 [DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_LATE_INDEX]  = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_SUSPENDING_LATE,
341         };
342
343         // convert deviced state to a correspond device enum
344         static const uint64_t mapping_device_state[DEVICED_POWER_TRANSIENT_STATE_MAX_INDEX] = {
345                 [DEVICED_POWER_STATE_START_INDEX]     = DEVICE_POWER_STATE_START,
346                 [DEVICED_POWER_STATE_NORMAL_INDEX]    = DEVICE_POWER_STATE_NORMAL,
347                 [DEVICED_POWER_STATE_SLEEP_INDEX]     = DEVICE_POWER_STATE_SLEEP,
348                 [DEVICED_POWER_STATE_POWEROFF_INDEX]  = DEVICE_POWER_STATE_POWEROFF,
349                 [DEVICED_POWER_STATE_REBOOT_INDEX]    = DEVICE_POWER_STATE_REBOOT,
350                 [DEVICED_POWER_STATE_EXIT_INDEX]      = DEVICE_POWER_STATE_EXIT,
351                 [DEVICED_POWER_TRANSIENT_STATE_RESUMING_EARLY_INDEX]   = DEVICE_POWER_TRANSIENT_STATE_RESUMING_EARLY,
352                 [DEVICED_POWER_TRANSIENT_STATE_RESUMING_INDEX]         = DEVICE_POWER_TRANSIENT_STATE_RESUMING,
353                 [DEVICED_POWER_TRANSIENT_STATE_RESUMING_LATE_INDEX]    = DEVICE_POWER_TRANSIENT_STATE_RESUMING_LATE,
354                 [DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_EARLY_INDEX] = DEVICE_POWER_TRANSIENT_STATE_SUSPENDING_EARLY,
355                 [DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_INDEX]       = DEVICE_POWER_TRANSIENT_STATE_SUSPENDING,
356                 [DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_LATE_INDEX]  = DEVICE_POWER_TRANSIENT_STATE_SUSPENDING_LATE,
357         };
358
359         gdbus_signal_emit(NULL, DEVICED_PATH_POWER, DEVICED_INTERFACE_POWER, mapping_signame[next],
360                 g_variant_new("(ttti)",
361                         mapping_device_state[curr],
362                         mapping_device_state[next],
363                         transition_context.id,
364                         transition_context.ti.reason));
365 }
366
367 int is_there_pending_transition(void)
368 {
369         return (g_queue_peek_tail(transition_queue) != NULL);
370 }
371
372 static uint64_t available_starting_state(void)
373 {
374         struct syscommon_plugin_deviced_power_trans_info *ti = NULL;
375
376         // If there is pending transition,
377         // the available state is the last state of pendiong transitions.
378         ti = g_queue_peek_head(transition_queue);
379         if (ti)
380                 return ti->next;
381
382         // If a transition is underway and there is no other queued transitions,
383         // the available state is the destination of the ongoing transition.
384         // Otherwise, if there neither ongoing nor queued transitions are,
385         // the available state is the current state.
386         return transition_context.ongoing ? transition_context.ti.next : current;
387 }
388
389 static int dequeue_transition(struct syscommon_plugin_deviced_power_trans_info *ti)
390 {
391         struct syscommon_plugin_deviced_power_trans_info *tail = NULL;
392
393         tail = g_queue_pop_tail(transition_queue);
394         if (!tail)
395                 return -1;
396
397         if (ti)
398                 *ti = *tail;
399
400         free(tail);
401
402         return 0;
403 }
404
405 static void enqueue_transition(const struct syscommon_plugin_deviced_power_trans_info *ti)
406 {
407         struct syscommon_plugin_deviced_power_trans_info *ti_new = NULL;
408
409         if (!ti)
410                 return;
411
412         ti_new = calloc(1, sizeof(struct syscommon_plugin_deviced_power_trans_info));
413         if (!ti_new)
414                 return;
415
416         *ti_new = *ti;
417
418         g_queue_push_head(transition_queue, ti_new);
419 }
420
421 // intermediate state of ongoing transition
422 // it might be a transient state or a destination state
423 static uint64_t get_next_state(void)
424 {
425         int curr = DEVICED_POWER_STATE_INDEX(transition_context.ti.curr);
426         int next = DEVICED_POWER_STATE_INDEX(transition_context.ti.next);
427         int step = transition_context.transient_step;
428
429         if (step >= transient[curr][next].max_step)
430                 return transition_context.ti.next;
431         else
432                 return transient[curr][next].scenario[step];
433 }
434
435 static void init_waiting_list(gpointer data, gpointer udata)
436 {
437         uint64_t waiting_state;
438         struct proc_info *pi = (struct proc_info *) data;
439         struct change_state_wait *csw = NULL;
440
441         waiting_state = get_next_state();
442
443         if ((pi->state_bitmap & waiting_state) == 0)
444                 return;
445
446         csw = calloc(1, sizeof(struct change_state_wait));
447         if (!csw)
448                 return;
449
450         *csw = (struct change_state_wait) {
451                 .pi = pi,
452                 .transition_id = transition_context.id,
453                 .state = waiting_state,
454         };
455
456         *(int *) udata += 1;
457
458         transition_context.waitings = g_list_append(transition_context.waitings, csw);
459 }
460
461 static char *state_abbr_name(uint64_t state)
462 {
463         if (state == DEVICED_POWER_STATE_START)
464                 return "START";
465         if (state == DEVICED_POWER_STATE_NORMAL)
466                 return "NORMAL";
467         if (state == DEVICED_POWER_STATE_SLEEP)
468                 return "SLEEP";
469         if (state == DEVICED_POWER_STATE_POWEROFF)
470                 return "POWEROFF";
471         if (state == DEVICED_POWER_STATE_REBOOT)
472                 return "REBOOT";
473         if (state == DEVICED_POWER_STATE_EXIT)
474                 return "EXIT";
475         if (state == DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_EARLY)
476                 return "SUSPENDING_EARLY";
477         if (state == DEVICED_POWER_TRANSIENT_STATE_SUSPENDING)
478                 return "SUSPENDING";
479         if (state == DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_LATE)
480                 return "SUSPENDING_LATE";
481         if (state == DEVICED_POWER_TRANSIENT_STATE_RESUMING_EARLY)
482                 return "RESUMING_EARLY";
483         if (state == DEVICED_POWER_TRANSIENT_STATE_RESUMING)
484                 return "RESUMING";
485         if (state == DEVICED_POWER_TRANSIENT_STATE_RESUMING_LATE)
486                 return "RESUMING_LATE";
487
488         return "INVALID";
489 }
490
491 static void reload_transition_sequence(GList **sequence)
492 {
493         GList *new_sequence = NULL;
494         int curr, next, step;
495
496         g_list_free(g_steal_pointer(sequence));
497
498         curr = DEVICED_POWER_STATE_INDEX(transition_context.ti.curr);
499         next = DEVICED_POWER_STATE_INDEX(transition_context.ti.next);
500
501         new_sequence = g_list_append(new_sequence, state_abbr_name(transition_context.ti.curr));
502         for (step = 0; step < transient[curr][next].max_step; ++step)
503                 new_sequence = g_list_append(new_sequence, state_abbr_name(transient[curr][next].scenario[step]));
504         new_sequence = g_list_append(new_sequence, state_abbr_name(transition_context.ti.next));
505
506         *sequence = new_sequence;
507 }
508
509 static const char* build_description(GList *sequence, const int seqnum)
510 {
511         static char buffer[MAX_DESC_LEN] = { 0, };
512         char *head = buffer;
513         // leave 1 byte for terminating null character
514         char *const tail = buffer + sizeof(buffer) - 1;
515
516         // additional (length-1) placeholders for transitioning arrow between each state
517         int max_sequence = g_list_length(sequence) * 2 - 1;
518
519         GList *iter = sequence;
520         int n = 0;
521
522         memset(buffer, 0, sizeof(buffer));
523
524         while (iter) {
525                 GList *next = iter->next;
526
527                 if (n == seqnum)
528                         head += snprintf(head, tail - head, "[%s] ", (const char *) iter->data);
529                 else
530                         head += snprintf(head, tail - head, " %s  ", (const char *) iter->data);
531
532                 if (head >= tail)
533                         break;
534
535                 ++n;
536                 if (n >= max_sequence)
537                         break;
538
539                 if (n == seqnum)
540                         head += snprintf(head, tail - head, "[=>] ");
541                 else
542                         head += snprintf(head, tail - head, " =>  ");
543
544                 if (head >= tail)
545                         break;
546
547                 ++n;
548                 iter = next;
549         }
550
551         return buffer;
552 }
553
554 static void transition_description(int reload)
555 {
556         static GList *transition_sequence = NULL;
557         static int seqnum = 0;
558
559         if (reload) {
560                 seqnum = 0;
561                 reload_transition_sequence(&transition_sequence);
562         }
563
564         _D("%s", build_description(transition_sequence, seqnum++));
565 }
566
567 static void trigger_transition(void)
568 {
569         int waiting = 0;
570
571         assert(current != DEVICED_POWER_STATE_POWEROFF);
572         assert(current != DEVICED_POWER_STATE_REBOOT);
573         assert(current != DEVICED_POWER_STATE_EXIT);
574         assert(transition_context.max_wait_timer == 0);
575
576         transition_context.id = alloc_unique_id();
577
578         if (!transition_context.ongoing) {
579                 // hold secondary wakelock not to fall asleep during transition
580                 event_wake_lock(EL_POWER_TRANSITION_STATE);
581                 transition_context.ongoing = 1;
582         }
583
584         transition_description(0);
585
586         broadcast_transition_info();
587         g_list_foreach(proc_list, init_waiting_list, &waiting);
588         if (waiting > 0)
589                 transition_context.max_wait_timer = g_timeout_add_seconds(max_wait_timeout, max_wait_expired_cb, NULL);
590         else
591                 action_transition();
592 }
593
594 static void cancel_transition(void)
595 {
596         struct syscommon_plugin_deviced_power_trans_info *ti = NULL;
597
598         struct syscommon_plugin_deviced_power_trans_info poweroff = { .next = DEVICED_POWER_STATE_UNDEFINED };
599         struct syscommon_plugin_deviced_power_trans_info undo = {
600                 .curr = transition_context.ti.next,
601                 .next = transition_context.ti.curr,
602                 /**
603                  * TODO: Is it needed that a reason for this cancelling transition, such as
604                  *       DEVICE_POWER_TRANSITION_REASON_CANCEL_TRANSITION. Or use the previous
605                  *       reason as it is?
606                  */
607                 .reason = transition_context.ti.reason,
608                 .data = transition_context.ti.data,
609         };
610
611         assert(transition_context.ongoing);
612         assert(transition_context.cancel);
613
614         /**
615          * Discard all pending transitions except transition to the poweroff/reboot/exit state.
616          * Transition to the powerff/reboot/exit must remain intact in any case.
617          */
618         while ((ti = g_queue_peek_tail(transition_queue))) {
619                 if (is_poweroff_state(ti->next)) {
620                         /**
621                          * Save the transition.
622                          *
623                          * Fix the poweroff.curr to next of the previous one. This is because the transition_queue always
624                          * manage its entries be chaining each other by matching those previous and next state in order.
625                          */
626                         dequeue_transition(&poweroff);
627                         poweroff.curr = undo.next;
628                 } else {
629                         /* Discard the transition */
630                         CRITICAL_LOG("Discard pending transition, curr=%s, next=%s, reason=%d",
631                                 state_abbr_name(ti->curr), state_abbr_name(ti->next), ti->reason);
632                         dequeue_transition(NULL);
633                 }
634         }
635
636         /* Reserve transition for undoing. */
637         enqueue_transition(&undo);
638         /* Reserve transition for poweroff. */
639         if (is_poweroff_state(poweroff.next))
640                 enqueue_transition(&poweroff);
641 }
642
643 static void action_transition(void)
644 {
645         uint64_t state = get_next_state();
646         struct syscommon_plugin_deviced_power_trans_info ti = { 0 , };
647         int retval;
648         int index;
649
650         transition_description(0);
651
652         if (state != transition_context.ti.next) {
653                 // step into the next transient state
654                 ++transition_context.transient_step;
655                 trigger_transition();
656                 return;
657         }
658
659         /* it reached the destination state */
660         index = DEVICED_POWER_STATE_INDEX(transition_context.ti.next);
661         if (transition_context.cancel) {
662                 cancel_transition();
663                 goto trigger_next;
664         }
665
666         if (pre_action_state[index])
667                 pre_action_state[index](transition_context.ti.data);
668
669         current = transition_context.ti.next;
670
671         if (post_action_state[index])
672                 post_action_state[index](transition_context.ti.data);
673
674 trigger_next:
675         /**
676          * transition_context.ongiong must be reset after the post_action_state().
677          * This prevents the post_action_state() from triggering another transition
678          * that might have been requested during its execution. Transition will be
679          * enqueued, not executed, if transition_context.ongoing is 1.
680          */
681         transition_context.ongoing = 0;
682         event_wake_unlock(EL_POWER_TRANSITION_STATE);
683
684         retval = dequeue_transition(&ti);
685         if (retval == 0) {
686                 prepare_transition(&ti);
687                 trigger_transition();
688         }
689 }
690
691 static void prepare_transition(const struct syscommon_plugin_deviced_power_trans_info *ti)
692 {
693         assert(transition_context.waitings == NULL);
694         assert(transition_context.max_wait_timer == 0);
695
696         if (ti) {
697                 transition_context.ti = (struct syscommon_plugin_deviced_power_trans_info) {
698                         .curr = ti->curr,
699                         .next = ti->next,
700                         .reason = ti->reason,
701                         .data = ti->data,
702                 };
703         }
704
705         transition_context.ongoing = 0;
706         transition_context.transient_step = 0;
707         transition_context.cancel = 0;
708
709         transition_description(1);
710 }
711
712 static gint find_ti_by_state(gconstpointer data, gconstpointer udata)
713 {
714         const struct syscommon_plugin_deviced_power_trans_info *ti =
715                 (const struct syscommon_plugin_deviced_power_trans_info *) data;
716         const uint64_t state = *(const uint64_t *) udata;
717
718         if (ti->curr & state)
719                 return 0;
720
721         return -1;
722 }
723
724 static int transition_request_callback(void *data)
725 {
726         GList *ti_list, *l;
727         const struct syscommon_plugin_deviced_power_trans_info *t = NULL;
728         struct syscommon_plugin_deviced_power_trans_info ti = { 0 , };
729         uint64_t available;
730
731         if (!data)
732                 return 0;
733
734         available = available_starting_state();
735
736         ti_list = (GList *) data;
737
738         l = g_list_find_custom(ti_list, &available, find_ti_by_state);
739         if (!l)
740                 return 0;
741
742         if (!l->data)
743                 return 0;
744
745         t = l->data;
746
747         // check invalid next state
748         if (__builtin_popcountll(t->next & DEVICED_POWER_STATE_ALL) != 1) {
749                 _E("Invalid next state, curr=%"PRIx64", next=%"PRIx64", reason=%d", t->curr, t->next, t->reason);
750                 return 0;
751         }
752
753         ti = (struct syscommon_plugin_deviced_power_trans_info) {
754                 .curr = available,
755                 .next = t->next,
756                 .reason = t->reason,
757                 .data = t->data,
758         };
759
760         // TODO: immediate handling of poweroff?
761
762         if (!delayed_init_done || transition_context.ongoing) {
763                 // Processes starting later than the deviced wanted to be informed
764                 // about power transition that has happend before the process start. To
765                 // this end, all transitions are delayed after the delayed_init_callback(),
766                 // which is called on completing delayed.target. Therefore it is guaranteed
767                 // that all processes that starts before delayed.target can receieve all
768                 // power transition information.
769                 enqueue_transition(&ti);
770                 return 0;
771         }
772
773         prepare_transition(&ti);
774         trigger_transition();
775
776         return 0;
777 }
778
779 static int delayed_init_callback(void *data)
780 {
781         int retval;
782         struct syscommon_plugin_deviced_power_trans_info ti = { 0 , };
783
784         delayed_init_done = 1;
785
786         _D("Start deferred state transition.");
787
788         retval = dequeue_transition(&ti);
789         if (retval == 0) {
790                 prepare_transition(&ti);
791                 trigger_transition();
792         }
793
794         power_init_autosleep();
795
796         return 0;
797 }
798
799 static int load_max_wait_timeout(struct parse_result *result, void *user_data)
800 {
801         if (MATCH(result->section, "PowerState")
802                 && MATCH(result->name, "ChangeStateMaxWaitSecond"))
803                 max_wait_timeout = atoi(result->value);
804
805         return 0;
806 }
807
808 void power_state_init(void *data)
809 {
810         int ret;
811         transition_queue = g_queue_new();
812
813         ret = config_parse(POWER_CONF_FILE, load_max_wait_timeout, NULL);
814         if (ret < 0)
815                 _W("Failed to load '%s'(%d)", POWER_CONF_FILE, ret);
816
817         syscommon_notifier_subscribe_notify(DEVICED_NOTIFIER_DELAYED_INIT, delayed_init_callback);
818         syscommon_notifier_subscribe_notify(DEVICED_NOTIFIER_REQUEST_TRANSITION_STATE, transition_request_callback);
819
820         power_dbus_init();
821         power_off_init();
822         power_suspend_init();
823         power_event_lock_init();
824
825         /* Take the first transition.
826          *
827          * It is determined by bootreason and bootmode to which state to transition, DEVICED_POWER_STATE_NORMAL
828          * or DEVICED_POWER_STATE_SLEEP. it may stay in DEVICED_POWER_STATE_START if there is no defined action for the
829          * matching bootreason and bootmode.
830          */
831         initial_transition_by_boot_condition();
832 }
833
834 static const struct device_ops power_state_device_ops = {
835         DECLARE_NAME_LEN("power-state"),
836         .init              = power_state_init,
837         /* It should be initilalized earlier than the almost other modules so that
838          * it can receive and handle power request from the other modules. Therefore
839          * give a high enough priority. */
840         .priority          = 990,
841 };
842
843 DEVICE_OPS_REGISTER(&power_state_device_ops)