Tizen 2.1 base
[platform/framework/native/app-service.git] / src / FSys_SystemService.cpp
1 //
2 // Open Service Platform
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 /**
19  * @file                FSys_SystemService.cpp
20  * @brief               This is the implementation file for _SystemService class.
21  */
22 #include <unique_ptr.h>
23 #include <new>
24 #include <time.h>
25
26 #include <device.h>
27 #include <system_info.h>
28
29 #include <FBaseSysLog.h>
30
31 #include <FApp_AppManagerImpl.h>
32 #include <FBase_StringConverter.h>
33 #include <FSec_AccessController.h>
34
35 #include "FApp_CommunicationDispatcher.h"
36 #include "FSys_SystemService.h"
37
38 using namespace std;
39
40 using namespace Tizen::App;
41 using namespace Tizen::Io;
42 using namespace Tizen::System;
43 using namespace Tizen::Base;
44 using namespace Tizen::Base::Collection;
45 using namespace Tizen::Base::Utility;
46 using namespace Tizen::Security;
47
48 namespace {
49         static const wchar_t* _SYSTEM_SERVICE_ID = L"osp.system.service";
50         static const wchar_t* _SYSTEM_COMMAND_CHANGE_TIME = L"osp.system.command.change.time";
51         static const wchar_t* _SYSTEM_COMMAND_CHANGE_BRIGHTNESS = L"osp.system.command.change.brightness";
52         static const wchar_t* _SYSTEM_COMMAND_RESTORE_BRIGHTNESS = L"osp.system.command.restore.brightness";
53         static const wchar_t* _SYSTEM_COMMAND_GET_IMEI = L"osp.system.command.get.imei";
54         static const wchar_t* _SYSTEM_RESULT_OK = L"osp.system.result.ok";
55         static const wchar_t* _SYSTEM_RESULT_ERROR = L"osp.system.result.error";
56         static const wchar_t* _SYSTEM_RESULT_INVALID = L"osp.system.result.invalid";
57         static const wchar_t* _SYSTEM_RESULT_PRIVILEGED = L"osp.system.result.privilege";
58         static const int _SYSTEM_COMMAND_ID = 1;
59         static const int _SYSTEM_COMMAND_ARG = 2;
60 }
61
62 Tizen::System::_SystemService* Tizen::System::_SystemService::__pSystemService = null;
63
64 void
65 DeviceBatteryCallback(int percent, void* userData)
66 {
67         device_battery_warn_e batteryLevel = DEVICE_BATTERY_WARN_EMPTY;
68         int ret = device_battery_get_warning_status(&batteryLevel);
69         if(ret == DEVICE_ERROR_NONE && batteryLevel < DEVICE_BATTERY_WARN_NORMAL)
70         {
71                 _SystemService* pSystemService = _SystemService::GetInstance();
72                 if(pSystemService != null)
73                 {
74                         pSystemService->RestoreBrightness();
75                 }
76         }
77 }
78
79 _SystemService::_SystemService()
80         : _ICommunicationRequestListener()
81         , __pCommunicationDispatcher(null)
82 {
83         int ret = 0;
84         result r = E_SUCCESS;
85         _AppManagerImpl* pAppManagerImpl = null;
86
87         __pCommunicationDispatcher = _CommunicationDispatcher::GetInstance();
88         SysTryCatch(NID_SYS, __pCommunicationDispatcher != null, r = E_SYSTEM, E_SYSTEM, "_CommunicationDispatcher initiate is failed");
89
90         r = __pCommunicationDispatcher->AddCommunicationEventListener(*this);
91         SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "fail to add event listener");
92
93         __appBrightnessList.Construct();
94         pAppManagerImpl = _AppManagerImpl::GetInstance();
95         SysTryCatch(NID_SYS, pAppManagerImpl != null, r = E_SYSTEM, E_SYSTEM, "It is failed to get _AppManagerImpl class.");
96
97         r = pAppManagerImpl->AddActiveAppEventListener(*this);
98         SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "It is failed to add active app event listener");
99
100         ret = device_battery_set_cb(DeviceBatteryCallback, null);
101         SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "It is failed to add battery event listener");
102
103 CATCH:
104         SetLastResult(r);
105 }
106
107 _SystemService::~_SystemService()
108 {
109         int ret = 0;
110         result r = E_SUCCESS;
111         _AppManagerImpl* pAppManagerImpl = null;
112         SysTryCatch(NID_SYS, __pCommunicationDispatcher != null, r = E_SYSTEM, E_SYSTEM, "_CommunicationDispatcher is not ready");
113
114         r = __pCommunicationDispatcher->RemoveCommunicationEventListener(*this);
115         SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "fail to remove event listener");
116
117         ret = device_battery_unset_cb();
118         SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "It is failed to remove battery event listener");
119
120         pAppManagerImpl = _AppManagerImpl::GetInstance();
121         SysTryCatch(NID_SYS, pAppManagerImpl != null, r = E_SYSTEM, E_SYSTEM, "It is failed to get _AppManagerImpl class.");
122
123         r = pAppManagerImpl->RemoveActiveAppEventListener(*this);
124         SysTryCatch(NID_SYS, r == E_SUCCESS, , E_SYSTEM, "It is failed to remove active app listener.");
125
126         __appBrightnessList.RemoveAll(true);
127
128 CATCH:
129         SetLastResult(r);
130 }
131
132 _SystemService*
133 _SystemService::GetInstance(void)
134 {
135         if(__pSystemService == null)
136         {
137                 __pSystemService = new (std::nothrow) _SystemService();
138         }
139         return __pSystemService;
140 }
141
142 String
143 _SystemService::GetId(void)
144 {
145         return _SYSTEM_SERVICE_ID;
146 }
147
148 void
149 _SystemService::RestoreBrightness(void)
150 {
151         int ret = 0;
152         Integer* pBrightness = null;
153         String convertedActiveAppId;
154         __activeAppId.SubString( 0, 10, convertedActiveAppId);
155
156         SysLog(NID_SYS, "Active App is %ls", __activeAppId.GetPointer());
157
158         pBrightness = (Integer*)(__appBrightnessList.GetValue(convertedActiveAppId));
159
160         if(pBrightness != null)
161         {
162                 //Change application's brightness
163                 SysLog(NID_SYS, "Application's brightness is %d", pBrightness->ToInt());
164                 ret = device_set_brightness(0, pBrightness->ToInt());
165                 if(ret != DEVICE_ERROR_NONE)
166                 {
167                         SysLogException(NID_SYS, E_SYSTEM, "It is failed to change screen brightness");
168                 }
169         }
170         else
171         {
172                 //Restore system brightness
173                 SysLog(NID_SYS, "Restore to System brightness");
174                 ret = device_set_brightness_from_settings(0);
175                 if(ret != DEVICE_ERROR_NONE)
176                 {
177                         SysLogException(NID_SYS, E_SYSTEM, "It is failed to restore screen brightness");
178                 }
179         }
180
181 }
182
183 void
184 _SystemService::OnActiveAppChanged(const AppId& appId)
185 {
186         __activeAppId = appId;
187         RestoreBrightness();
188 }
189
190 void
191 _SystemService::OnRequestOccured(AppId appId, ArrayList* request, ArrayList* response)
192 {
193         int ret = 0;
194         result r = E_SUCCESS;
195         StringComparer strComparer;
196         String* resultId = null;
197         String* command = null;
198         String* serviceId = null;
199         String* commandId = null;
200         String* returnValue = null;
201
202         SysLog(NID_APP, "Request is forwarded to SystemService");
203         SysTryCatch(NID_SYS, request != null && response != null, r = E_INVALID_ARG, E_INVALID_ARG, "Parameters are null");
204
205         command = (String*)request->GetAt(_SYSTEM_COMMAND_ID);
206         SysTryCatch(NID_SYS, command!= null, r = E_INVALID_ARG, E_INVALID_ARG, "Parameters has no command %x, %x", command);
207         
208         serviceId = new (std::nothrow) String(_SYSTEM_SERVICE_ID);
209         commandId = new (std::nothrow) String(_SYSTEM_COMMAND_CHANGE_TIME);
210
211         if(*command == _SYSTEM_COMMAND_GET_IMEI)
212         {
213                 SysLog(NID_SYS, "Get IMEI");
214                 if(response != null)
215                 {
216                         r = _AccessController::CheckSystemPrivilege(appId, _PRV_USERIDENTITY);
217
218                         if(r != E_SUCCESS)
219                         {
220                                 SysLogException(NID_SYS, E_PRIVILEGE_DENIED, "Application[%ls] does not have enought privilege.", appId.GetPointer());
221                                 resultId = new (std::nothrow) String(_SYSTEM_RESULT_PRIVILEGED);
222                         }
223                         else
224                         {
225                                 char* pImei = null;
226                                 ret = system_info_get_value_string(SYSTEM_INFO_KEY_MOBILE_DEVICE_ID, &pImei);
227                                 if(ret != SYSTEM_INFO_ERROR_NONE || pImei == null)
228                                 {
229                                         SysLogException(NID_SYS, E_SYSTEM, "It is failed to get IMEI.");
230                                         resultId = new (std::nothrow) String(_SYSTEM_RESULT_ERROR);
231                                 }
232                                 else
233                                 {
234                                         resultId = new (std::nothrow) String(_SYSTEM_RESULT_OK);
235                                         returnValue = new (std::nothrow) String(pImei);
236                                 }
237                         }
238                 }
239         }
240         else if(*command == _SYSTEM_COMMAND_CHANGE_BRIGHTNESS)
241         {
242                 SysLog(NID_SYS, "Change brightness");
243                 int brightness = 0;
244                 String* brightnessBuffer = (String*)request->GetAt(_SYSTEM_COMMAND_ARG);
245
246                 if(brightnessBuffer == null)
247                 {
248                         resultId = new (std::nothrow) String(_SYSTEM_RESULT_ERROR);
249                 }
250                 else
251                 {
252                         Integer::Parse(*brightnessBuffer, brightness);
253                         SysLog(NID_SYS, "requested brightness is %d", brightness);
254
255                         __appBrightnessList.Remove(appId, true);
256                         unique_ptr<Integer> pBrightness(new (std::nothrow) Integer(brightness));
257                         unique_ptr<String> pAppId(new (std::nothrow) String(appId));
258
259                         SysTryCatch(NID_SYS, pBrightness != null && pAppId != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "It is failed to create appId or brightness.");
260
261                         r = __appBrightnessList.Add(pAppId.get(), pBrightness.get());
262
263                         SysTryCatch(NID_SYS, r == E_SUCCESS, , r, "It is failed to add appid and brightness.");
264
265                         pAppId.release();
266                         pBrightness.release();
267
268                         SysLog(NID_SYS, "Current App is %ls, Active App is %ls", appId.GetPointer(), __activeAppId.GetPointer());
269
270                         String convertedActiveAppId;
271                         __activeAppId.SubString( 0, 10, convertedActiveAppId);
272
273                         if(convertedActiveAppId == appId)
274                         {
275                                 SysLog(NID_SYS, "Current application is active. So brightness is changed.");
276                                 ret = device_set_brightness(0, brightness);
277                                 SysTryCatch(NID_SYS, ret == DEVICE_ERROR_NONE, r = E_SYSTEM, E_SYSTEM, "It is failed to change brightness [%d].", brightness);
278                         }
279
280                         resultId = new (std::nothrow) String(_SYSTEM_RESULT_OK);
281                 }
282         }
283         else if(*command == _SYSTEM_COMMAND_RESTORE_BRIGHTNESS)
284         {
285                 SysLog(NID_SYS, "Restore brightness");
286                 __appBrightnessList.Remove(appId);
287                 String convertedActiveAppId;
288                 __activeAppId.SubString( 0, 10, convertedActiveAppId);
289
290                 if(convertedActiveAppId == appId)
291                 {
292                         SysLog(NID_SYS, "Current application is active. So brightness is restored.");
293                         ret = device_set_brightness_from_settings(0);
294                         SysTryCatch(NID_SYS, ret == DEVICE_ERROR_NONE, r = E_SYSTEM, E_SYSTEM, "It is failed to restore system brightness.");
295                 }
296                 resultId = new (std::nothrow) String(_SYSTEM_RESULT_OK);
297         }
298
299         else if(*command == _SYSTEM_COMMAND_CHANGE_TIME)
300         {
301                 SysLog(NID_SYS, "Change system time");
302                 r = _AccessController::CheckSystemPrivilege(appId, _PRV_SYSTEMSETTING_WRITE);
303                 if(r != E_SUCCESS)
304                 {
305                         resultId = new (std::nothrow) String(_SYSTEM_RESULT_PRIVILEGED);
306                 }
307                 else
308                 {
309                         struct tm tTime;
310                         String* dateTime = (String*)request->GetAt(_SYSTEM_COMMAND_ARG);
311                         char* datetime = null;
312
313                         datetime = _StringConverter::CopyToCharArrayN(*dateTime);
314                         if(datetime != null)
315                         {
316                                 sscanf(datetime, "%3d %2d %2d %2d:%2d:%2d", &(tTime.tm_year), &(tTime.tm_mon), &(tTime.tm_mday), &(tTime.tm_hour), &(tTime.tm_min), &(tTime.tm_sec));
317                                 time_t _tTime = mktime(&tTime);
318                                 if(stime(&_tTime) == 0)
319                                 {
320                                         resultId = new (std::nothrow) String(_SYSTEM_RESULT_OK);
321                                 }
322                                 else
323                                 {
324                                         resultId = new (std::nothrow) String(_SYSTEM_RESULT_ERROR);
325                                 }
326                                 delete [] datetime;                     
327                         }
328                         else
329                         {
330                                 resultId = new (std::nothrow) String(_SYSTEM_RESULT_ERROR);
331                         }
332                 }               
333         }
334         else
335         {
336                 resultId = new (std::nothrow) String(_SYSTEM_RESULT_INVALID);
337         }
338
339 CATCH:
340         if(resultId == null)
341         {
342                 resultId = new (std::nothrow) String(_SYSTEM_RESULT_ERROR);
343         }
344
345         response->Add(*serviceId);
346         response->Add(*commandId);
347         response->Add(*resultId);
348
349         if(returnValue != null)
350         {
351                 response->Add(*returnValue);
352         }
353         SetLastResult(r);
354 }
355
356 void
357 _SystemService::OnApplicationTerminated(const AppId& appId, _AppType type)
358 {
359         SysLog(NID_SYS, "Application (%ls) is terminated.", appId.GetPointer());
360         __appBrightnessList.Remove(appId, true);
361 }
362