merge with master
[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     int native_state = POWER_STATE_SCREEN_OFF;
104     switch( state ){
105         case PowerState::SCREENDIM :
106             native_state = POWER_STATE_SCREEN_DIM;
107         case PowerState::SCREENNORMAL :
108             native_state = POWER_STATE_NORMAL;
109         case PowerState::CPUAWAKE :
110             ret = power_lock_state( state.mState == PowerState::SCREENDIM ? POWER_STATE_SCREEN_DIM : POWER_STATE_NORMAL, 0);
111             if( POWER_ERROR_NONE!=ret )
112                 throw UnknownException("power_lock_state error");
113             break;
114         case PowerState::SCREENBRIGHT :
115         {
116             int maxBrightness = 100;
117             ret = device_get_max_brightness(0, &maxBrightness);
118             if( DEVICE_ERROR_NONE!=ret) {
119                 LOGE("Platform error while getting max brightness: %d", ret);
120             }
121
122             ret = device_set_brightness(0, maxBrightness);
123             if( DEVICE_ERROR_NONE!=ret)
124                 throw UnknownException("Platform error while setting max brightness:");
125
126             LOGI("Succeeded setting the brightness to a max level: %d", maxBrightness);
127             ret = power_lock_state(POWER_STATE_NORMAL, 0);
128             if( POWER_ERROR_NONE!=ret )
129                 throw UnknownException("Platform error while locking state");
130
131             mBrightStateEnable = true;
132             power_state_e platform_state = power_get_state();
133             if( platform_state ==  POWER_STATE_NORMAL)
134                 broadcastScreenState(PowerState::SCREENBRIGHT);
135             break;
136         }
137         default :
138             throw UnknownException("Platform error while locking state");
139     }
140 }
141
142 void PowerManager::release(PowerResource resource){
143     int ret;
144     if( PowerResource::SCREEN == resource ) {
145         ret = power_unlock_state(POWER_STATE_SCREEN_DIM);
146         if( POWER_ERROR_NONE!=ret )
147             LOGI("Platform return value from dim unlock: %d", ret);
148
149         ret = power_unlock_state(POWER_STATE_NORMAL);
150         if( POWER_ERROR_NONE!=ret )
151             LOGI("Platform return value from dim unlock: %d", ret);
152
153         ret = device_set_brightness_from_settings(0);
154         if( DEVICE_ERROR_NONE!=ret)
155             throw UnknownException("Platform error while setting restore brightness");
156
157         mBrightStateEnable = false;
158         power_state_e platform_state = power_get_state();
159         if( platform_state ==  POWER_STATE_NORMAL)
160             broadcastScreenState(PowerState::SCREENNORMAL);
161
162     } else if( PowerResource::CPU == resource ) {
163         ret = power_unlock_state(POWER_STATE_SCREEN_OFF);
164         if( POWER_ERROR_NONE!=ret )
165             LOGI("Platform return value from off unlock: %d", ret);
166     }
167 }
168
169 double PowerManager::getScreenBrightness(){
170     int ret, brightness;
171     ret = device_get_brightness(0, &brightness);
172     if( DEVICE_ERROR_NONE!=ret )
173         throw UnknownException("Platform error while get brightness");
174     LOGI("Brightness value: %d", brightness);
175     return brightness/100.0;
176 }
177
178 void PowerManager::setScreenBrightness(double brightness){
179     int ret;
180     ret = device_set_brightness(0, (int)(brightness*100));
181     if( DEVICE_ERROR_NONE!=ret )
182         throw UnknownException("Platform error while setting brightness.");
183     LOGI("Set the brightness value: %d", (int)(brightness*100));
184 }
185
186 bool PowerManager::isScreenOn(){
187     power_state_e state = power_get_state();
188     if(POWER_STATE_SCREEN_OFF==state)
189         return false;
190     else
191         return true;
192 }
193
194 void PowerManager::setScreenState(bool onoff){
195     int ret = 0;
196     if( onoff )
197         ret = pm_change_state(LCD_NORMAL);
198     else
199         ret = pm_change_state(LCD_OFF);
200
201     if( ret<0 )
202         throw UnknownException("Platform error while changing screen state");
203 }
204
205 void PowerManager::restoreScreenBrightness(){
206     int ret;
207     ret = device_set_brightness_from_settings(0);
208     if( DEVICE_ERROR_NONE!=ret)
209         throw UnknownException("Platform error while restoring brightness");
210 }
211
212 PowerManager* PowerManager::getInstance(){
213     static PowerManager instance;
214     return &instance;
215 }
216
217 void PowerManager::addScreenStateChangedCallback(Common::CallbackUserData * callback){
218     list<CallbackUserData*>::iterator itr;
219     itr = find(mListener.begin(), mListener.end(), callback);
220     if( itr == mListener.end() )
221         mListener.push_back(callback);
222 }
223
224 void PowerManager::removeScreenStateChangedCallback(Common::CallbackUserData * callback){
225     mListener.remove(callback);
226 }
227
228 void PowerManager::broadcastScreenState(PowerState current){
229     if( mCurrentState == current)
230         return;
231
232     list<CallbackUserData*> tmplist(mListener);
233     list<CallbackUserData*>::iterator itr = tmplist.begin();
234
235     while( itr != tmplist.end() ){
236         CallbackUserData *callback = *itr;
237         if( callback != NULL ){
238             JSValueRef previousState = JSUtil::toJSValueRef(callback->getContext(), mCurrentState.toString());
239             JSValueRef currentState = JSUtil::toJSValueRef(callback->getContext(), current.toString());
240             JSValueRef args[2] = { previousState, currentState };
241             callback->callSuccessCallback(2, args);
242         }
243         ++itr;
244     }
245     mCurrentState = current;
246 }
247
248
249 PowerManager::PowerManager():mCurrentState(PowerState::SCREENNORMAL),mBrightStateEnable(false){
250     power_state_e platform_state = power_get_state();
251     switch( platform_state ){
252         case POWER_STATE_NORMAL :
253             mCurrentState.mState = PowerState::SCREENNORMAL;
254             break;
255         case POWER_STATE_SCREEN_DIM :
256             mCurrentState.mState = PowerState::SCREENDIM;
257             break;
258         case POWER_STATE_SCREEN_OFF :
259             mCurrentState.mState = PowerState::SCREENOFF;
260             break;
261     }
262     power_set_changed_cb(PowerManager::onPlatformStateChangedCB, this);
263 }
264 PowerManager::~PowerManager(){
265     power_unset_changed_cb();
266 }
267
268 } //Power
269 } //DeviceAPI
270