wrt-plugins-tizen_0.4.23
[framework/web/wrt-plugins-tizen.git] / src / Power / PowerManager.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include "PowerManager.h"
19 #include <cstring>
20 #include <power.h>
21 #include <pmapi.h>
22 #include <device.h>
23 #include <algorithm>
24 #include <PlatformException.h>
25 #include <JSUtil.h>
26 #include <vconf.h>
27 #include <Logger.h>
28
29 using namespace DeviceAPI::Common;
30 using namespace std;
31
32 namespace DeviceAPI {
33 namespace Power {
34
35 PowerResource::PowerResource(const char *resource)
36 {
37     if( strcmp(resource,"SCREEN") == 0 )
38         mType = SCREEN;
39     else if( strcmp(resource,"CPU") == 0 )
40        mType = CPU;
41     else
42        throw TypeMismatchException("value is not PowerResource type");
43 };
44
45 const std::string PowerResource::toString(){
46     static const char *table[] = {"SCREEN", "CPU"};
47     return std::string(table[mType]);
48 }
49
50
51 PowerState::PowerState(const char *str)
52 {
53     static const char *table[] = { "SCREEN_OFF", "SCREEN_DIM", "SCREEN_NORMAL", "SCREEN_BRIGHT", "CPU_AWAKE"};
54     static state state_table[] = { SCREENOFF, SCREENDIM, SCREENNORMAL, SCREENBRIGHT, CPUAWAKE };
55     for(unsigned int i =0; i < sizeof(table)/sizeof(char*) ; i++){
56         if( strcmp(str, table[i]) == 0 ){
57             mState = state_table[i];
58             return;
59         }
60     }
61     throw TypeMismatchException("value is not PowerState type");
62 };
63
64 PowerState::PowerState(state in):mState(in){
65 }
66
67 const std::string PowerState::toString(){
68     static const char *table[] = { "SCREEN_OFF", "SCREEN_DIM", "SCREEN_NORMAL", "SCREEN_BRIGHT", "CPU_AWAKE"};
69     return std::string(table[mState]);
70 }
71
72
73 void PowerManager::onPlatformStateChangedCB(power_state_e state, void *user_data){
74     PowerManager* object = static_cast<PowerManager*>(user_data);
75     if(object == NULL){
76         LoggerE("User data is NULL");
77         return;
78     }
79     PowerState current(PowerState::SCREENOFF);
80     switch( state ){
81         case POWER_STATE_NORMAL :
82             current.mState = object->mBrightStateEnable ? PowerState::SCREENBRIGHT : PowerState::SCREENNORMAL;
83             break;
84         case POWER_STATE_SCREEN_DIM :
85             current.mState = PowerState::SCREENDIM;
86             break;
87         case POWER_STATE_SCREEN_OFF :
88             current.mState = PowerState::SCREENOFF;
89             break;
90     }
91     object->broadcastScreenState(current);
92 }
93
94
95 void PowerManager::request(PowerResource resource, PowerState state){
96     if( resource == PowerResource::SCREEN && state == PowerState::CPUAWAKE)
97         throw InvalidValuesException("invalid PowerState");
98     if( resource == PowerResource::CPU && state != PowerState::CPUAWAKE)
99         throw InvalidValuesException("invalid PowerState");
100
101     int ret=0;
102     switch( state ){
103         case PowerState::SCREENDIM :
104         case PowerState::SCREENNORMAL :
105         case PowerState::CPUAWAKE :
106         {
107             int native_state = POWER_STATE_SCREEN_OFF;
108             if( state == PowerState::SCREENDIM )
109                 native_state = POWER_STATE_SCREEN_DIM;
110             else if( state == PowerState::SCREENNORMAL )
111                 native_state = POWER_STATE_NORMAL;
112             else
113                 native_state = POWER_STATE_SCREEN_OFF;
114
115             ret = power_lock_state( (power_state_e)native_state , 0);
116             if( POWER_ERROR_NONE!=ret ){
117                 LoggerE("power_lock_state(%d) error %d",native_state, ret);
118                 throw UnknownException("power_lock_state error");
119             }
120             break;
121         }
122         case PowerState::SCREENBRIGHT :
123         {
124             int maxBrightness;
125             ret = device_get_max_brightness(0, &maxBrightness);
126             if( DEVICE_ERROR_NONE!=ret) {
127                 LoggerE("Platform error while getting max brightness: %d", ret);
128                 throw UnknownException("Platform error while getting max brightness");
129             }
130
131             setPlatformBrightness( maxBrightness );
132
133             LOGI("Succeeded setting the brightness to a max level: %d", maxBrightness);
134             ret = power_lock_state(POWER_STATE_NORMAL, 0);
135             if( POWER_ERROR_NONE!=ret ){
136                 LoggerE("Platform error while locking state %d", ret);
137                 throw UnknownException("Platform error while locking state");
138             }
139
140             mBrightStateEnable = true;
141             power_state_e platform_state = power_get_state();
142             if( platform_state ==  POWER_STATE_NORMAL)
143                 broadcastScreenState(PowerState::SCREENBRIGHT);
144             break;
145         }
146         case PowerState::SCREENOFF:
147             LoggerE("SCREEN_OFF state cannot be requested");
148             throw InvalidValuesException("SCREEN_OFF state cannot be requested");
149
150         default :
151             throw UnknownException("Platform error while locking state");
152     }
153 }
154
155 void PowerManager::release(PowerResource resource){
156     int ret;
157     if( PowerResource::SCREEN == resource ) {
158         ret = power_unlock_state(POWER_STATE_SCREEN_DIM);
159         if( POWER_ERROR_NONE!=ret )
160             LOGI("Platform return value from dim unlock: %d", ret);
161
162         ret = power_unlock_state(POWER_STATE_NORMAL);
163         if( POWER_ERROR_NONE!=ret )
164             LOGI("Platform return value from dim unlock: %d", ret);
165
166         if( mBrightStateEnable ){
167             ret = device_set_brightness_from_settings(0);
168             if( DEVICE_ERROR_NONE!=ret){
169                 LoggerE("Platform error while setting restore brightness %d", ret);
170                 throw UnknownException("Platform error while setting restore brightness");
171             }
172         }
173
174         mBrightStateEnable = false;
175         power_state_e platform_state = power_get_state();
176         if( platform_state ==  POWER_STATE_NORMAL)
177             broadcastScreenState(PowerState::SCREENNORMAL);
178
179     } else if( PowerResource::CPU == resource ) {
180         ret = power_unlock_state(POWER_STATE_SCREEN_OFF);
181         if( POWER_ERROR_NONE!=ret )
182             LOGI("Platform return value from off unlock: %d", ret);
183     }
184 }
185
186 double PowerManager::getScreenBrightness(){
187     int brightness;
188     brightness = getPlatformBrightness();
189     LOGI("Brightness value: %d", brightness);
190     return brightness/100.0;
191 }
192
193 void PowerManager::setScreenBrightness(double brightness){
194     int ret;
195     if( brightness > 1 || brightness < 0 )
196         throw InvalidValuesException("brightness should be 0 <= brightness <= 1");
197     int maxBrightness;
198     ret = device_get_max_brightness(0, &maxBrightness);
199     if( ret != 0 ){
200         LoggerE("Platform error while setting restore brightness: %d", ret);
201         throw UnknownException("Platform error while getting max brightness");
202     }
203     int nativeBrightness = (int)(brightness*maxBrightness);
204
205     setPlatformBrightness(nativeBrightness);
206     LOGI("Set the brightness value: %d", nativeBrightness);
207 }
208
209 bool PowerManager::isScreenOn(){
210     power_state_e state = power_get_state();
211     if(POWER_STATE_SCREEN_OFF==state)
212         return false;
213     else
214         return true;
215 }
216
217 void PowerManager::setScreenState(bool onoff){
218     int ret = 0;
219     if( onoff )
220         ret = pm_change_state(LCD_NORMAL);
221     else
222         ret = pm_change_state(LCD_OFF);
223
224     if( ret<0 ){
225         LoggerE("Platform error while changing screen state %d", ret);
226         throw UnknownException("Platform error while changing screen state");
227     }
228 }
229
230 void PowerManager::restoreScreenBrightness(){
231     int ret;
232     ret = device_set_brightness_from_settings(0);
233     if( DEVICE_ERROR_NONE!=ret){
234         LoggerE("Platform error while restoring brightness %d", ret);
235         throw UnknownException("Platform error while restoring brightness");
236     }
237 }
238
239 PowerManager* PowerManager::getInstance(){
240     static PowerManager instance;
241     return &instance;
242 }
243
244 void PowerManager::addScreenStateChangedCallback(Common::CallbackUserData * callback){
245     list<CallbackUserData*>::iterator itr;
246     itr = find(mListener.begin(), mListener.end(), callback);
247     if( itr == mListener.end() )
248         mListener.push_back(callback);
249 }
250
251 void PowerManager::removeScreenStateChangedCallback(Common::CallbackUserData * callback){
252     mListener.remove(callback);
253 }
254
255 void PowerManager::setPlatformBrightness(int brightness){
256
257
258     if( mCurrentState.mState == PowerState::SCREENDIM ){
259         mCurrentBrightness = brightness;
260         LOGI("Current state is not normal state the value is saved in cache: %d", brightness);
261         mShouldBeReadFromCache = true;
262         return;
263     }else
264         mShouldBeReadFromCache = false;
265
266     int ret = device_set_brightness(0, brightness);
267     if( ret != 0){
268         LoggerE("Platform error while setting %d brightness: %d", brightness, ret);
269         throw UnknownException("Platform error while setting brightness.");
270     }
271     mCurrentBrightness = brightness;
272 }
273
274 int PowerManager::getPlatformBrightness(){
275     int brightness = 0;
276     int ret = 0;
277
278     int isCustomMode = 0;
279     vconf_get_int(VCONFKEY_PM_CUSTOM_BRIGHTNESS_STATUS, &isCustomMode);
280     if( (isCustomMode && mCurrentBrightness != -1) || mShouldBeReadFromCache ){
281         LOGI("return custom brightness %d", mCurrentBrightness);
282         return mCurrentBrightness;
283     }
284
285     ret = vconf_get_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, &brightness);
286     if( ret != 0 ){
287         LoggerE("Platform error while getting brightness: %d", ret);
288         throw UnknownException("Platform error while getting brightness");
289     }
290     LoggerE("VCONFKEY_SETAPPL_LCD_BRIGHTNESS %d", brightness);
291
292     return brightness;
293 }
294
295
296 void PowerManager::restoreSettedBrightness(){
297     int isCustomMode = 0;
298     vconf_get_int(VCONFKEY_PM_CUSTOM_BRIGHTNESS_STATUS, &isCustomMode);
299     if( isCustomMode || mShouldBeReadFromCache ){
300         if( mCurrentBrightness == -1 ){
301             // brightness was changed in other process
302             restoreScreenBrightness();
303         }else{
304             setPlatformBrightness(mCurrentBrightness);
305         }
306     }
307     mShouldBeReadFromCache = false;
308 }
309
310 void PowerManager::broadcastScreenState(PowerState current){
311     if( mCurrentState == current)
312         return;
313
314     PowerState PreviousState = mCurrentState;
315     mCurrentState = current;
316
317     if( mCurrentState.mState == PowerState::SCREENNORMAL && PreviousState.mState == PowerState::SCREENDIM ){
318         //restore ScreenBrightness
319         try{
320             restoreSettedBrightness();
321         }
322         catch( const BasePlatformException& err){
323             LoggerE("Error restore custom brightness %s", err.getMessage().c_str());
324         }
325     }
326     if( mCurrentState.mState == PowerState::SCREENNORMAL && PreviousState.mState == PowerState::SCREENOFF){
327         mShouldBeReadFromCache = false;
328     }
329
330     list<CallbackUserData*> tmplist(mListener);
331     list<CallbackUserData*>::iterator itr = tmplist.begin();
332
333     while( itr != tmplist.end() ){
334         CallbackUserData *callback = *itr;
335         if( callback != NULL ){
336             JSValueRef previousState = JSUtil::toJSValueRef(callback->getContext(), PreviousState.toString());
337             JSValueRef currentState = JSUtil::toJSValueRef(callback->getContext(), mCurrentState.toString());
338             JSValueRef args[2] = { previousState, currentState };
339             callback->callSuccessCallback(2, args);
340         }
341         ++itr;
342     }
343 }
344
345
346 PowerManager::PowerManager():mCurrentState(PowerState::SCREENNORMAL),mBrightStateEnable(false),mCurrentBrightness(-1),mShouldBeReadFromCache(false){
347     power_state_e platform_state = power_get_state();
348     switch( platform_state ){
349         case POWER_STATE_NORMAL :
350             mCurrentState.mState = PowerState::SCREENNORMAL;
351             break;
352         case POWER_STATE_SCREEN_DIM :
353             mCurrentState.mState = PowerState::SCREENDIM;
354             break;
355         case POWER_STATE_SCREEN_OFF :
356             mCurrentState.mState = PowerState::SCREENOFF;
357             break;
358     }
359     power_set_changed_cb(PowerManager::onPlatformStateChangedCB, this);
360 }
361 PowerManager::~PowerManager(){
362     power_unset_changed_cb();
363 }
364
365 } //Power
366 } //DeviceAPI
367