Bump version to 0.127
[platform/framework/web/tizen-extensions-crosswalk.git] / power / power_instance_tizen.cc
1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "power/power_instance_tizen.h"
6
7 #include <device.h>
8 #include <glib.h>
9 #include <pmapi.h>
10 #include <vconf.h>
11 #include <string>
12
13 #include "common/picojson.h"
14
15 PowerInstanceMobile::PowerInstanceMobile(PowerEventSource* event_source)
16     : js_listening_to_state_change_(false),
17       event_source_(event_source) {
18   pending_screen_state_change_ = false;
19   pending_screen_state_reply_ = false;
20
21   event_source_->AddListener(this);
22 }
23
24 PowerInstanceMobile::~PowerInstanceMobile() {
25   event_source_->RemoveListener(this);
26 }
27
28 ResourceType getResourceType(const picojson::value& msg,
29                                            bool* error) {
30     int type = msg.get("resource").get<double>();
31     if (type < 0 || type >= ResourceTypeValueCount)
32         *error = true;
33     return static_cast<ResourceType>(type);
34 }
35
36 ResourceState getResourceState(const picojson::value& msg,
37                                              bool* error) {
38     int state = msg.get("state").get<double>();
39     if (state < 0 || state >= ResourceStateValueCount)
40         *error = true;
41     return static_cast<ResourceState>(state);
42 }
43
44 static ResourceState toResourceState(power_state_e pstate) {
45     switch (pstate) {
46     case POWER_STATE_NORMAL:
47       return SCREEN_NORMAL;
48     case POWER_STATE_SCREEN_DIM:
49       return SCREEN_DIM;
50     case POWER_STATE_SCREEN_OFF:
51     default:
52       return SCREEN_OFF;
53     }
54 }
55
56 void PowerInstanceMobile::HandleMessage(const char* message) {
57   picojson::value v;
58
59   std::string err;
60   picojson::parse(v, message, message + strlen(message), &err);
61   if (!err.empty()) {
62     std::cout << "Ignoring message.\n";
63     return;
64   }
65
66   std::string cmd = v.get("cmd").to_str();
67   if (cmd == "PowerRequest") {
68     HandleRequest(v);
69   } else if (cmd == "PowerRelease") {
70     HandleRelease(v);
71   } else if (cmd == "PowerSetScreenBrightness") {
72     // value of -1 means restore to default value.
73     HandleSetScreenBrightness(v);
74   } else if (cmd == "PowerSetScreenEnabled") {
75     HandleSetScreenEnabled(v);
76   } else if (cmd == "SetListenToScreenStateChange") {
77     HandleSetListenToScreenStateChange(v);
78   } else {
79     std::cout << "ASSERT NOT REACHED.\n";
80   }
81 }
82
83 void PowerInstanceMobile::HandleSyncMessage(const char* message) {
84   picojson::value v;
85
86   std::string err;
87   picojson::parse(v, message, message + strlen(message), &err);
88   if (!err.empty()) {
89     std::cout << "Ignoring message.\n";
90     return;
91   }
92
93   std::string cmd = v.get("cmd").to_str();
94   if (cmd == "PowerGetScreenBrightness") {
95     HandleGetScreenBrightness();
96   }  else if (cmd == "PowerGetScreenState") {
97     HandleGetScreenState();
98   } else {
99     std::cout << "ASSERT NOT REACHED.\n";
100   }
101 }
102
103 void PowerInstanceMobile::DispatchScreenStateChangedToJS(
104     ResourceState state) {
105   if (!js_listening_to_state_change_)
106     return;
107
108   picojson::value::object o;
109   o["cmd"] = picojson::value("ScreenStateChanged");
110   o["state"] = picojson::value(static_cast<double>(state));
111
112   picojson::value v(o);
113   PostMessage(v.serialize().c_str());
114 }
115
116 void PowerInstanceMobile::OnPowerStateChanged(power_state_e pstate) {
117   ResourceState state = toResourceState(pstate);
118   pending_screen_state_change_ = false;
119   DispatchScreenStateChangedToJS(state);
120
121   if (pending_screen_state_reply_) {
122     picojson::value::object o;
123     o["state"] = picojson::value(static_cast<double>(state));
124     picojson::value v(o);
125     pending_screen_state_reply_ = false;
126     SendSyncReply(v.serialize().c_str());
127   }
128 }
129
130 void PowerInstanceMobile::HandleRequest(const picojson::value& msg) {
131   bool error = false;
132   // ResourceType is unused in this impl, as the JS API verifies
133   // that resource type and state fit.
134   ResourceState state = getResourceState(msg, &error);
135
136   power_state_e pstate;
137   int pm_state;
138   switch (state) {
139     case CPU_AWAKE:
140     case SCREEN_NORMAL: {
141       pstate = POWER_STATE_NORMAL;
142       pm_state = LCD_NORMAL;
143       break;
144     }
145     case SCREEN_DIM: {
146       pstate = POWER_STATE_SCREEN_DIM;
147       pm_state = LCD_DIM;
148       break;
149     }
150     case SCREEN_BRIGHT: {
151       pstate = POWER_STATE_NORMAL;
152       pm_state = LCD_NORMAL;
153       // FIXME : Set to max brightness when we can call the function properly.
154       break;
155     }
156     case SCREEN_OFF:
157     default:
158       pstate = POWER_STATE_SCREEN_OFF;
159       pm_state = LCD_OFF;
160       break;
161   }
162
163   pm_change_state(pm_state);
164   pm_lock_state(pm_state, GOTO_STATE_NOW, 0);
165   int ret = power_lock_state(pstate, 0);
166   if (ret != 0) {
167     fprintf(stderr, "Can't lock the state of the platform. \n");
168     // FIXME: We need to throw an exception here.
169     return;
170   }
171 }
172
173 void PowerInstanceMobile::HandleRelease(const picojson::value& msg) {
174   bool error = false;
175   ResourceType resource = getResourceType(msg, &error);
176
177   switch (resource) {
178     case SCREEN: {
179       power_unlock_state(POWER_STATE_SCREEN_DIM);
180       power_unlock_state(POWER_STATE_NORMAL);
181       device_set_brightness_from_settings(0);
182       power_state_e pstate = power_get_state();
183       OnPowerStateChanged(pstate);
184       break;
185     }
186     case CPU: {
187       power_unlock_state(POWER_STATE_SCREEN_OFF);
188       break;
189     }
190     default:
191       break;
192   }
193   // FIXME: Check return value and throw exception if needed.
194 }
195
196 void PowerInstanceMobile::HandleSetScreenBrightness(
197         const picojson::value& msg) {
198   double brightness = msg.get("value").get<double>();
199   int maxBrightness;
200   power_wakeup(false);
201   int ret = device_get_max_brightness(0, &maxBrightness);
202   if (ret != 0) {
203     fprintf(stderr, "Can't get the max brightness from the platform. \n");
204     device_set_brightness(0, static_cast<int>(brightness * 100.0));
205   } else {
206     device_set_brightness(0, static_cast<int>(brightness * maxBrightness));
207   }
208 }
209
210 void PowerInstanceMobile::HandleGetScreenState() {
211   if (pending_screen_state_change_) {
212     pending_screen_state_reply_ = true;
213   } else {
214     picojson::value::object o;
215     o["state"] = picojson::value(
216             static_cast<double>(toResourceState(power_get_state())));
217     picojson::value v(o);
218     SendSyncReply(v.serialize().c_str());
219   }
220 }
221
222 void PowerInstanceMobile::HandleGetScreenBrightness() {
223   int platformBrightness;
224   picojson::value::object o;
225
226   int ret = device_get_brightness(0, &platformBrightness);
227   if (ret != 0) {
228     fprintf(stderr, "Can't get the brightness from the platform. \n");
229     o["error"] = picojson::value("Can't get the brightness from the platform.");
230   } else {
231     int maxBrightness;
232     ret = device_get_max_brightness(0, &maxBrightness);
233     if (ret != 0 || maxBrightness <= 0) {
234       fprintf(stderr, "Can't get the max brightness from the platform. \n");
235       maxBrightness = 100;
236     }
237     double brightness = platformBrightness / maxBrightness;
238     o["brightness"] = picojson::value(brightness);
239   }
240   picojson::value v(o);
241   SendSyncReply(v.serialize().c_str());
242 }
243
244 void PowerInstanceMobile::HandleSetScreenEnabled(const picojson::value& msg) {
245   bool is_enabled = msg.get("value").get<bool>();
246   power_state_e current_state = power_get_state();
247   if ((is_enabled && current_state != POWER_STATE_SCREEN_OFF)
248     || (!is_enabled && current_state == POWER_STATE_SCREEN_OFF))
249       return;
250
251   int ret = 0;
252   int new_state = is_enabled ? LCD_NORMAL : LCD_OFF;
253   ret = pm_change_state(new_state);
254   if (ret != 0) {
255     // FIXME: Check return value and throw Unknown exception if needed.
256     return;
257   }
258   pending_screen_state_change_ = true;
259 }
260
261 namespace {
262
263 bool GetBoolFromJSONValue(const picojson::value& v, bool* result) {
264   if (!result || !v.is<bool>())
265     return false;
266   *result = v.get<bool>();
267   return true;
268 }
269
270 }  // namespace
271
272 void PowerInstanceMobile::HandleSetListenToScreenStateChange(
273     const picojson::value& msg) {
274   bool listening = false;
275   if (!GetBoolFromJSONValue(msg.get("value"), &listening))
276     return;
277   js_listening_to_state_change_ = listening;
278 }