Update change log and spec for wrt-plugins-tizen_0.4.20
[platform/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 <dlog.h>
24 #include <algorithm>
25 #include <PlatformException.h>
26 #include <Logger.h>
27 #include <JSUtil.h>
28
29 using namespace DeviceAPI::Common;
30 using namespace std;
31
32 namespace DeviceAPI {
33 namespace Power {
34
35
36 PowerResource::PowerResource(const char *resource)
37 {
38     if( strcmp(resource,"SCREEN") == 0 )
39         mType = SCREEN;
40     else if( strcmp(resource,"CPU") == 0 )
41        mType = CPU;
42     else
43        throw TypeMismatchException("value is not PowerResource type");
44 };
45
46 const std::string PowerResource::toString(){
47     static const char *table[] = {"SCREEN", "CPU"};
48     return std::string(table[mType]);
49 }
50
51
52 PowerState::PowerState(const char *str)
53 {
54     static const char *table[] = { "SCREEN_OFF", "SCREEN_DIM", "SCREEN_NORMAL", "SCREEN_BRIGHT", "CPU_AWAKE"};
55     static state state_table[] = { SCREENOFF, SCREENDIM, SCREENNORMAL, SCREENBRIGHT, CPUAWAKE };
56     for(unsigned int i =0; i < sizeof(table)/sizeof(char*) ; i++){
57         if( strcmp(str, table[i]) == 0 ){
58             mState = state_table[i];
59             return;
60         }
61     }
62     throw TypeMismatchException("value is not PowerState type");
63 };
64
65 PowerState::PowerState(state in):mState(in){
66 }
67
68 const std::string PowerState::toString(){
69     static const char *table[] = { "SCREEN_OFF", "SCREEN_DIM", "SCREEN_NORMAL", "SCREEN_BRIGHT", "CPU_AWAKE"};
70     return std::string(table[mState]);
71 }
72
73
74 void PowerManager::onPlatformStateChangedCB(power_state_e state, void *user_data){
75     PowerManager* object = static_cast<PowerManager*>(user_data);
76     if(object == NULL){
77         LOGE("User data is NULL");
78         return;
79     }
80     PowerState current(PowerState::SCREENOFF);
81     switch( state ){
82         case POWER_STATE_NORMAL :
83             current.mState = object->mBrightStateEnable ? PowerState::SCREENBRIGHT : PowerState::SCREENNORMAL;
84             break;
85         case POWER_STATE_SCREEN_DIM :
86             current.mState = PowerState::SCREENDIM;
87             break;
88         case POWER_STATE_SCREEN_OFF :
89             current.mState = PowerState::SCREENOFF;
90             break;
91     }
92     object->broadcastScreenState(current);
93 }
94
95
96 void PowerManager::request(PowerResource resource, PowerState state){
97     if( resource == PowerResource::SCREEN && state == PowerState::CPUAWAKE)
98         throw InvalidValuesException("invalid PowerState");
99     if( resource == PowerResource::CPU && state != PowerState::CPUAWAKE)
100         throw InvalidValuesException("invalid PowerState");
101
102     int ret=0;
103     switch( state ){
104         case PowerState::SCREENDIM :
105         case PowerState::SCREENNORMAL :
106         case PowerState::CPUAWAKE :
107         {
108             int native_state = POWER_STATE_SCREEN_OFF;
109             if( state == PowerState::SCREENDIM )
110                 native_state = POWER_STATE_SCREEN_DIM;
111             else if( state == PowerState::SCREENNORMAL )
112                 native_state = POWER_STATE_NORMAL;
113             else
114                 native_state = POWER_STATE_SCREEN_OFF;
115
116             ret = power_lock_state( (power_state_e)native_state , 0);
117             if( POWER_ERROR_NONE!=ret ){
118                 LOGE("power_lock_state(%d) error %d",native_state, ret);
119                 throw UnknownException("power_lock_state error");
120             }
121             break;
122         }
123         case PowerState::SCREENBRIGHT :
124         {
125             int maxBrightness;
126             ret = device_get_max_brightness(0, &maxBrightness);
127             if( DEVICE_ERROR_NONE!=ret) {
128                 LOGE("Platform error while getting max brightness: %d", ret);
129                 throw UnknownException("Platform error while getting max brightness");
130             }
131
132             ret = device_set_brightness(0, maxBrightness);
133             if( DEVICE_ERROR_NONE!=ret){
134                 LOGE("Platform error while setting %d brightness: %d", maxBrightness, ret);
135                 throw UnknownException("Platform error while setting max brightness");
136             }
137
138             LOGI("Succeeded setting the brightness to a max level: %d", maxBrightness);
139             ret = power_lock_state(POWER_STATE_NORMAL, 0);
140             if( POWER_ERROR_NONE!=ret ){
141                 LOGE("Platform error while locking state %d", ret);
142                 throw UnknownException("Platform error while locking state");
143             }
144
145             mBrightStateEnable = true;
146             power_state_e platform_state = power_get_state();
147             if( platform_state ==  POWER_STATE_NORMAL)
148                 broadcastScreenState(PowerState::SCREENBRIGHT);
149             break;
150         }
151         case PowerState::SCREENOFF:
152             LOGE("SCREEN_OFF state cannot be requested");
153             throw InvalidValuesException("SCREEN_OFF state cannot be requested");
154
155         default :
156             throw UnknownException("Platform error while locking state");
157     }
158 }
159
160 void PowerManager::release(PowerResource resource){
161     int ret;
162     if( PowerResource::SCREEN == resource ) {
163         ret = power_unlock_state(POWER_STATE_SCREEN_DIM);
164         if( POWER_ERROR_NONE!=ret )
165             LOGI("Platform return value from dim unlock: %d", ret);
166
167         ret = power_unlock_state(POWER_STATE_NORMAL);
168         if( POWER_ERROR_NONE!=ret )
169             LOGI("Platform return value from dim unlock: %d", ret);
170
171         ret = device_set_brightness_from_settings(0);
172         if( DEVICE_ERROR_NONE!=ret){
173             LOGE("Platform error while setting restore brightness %d", ret);
174             throw UnknownException("Platform error while setting restore brightness");
175         }
176
177         mBrightStateEnable = false;
178         power_state_e platform_state = power_get_state();
179         if( platform_state ==  POWER_STATE_NORMAL)
180             broadcastScreenState(PowerState::SCREENNORMAL);
181
182     } else if( PowerResource::CPU == resource ) {
183         ret = power_unlock_state(POWER_STATE_SCREEN_OFF);
184         if( POWER_ERROR_NONE!=ret )
185             LOGI("Platform return value from off unlock: %d", ret);
186     }
187 }
188
189 double PowerManager::getScreenBrightness(){
190     int ret, brightness;
191     ret = device_get_brightness(0, &brightness);
192     if( DEVICE_ERROR_NONE!=ret ){
193         LOGE("Platform error while get brightness %d", ret);
194         throw UnknownException("Platform error while get brightness");
195     }
196     LOGI("Brightness value: %d", brightness);
197     return brightness/100.0;
198 }
199
200 void PowerManager::setScreenBrightness(double brightness){
201     int ret;
202     if( brightness > 1 || brightness < 0 )
203         throw InvalidValuesException("brightness should be 0 <= brightness <= 1");
204     int maxBrightness;
205     ret = device_get_max_brightness(0, &maxBrightness);
206     if( ret != 0 ){
207         LOGE("Platform error while setting restore brightness: %d", ret);
208         throw UnknownException("Platform error while getting max brightness");
209     }
210     int nativeBrightness = (int)(brightness*maxBrightness);
211     ret = device_set_brightness(0, nativeBrightness);
212     if( DEVICE_ERROR_NONE!=ret ){
213         LOGE("Platform error while setting %d brightness : %d",nativeBrightness, ret);
214         throw UnknownException("Platform error while setting brightness.");
215     }
216     LOGI("Set the brightness value: %d", nativeBrightness);
217 }
218
219 bool PowerManager::isScreenOn(){
220     power_state_e state = power_get_state();
221     if(POWER_STATE_SCREEN_OFF==state)
222         return false;
223     else
224         return true;
225 }
226
227 void PowerManager::setScreenState(bool onoff){
228     int ret = 0;
229     if( onoff )
230         ret = pm_change_state(LCD_NORMAL);
231     else
232         ret = pm_change_state(LCD_OFF);
233
234     if( ret<0 ){
235         LOGE("Platform error while changing screen state %d", ret);
236         throw UnknownException("Platform error while changing screen state");
237     }
238 }
239
240 void PowerManager::restoreScreenBrightness(){
241     int ret;
242     ret = device_set_brightness_from_settings(0);
243     if( DEVICE_ERROR_NONE!=ret){
244         LOGE("Platform error while restoring brightness %d", ret);
245         throw UnknownException("Platform error while restoring brightness");
246     }
247 }
248
249 PowerManager* PowerManager::getInstance(){
250     static PowerManager instance;
251     return &instance;
252 }
253
254 void PowerManager::addScreenStateChangedCallback(Common::CallbackUserData * callback){
255     list<CallbackUserData*>::iterator itr;
256     itr = find(mListener.begin(), mListener.end(), callback);
257     if( itr == mListener.end() )
258         mListener.push_back(callback);
259 }
260
261 void PowerManager::removeScreenStateChangedCallback(Common::CallbackUserData * callback){
262     mListener.remove(callback);
263 }
264
265 void PowerManager::broadcastScreenState(PowerState current){
266     if( mCurrentState == current)
267         return;
268
269     list<CallbackUserData*> tmplist(mListener);
270     list<CallbackUserData*>::iterator itr = tmplist.begin();
271
272     while( itr != tmplist.end() ){
273         CallbackUserData *callback = *itr;
274         if( callback != NULL ){
275             JSValueRef previousState = JSUtil::toJSValueRef(callback->getContext(), mCurrentState.toString());
276             JSValueRef currentState = JSUtil::toJSValueRef(callback->getContext(), current.toString());
277             JSValueRef args[2] = { previousState, currentState };
278             callback->callSuccessCallback(2, args);
279         }
280         ++itr;
281     }
282     mCurrentState = current;
283 }
284
285
286 PowerManager::PowerManager():mCurrentState(PowerState::SCREENNORMAL),mBrightStateEnable(false){
287     power_state_e platform_state = power_get_state();
288     switch( platform_state ){
289         case POWER_STATE_NORMAL :
290             mCurrentState.mState = PowerState::SCREENNORMAL;
291             break;
292         case POWER_STATE_SCREEN_DIM :
293             mCurrentState.mState = PowerState::SCREENDIM;
294             break;
295         case POWER_STATE_SCREEN_OFF :
296             mCurrentState.mState = PowerState::SCREENOFF;
297             break;
298     }
299     power_set_changed_cb(PowerManager::onPlatformStateChangedCB, this);
300 }
301 PowerManager::~PowerManager(){
302     power_unset_changed_cb();
303 }
304
305 } //Power
306 } //DeviceAPI
307