b74a1c4d4716b687c43e42e090f945f701a4ef8d
[platform/framework/native/appfw.git] / src / system / FSys_RuntimeInfoImpl.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file                FSysRuntimeInfo.cpp
19  * @brief               This is the implementation file for _RuntimeInfoImpl class.
20  *
21  *
22  * This file contains the implementation of _RuntimeInfoImpl class.
23  */
24
25 #include <unique_ptr.h>
26 #include <pthread.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <sys/vfs.h>
32 #include <app_storage.h>
33 #include <devman.h>
34 #include <runtime_info.h>
35 #include <vconf.h>
36
37 #include <FIo.h>
38 #include <FAppApp.h>
39 #include <FBaseRtEvent.h>
40 #include <FBaseRtIEventArg.h>
41 #include <FBaseRtIEventListener.h>
42 #include <FBaseRtThread.h>
43 #include <FBaseSysLog.h>
44 #include <FApp_AppInfo.h>
45 #include <FBase_StringConverter.h>
46
47 #include "FSys_EnvironmentImpl.h"
48 #include "FSys_RuntimeInfoImpl.h"
49 #include "FSys_RuntimeClient.h"
50
51 using namespace Tizen::App;
52 using namespace Tizen::Base;
53 using namespace Tizen::Base::Runtime;
54
55 using namespace std;
56
57 namespace Tizen { namespace System
58 {
59
60 #ifndef VCONFKEY_SERVICE_READY
61 #define VCONFKEY_SERVICE_READY  "memory/deviced/boot_power_on"
62 #endif
63
64 static const wchar_t* _ALLOCATED_MEMORY = L"AllocatedMemory";
65 static const wchar_t* _MEMORY_ALLOCATED = L"http://tizen.org/runtime/memory.allocated";
66 static const wchar_t* _MEMORY_ALLOCATED_SELF = L"http://tizen.org/runtime/memory.allocated.self";
67
68 static const wchar_t* _AVAILABLE_EXTERNAL_STORAGE = L"AvailableExternalStorage";
69 static const wchar_t* _STORAGE_AVAILABLE_EXTERNAL = L"http://tizen.org/runtime/storage.available.external";
70
71 static const wchar_t* _AVAILABLE_INTERNAL_STORAGE = L"AvailableInternalStorage";
72 static const wchar_t* _STORAGE_AVAILABLE_INTERNAL = L"http://tizen.org/runtime/storage.available.internal";
73
74 static const wchar_t* _AVAILABLE_MEDIA_STORAGE = L"AvailableMediaStorage";
75 static const wchar_t* _STORAGE_AVAILABLE_INTERNAL_MEDIA = L"http://tizen.org/runtime/storage.available.internal.media";
76
77 static const wchar_t* _BATTERY_LEVEL = L"BatteryLevel";
78 static const wchar_t* _CHARGING = L"IsCharging";
79
80 static const wchar_t* _CPU_CORE_ALL_USAGE = L"http://tizen.org/runtime/cpu.core.all.usage";
81
82 static const wchar_t* _MAX_ALLOCATABLE_MEMORY = L"MaxAllocatableMemory";
83 static const wchar_t* _AVAILABLE_VIDEO_MEMORY = L"AvailableVideoMemory";
84 static const wchar_t* _ALLOCATED_VIDEO_MEMORY = L"AllocatedVideoMemory";
85 static const wchar_t* _AVAILABLE_MEMORY = L"AvailableMemory";
86 static const wchar_t* _MEMORY_AVAILABLE = L"http://tizen.org/runtime/memory.available";
87 static const wchar_t* _MEMORY_AVAILABLE_VIDEO = L"http://tizen.org/runtime/memory.available.video";
88 static const wchar_t* _MEMORY_ALLOCATED_VIDEO = L"http://tizen.org/runtime/memory.allocated.video";
89
90 static const wchar_t* _STORAGE_ALLOCATED_INTERNAL_APPLICATION = L"http://tizen.org/runtime/storage.allocated.internal.application";
91 static const wchar_t* _STORAGE_ALLOCATED_INTERNAL_AUDIO = L"http://tizen.org/runtime/storage.allocated.internal.audio";
92 static const wchar_t* _STORAGE_ALLOCATED_INTERNAL_VIDEO = L"http://tizen.org/runtime/storage.allocated.internal.video";
93 static const wchar_t* _STORAGE_ALLOCATED_INTERNAL_IMAGE = L"http://tizen.org/runtime/storage.allocated.internal.image";
94 static const wchar_t* _STORAGE_ALLOCATED_INTERNAL_DOWNLOAD = L"http://tizen.org/runtime/storage.allocated.internal.download";
95 static const wchar_t* _STORAGE_ALLOCATED_EXTERNAL_APPLICATION = L"http://tizen.org/runtime/storage.allocated.external.application";
96 static const wchar_t* _STORAGE_ALLOCATED_EXTERNAL_AUDIO = L"http://tizen.org/runtime/storage.allocated.external.audio";
97 static const wchar_t* _STORAGE_ALLOCATED_EXTERNAL_VIDEO = L"http://tizen.org/runtime/storage.allocated.external.video";
98 static const wchar_t* _STORAGE_ALLOCATED_EXTERNAL_IMAGE = L"http://tizen.org/runtime/storage.allocated.external.image";
99 static const wchar_t* _STORAGE_ALLOCATED_EXTERNAL_DOWNLOAD = L"http://tizen.org/runtime/storage.allocated.external.download";
100
101 static const wchar_t _BOOT_STATUS_KEY[] = L"http://tizen.org/runtime/system.status";
102 static const wchar_t _BOOT_STATUS_INITIALIZING[] = L"initializing";
103 static const wchar_t _BOOT_STATUS_READY[]  = L"ready";
104
105
106 static const int _RUNTIME_INFO_EVENT_TYPE_INT = 101;
107 static const int _RUNTIME_INFO_EVENT_TYPE_LONGLONG = 102;
108
109
110 static const char* const _PROC_SYSTEM_MEMORY_INFO = "/proc/meminfo";
111 static const char* const _PROC_PROCESS_MEMORY_INFO = "/proc/self/status";
112 static const char* const _PROC_STAT = "/proc/stat";
113
114 static const char* const _PROC_KEY_SYSTEM_MEMORY_TOTAL = "MemTotal";
115 static const char* const _PROC_KEY_SYSTEM_MEMORY_FREE = "MemFree";
116 static const char* const _PROC_KEY_PROCESS_MEMORY = "VmSize";
117
118 static const char* const _ROOT_PATH = "/";
119
120 static const int _MAX_BUFFER_LENGTH = 1024;
121
122 static const int _CPU_USAGE_EVALUATION_INTERVAL = 1000000; //1 sec
123
124 typedef struct {
125     char cpu[20];
126     unsigned long long user;
127     unsigned long long system;
128     unsigned long long nice;
129     unsigned long long idle;
130     unsigned long long wait;
131     unsigned long long hi;
132     unsigned long long si;
133     unsigned long long zero;
134 } procstat_t;
135
136 bool read_proc_stat(procstat_t *p)
137 {
138         FILE *fp = null;
139         int ret = 0;
140
141         fp = fopen(_PROC_STAT, "r");
142         if(fp == null)
143         {
144                 return false;
145         }
146
147         ret = fscanf(fp, "%s %llu %llu %llu %llu %llu %llu %llu %llu",
148         p->cpu,
149         &p->user,
150         &p->system,
151         &p->nice,
152         &p->idle,
153         &p->wait,
154         &p->hi,
155         &p->si,
156         &p->zero);
157
158         if(ret < 1)
159         {
160                 if(fp != null)
161                 {
162                         fclose(fp);
163                 }
164                 return false;
165         }
166
167         if(fp != null)
168         {
169                 fclose(fp);
170         }
171
172         return true;
173 }
174  
175 void diff_proc_stat(procstat_t *a, procstat_t *b, procstat_t *d)
176 {
177         d->user     = a->user   - b->user;
178         d->system   = a->system - b->system;
179         d->nice     = a->nice   - b->nice;
180         d->idle     = a->idle   - b->idle;
181         d->wait     = a->wait   - b->wait;
182         d->hi       = a->hi     - b->hi;
183         d->si       = a->si     - b->si;
184         d->zero     = a->zero   - b->zero;
185 }
186
187 class _RuntimeInfoEventArg : public IEventArg
188 {
189 public:
190         _RuntimeInfoEventArg()
191         : Type(0)
192         , intValue(0)
193         , longLongValue(0)
194         , errorCode(E_SUCCESS)
195         , DirectoryPath(null)
196         , pListener(null)
197         {
198         }
199
200         ~_RuntimeInfoEventArg()
201         {
202                 if(DirectoryPath != null)
203                 {
204                         delete [] DirectoryPath;
205                 }
206         }
207
208         int Type;
209         int intValue;
210         long long longLongValue;
211         result errorCode;
212         char* DirectoryPath;
213         IEventListener* pListener;
214 };
215
216 class _RuntimeInfoEvent : public Event
217 {
218 protected:
219         void FireImpl(IEventListener& listener, const IEventArg& arg)
220         {
221                 const _RuntimeInfoEventArg* runtimeArg = dynamic_cast<const _RuntimeInfoEventArg*> (&arg);
222
223                 if(runtimeArg == null)
224                 {
225                         SysLogException(NID_SYS, E_SYSTEM, "Argument is null.");
226                         return;
227                 }
228
229                 switch(runtimeArg->Type)
230                 {
231                 case _RUNTIME_INFO_EVENT_TYPE_INT:
232                 {
233                         IRuntimeInfoGetIntAsyncResultListener* pIntListener = dynamic_cast<IRuntimeInfoGetIntAsyncResultListener*>(&listener);
234
235                         if(pIntListener == runtimeArg->pListener)
236                         {                               
237                                 pIntListener->OnResultReceivedForGetValueAsync(runtimeArg->intValue, runtimeArg->errorCode);
238                                 RemoveListener(listener);
239                         }
240                 }
241                 break;
242                 case _RUNTIME_INFO_EVENT_TYPE_LONGLONG:
243                 {
244                         IRuntimeInfoGetLonglongAsyncResultListener* pLonglongListener = dynamic_cast<IRuntimeInfoGetLonglongAsyncResultListener*>(&listener);
245                         if(pLonglongListener == runtimeArg->pListener)
246                         {
247                                 pLonglongListener->OnResultReceivedForGetValueAsync(runtimeArg->longLongValue, runtimeArg->errorCode);
248                                 RemoveListener(listener);
249                         }
250                 }
251                 break;
252                 }
253         }
254 };
255
256 _RuntimeInfoEvent runtimeInfoEvent;
257
258 _RuntimeInfoImpl::_RuntimeInfoImpl(void)
259 {
260 }
261
262 _RuntimeInfoImpl::~_RuntimeInfoImpl(void)
263 {
264 }
265
266 result
267 _RuntimeInfoImpl::GetValue(const String& key, String& value)
268 {
269         if (key == _BOOT_STATUS_KEY)
270         {
271                 int bootReady = -1;
272                 const int errorCode = vconf_get_int(VCONFKEY_SERVICE_READY, &bootReady);
273                 if (errorCode != 0)
274                 {
275                         value = (bootReady == 1 ) ? _BOOT_STATUS_READY : _BOOT_STATUS_INITIALIZING;
276
277                         return E_SUCCESS;
278                 }
279
280                 return E_SYSTEM;
281         }
282         else
283         {
284                 return E_OBJ_NOT_FOUND;
285         }
286 }
287
288 result
289 _RuntimeInfoImpl::GetValue(const String& key, int& value)
290 {
291         int total_size = 0;
292         int free_size =0;
293         result r = E_OBJ_NOT_FOUND;
294
295         if (key == _BATTERY_LEVEL)
296         {
297                 return GetBatteryLevel(value);
298         }
299         else if (key == _ALLOCATED_MEMORY || key == _ALLOCATED_VIDEO_MEMORY)
300         {
301                 r = GetFromProc(_PROC_PROCESS_MEMORY_INFO, _PROC_KEY_PROCESS_MEMORY, free_size);
302                 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get memory size.");
303                 value = free_size * 1024;
304         }
305         else if (key == _AVAILABLE_MEMORY || key == _AVAILABLE_VIDEO_MEMORY || key == _MAX_ALLOCATABLE_MEMORY)
306         {
307                 r = GetFromProc(_PROC_SYSTEM_MEMORY_INFO, _PROC_KEY_SYSTEM_MEMORY_FREE, free_size);
308                 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get memory size.");
309                 value = free_size * 1024;
310         }
311         return r;
312 }
313
314 result
315 _RuntimeInfoImpl::GetValue(const String& key, long long& value)
316 {
317
318         long long total_size = 0;
319         long long free_size =0;
320         result r = E_OBJ_NOT_FOUND;
321
322         if (key == _MEMORY_AVAILABLE || key == _MEMORY_AVAILABLE_VIDEO)
323         {
324                 r = GetFromProcLonglong(_PROC_SYSTEM_MEMORY_INFO, _PROC_KEY_SYSTEM_MEMORY_FREE, free_size);
325                 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get memory size.");
326                 value = free_size * 1024;
327         }
328         else if (key == _MEMORY_ALLOCATED || key == _MEMORY_ALLOCATED_VIDEO)
329         {
330                 r = GetFromProcLonglong(_PROC_SYSTEM_MEMORY_INFO, _PROC_KEY_SYSTEM_MEMORY_TOTAL, total_size);
331                 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get memory size.");
332                 r = GetFromProcLonglong(_PROC_SYSTEM_MEMORY_INFO, _PROC_KEY_SYSTEM_MEMORY_FREE, free_size);
333                 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get memory size.");
334                 value = (total_size - free_size) * 1024;
335         }
336         else if (key == _MEMORY_ALLOCATED_SELF)
337         {   
338                 r = GetFromProcLonglong(_PROC_PROCESS_MEMORY_INFO, _PROC_KEY_PROCESS_MEMORY, free_size);
339                 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get memory size.");
340                 value = free_size * 1024;
341         } 
342         else if (key == _AVAILABLE_INTERNAL_STORAGE)
343         {
344                 return GetAvailableInternalStorage(value);
345         }
346         else if (key == _AVAILABLE_EXTERNAL_STORAGE)
347         {
348                 return GetAvailableExternalStorage(value);
349         }
350         else if (key == _AVAILABLE_MEDIA_STORAGE)
351         {
352                 return GetAvailableMediaStorage(value);
353         }
354         else if(key == _STORAGE_AVAILABLE_INTERNAL)
355         {
356                 return GetAvailableInternalStorage(value);
357         }
358         else if(key == _STORAGE_AVAILABLE_EXTERNAL)
359         {
360                 return GetAvailableExternalStorage(value);
361         }
362         else if(key == _STORAGE_AVAILABLE_INTERNAL_MEDIA)
363         {
364                 return GetAvailableMediaStorage(value);
365         }
366         else
367         {
368                 SysLogException(NID_SYS, r, "Key[%ls] is not valid.", key.GetPointer());
369         }
370         return r;
371 }
372
373 long long
374 _RuntimeInfoImpl::GetDirectorySize(const char* path)
375 {
376         if(path == null)
377         {
378                 return 0;
379         }
380
381         char* pCommand = null;
382         char* pFileName = null;
383         int fileLength = 0;
384         int commandLength = 0;
385         long long size = 0;
386         int ret = 0;
387         FILE* pFile = null;
388
389         Tizen::App::App* pApp = Tizen::App::App::GetInstance();
390         if(pApp == null)
391         {
392                 return 0;
393         }
394
395         String appId(pApp->GetAppId());
396         unique_ptr <char[]> appIdPath(_StringConverter::CopyToCharArrayN(appId));
397
398         fileLength = strlen(appIdPath.get()) + 29;
399         pFileName = (char*)malloc(fileLength);
400         SysTryCatch(NID_SYS, pFileName, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "It is not enough memory.");
401
402         ret = sprintf(pFileName, "/tmp/size_of_directory_%s.tmp", appIdPath.get());
403         SysTryCatch(NID_SYS, ret > 0, E_SYSTEM, E_SYSTEM, "It is failed to write file path.");
404
405         commandLength = strlen(pFileName) + 8;
406         pCommand = (char*) malloc(commandLength);
407         SysTryCatch(NID_SYS, pCommand, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "It is not enough memory.");
408
409         ret = sprintf(pCommand, "rm -rf %s", pFileName);
410         SysTryCatch(NID_SYS, ret > 0, E_SYSTEM, E_SYSTEM, "It is failed to write remove pCommand.");
411
412         ret = system(pCommand);
413         if(ret == -1)
414         {
415                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to execute pCommand[%s].", pCommand);
416         }
417         free(pCommand);
418         pCommand = null;
419
420         commandLength = strlen(pFileName) + strlen(path) + 16;
421         pCommand = (char*)malloc(commandLength);
422         SysTryCatch(NID_SYS, pCommand, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "It is not enough memory.");
423
424         ret = sprintf(pCommand, "du -skb -P %s >> %s", path, pFileName);
425         SysTryCatch(NID_SYS, ret > 0, E_SYSTEM, E_SYSTEM, "It is failed to write du pCommand.");
426
427         ret = system(pCommand);
428         SysTryCatch(NID_SYS, ret != -1, E_SYSTEM, E_SYSTEM, "It is failed to execute pCommand[%s].", pCommand);
429
430         pFile = fopen(pFileName, "r");
431         SysTryCatch(NID_SYS, pFile != null, E_SYSTEM, E_SYSTEM, "It is failed to read file [%s].", pFileName);
432
433         ret = fscanf(pFile, "%lld", &size);
434         SysTryCatch(NID_SYS, ret > 0, E_SYSTEM, E_SYSTEM, "It is failed to read file [%s].", pFileName);
435
436         ret = sprintf(pCommand, "rm -rf %s", pFileName);
437         SysTryCatch(NID_SYS, ret > 0, E_SYSTEM, E_SYSTEM, "It is failed to write remove pCommand.");
438
439         ret = system(pCommand);
440         SysTryCatch(NID_SYS, ret != -1, E_SYSTEM, E_SYSTEM, "It is failed to execute pCommand[%s].", pCommand);
441
442 CATCH:
443         if (pFileName)
444         {
445                 free(pFileName);
446         }
447         if (pCommand)
448         {
449                 free(pCommand);
450         }
451         if (pFile)
452         {
453                 fclose(pFile);
454         }
455         return size;
456 }
457
458 result
459 _RuntimeInfoImpl::GetValue(const String& key, double& value)
460 {
461         return E_OBJ_NOT_FOUND;
462 }
463
464 result
465 _RuntimeInfoImpl::GetValue(const String& key, bool& value)
466 {
467         if (key == _CHARGING)
468         {
469                 return IsChargingMode(value);
470         }
471         else
472         {
473                 return E_OBJ_NOT_FOUND;
474         }
475 }
476
477 result
478 _RuntimeInfoImpl::GetValue(const String& key, UuId& value)
479 {
480         return E_OBJ_NOT_FOUND;
481 }
482
483 result
484 _RuntimeInfoImpl::GetBatteryLevel(int& value)
485 {
486         int batteryValue = -1;
487         batteryValue = device_get_battery_pct();
488         SysTryReturnResult(NID_SYS, !(batteryValue < 0 || value > 100), E_SYSTEM, "[E_SYSTEM] device_get_battery_pct return %d", batteryValue);
489         value = batteryValue;
490
491         return E_SUCCESS;
492 }
493
494 result
495 _RuntimeInfoImpl::IsChargingMode(bool& value)
496 {
497         bool chargeState = false;
498         int ret = 0;
499         ret = runtime_info_get_value_bool(RUNTIME_INFO_KEY_BATTERY_IS_CHARGING, &chargeState);
500         SysTryReturnResult(NID_SYS, ret == 0, E_SYSTEM, "[E_SYSTEM] runtime_info_get_value_bool returns %d.", ret);
501         value = chargeState;
502         return E_SUCCESS;
503
504 }
505
506 result
507 _RuntimeInfoImpl::GetAvailableInternalStorage(long long& value)
508 {
509         long long total = 0;
510         result r = E_SUCCESS;
511
512         r = GetCapacity(_ROOT_PATH, total, value);
513         SysTryReturn(NID_SYS, !IsFailed(r), E_SYSTEM, r, "[E_SYSTEM] system error has occurred. ");
514
515         return E_SUCCESS;
516 }
517 result
518 _RuntimeInfoImpl::GetAvailableExternalStorage(long long& value)
519 {
520         int sdCardStatus = 0;
521         int ret = -1;
522         long long total = 0;
523
524         ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &sdCardStatus);
525         SysTryReturn(NID_SYS, !(ret < 0), E_SYSTEM, E_SYSTEM, "[E_SYSTEM] vconf_get_int VCONFKEY_SYSMAN_MMC_STATUS failed");
526
527         if(sdCardStatus == 0)
528         {
529                 value = 0;
530                 return E_SUCCESS;
531         }
532         char* directoryPath = _StringConverter::CopyToCharArrayN(_EnvironmentImpl::GetExternalStoragePath());
533         SysTryReturnResult(NID_SYS, directoryPath != null, E_SYSTEM, "It is failed to get external directory path.");
534         result r = GetCapacity(directoryPath, total, value);
535         delete [] directoryPath;
536         return r ;
537 }
538
539 result
540 _RuntimeInfoImpl::GetAvailableMediaStorage(long long& value)
541 {
542         long long total = 0;
543
544         char* directoryPath = _StringConverter::CopyToCharArrayN(_EnvironmentImpl::GetMediaPath());
545         SysTryReturnResult(NID_SYS, directoryPath != null, E_SYSTEM, "It is failed to get media directory path.");
546         result r = GetCapacity(directoryPath, total, value);
547         delete [] directoryPath;
548         return r;
549 }
550
551 result
552 _RuntimeInfoImpl::GetCapacity(const char* path, long long& totalSize, long long& availableSize)
553 {
554         struct statfs fs;
555         if (statfs(path, &fs) < 0)
556         {
557                 SysLogException(NID_SYS, E_SYSTEM, "[E_SYSTEM] statfs() failed");
558                 return E_SYSTEM;
559         }
560
561         totalSize = static_cast< long long >(fs.f_bsize) * static_cast< long long >(fs.f_blocks);
562         availableSize = static_cast< long long >(fs.f_bsize) * static_cast< long long >(fs.f_bavail);
563
564         return E_SUCCESS;
565 }
566
567 result
568 _RuntimeInfoImpl::GetFromProcLonglong(const char* path, const char* key, long long& value)
569 {
570         FILE* pStream = null;
571         char line[_MAX_BUFFER_LENGTH] = {0, };
572         char fieldName[_MAX_BUFFER_LENGTH] = {0, };
573         long long keyValue = 0;
574         pStream = fopen(path, "r");
575         SysTryReturnResult(NID_SYS, pStream != null, E_SYSTEM, "%s open is failed.", path);
576
577         while (fgets(line, sizeof(line), pStream))
578         {
579                 if (sscanf(line, "%s %lld %*s", fieldName, &keyValue) == 2)
580                 {
581                         if (strncmp(fieldName, key, static_cast< int >(strlen(key))) == 0)
582                         {
583                                 value = keyValue;
584                                 fclose(pStream);
585                                 return E_SUCCESS;
586                         }
587                 }
588         }
589         fclose(pStream);
590
591         SysLogException(NID_SYS, E_OBJ_NOT_FOUND, "it can't find %s field", key);
592         return E_OBJ_NOT_FOUND;
593 }
594
595 result
596 _RuntimeInfoImpl::GetFromProc(const char* path, const char* key, int& value)
597 {
598         FILE* pStream = null;
599         char line[_MAX_BUFFER_LENGTH] = {0, };
600         char fieldName[_MAX_BUFFER_LENGTH] = {0, };
601         int keyValue = 0;
602         pStream = fopen(path, "r");
603         SysTryReturnResult(NID_SYS, pStream != null, E_SYSTEM, "%s open is failed.", path);
604
605         while (fgets(line, sizeof(line), pStream))
606         {
607                 if (sscanf(line, "%s %d %*s", fieldName, &keyValue) == 2)
608                 {
609                         if (strncmp(fieldName, key, static_cast< int >(strlen(key))) == 0)
610                         {
611                                 value = keyValue;
612                                 fclose(pStream);
613                                 return E_SUCCESS;
614                         }
615                 }
616         }
617         fclose(pStream);
618
619         SysLogException(NID_SYS, E_OBJ_NOT_FOUND, "it can't find %s field", key);
620         return E_OBJ_NOT_FOUND;
621 }
622
623 void*
624 _RuntimeInfoImpl::GetDirectorySizeAsync(void* data)
625 {       
626         if(data == null)
627         {               
628                 return null;
629         }
630         _RuntimeInfoEventArg* pEventArg = (_RuntimeInfoEventArg*)data;
631         long long size = _RuntimeInfoImpl::GetDirectorySize(pEventArg->DirectoryPath);
632
633         if(pEventArg == null)
634         {
635                 SysLogException(NID_SYS, E_OUT_OF_MEMORY, "It is failed to create instance of _RuntimeInfoEventArg");
636                 return null;
637         }
638         pEventArg->Type = _RUNTIME_INFO_EVENT_TYPE_LONGLONG;
639         pEventArg->longLongValue = size;
640         SysLog(NID_SYS, "Fire event %x %s %lld", pEventArg, pEventArg->DirectoryPath, size);
641         runtimeInfoEvent.Fire(*pEventArg);
642         
643         return null;
644 }
645
646 void*
647 _RuntimeInfoImpl::GetCpuUsageAsync(void* data)
648 {
649         result r = E_SUCCESS;
650
651         int value = 0;
652         procstat_t first, second, diffrence;
653         unsigned long long total, usage;
654
655         if(read_proc_stat(&first) != false)
656         {
657                 usleep(_CPU_USAGE_EVALUATION_INTERVAL);
658                 if(read_proc_stat(&second) != false)
659                 {
660                         diff_proc_stat(&second, &first, &diffrence);
661                         total = diffrence.user + diffrence.system 
662                                 + diffrence.nice + diffrence.idle 
663                                 + diffrence.wait + diffrence.hi 
664                                 + diffrence.si;
665                         usage = 10000 - (diffrence.idle * 10000 / total);
666                         value = usage/100;
667                         r = E_SUCCESS;
668                 }
669                 else
670                 {
671                         r = E_SYSTEM;
672                 }
673         }
674         else
675         {
676                 r = E_SYSTEM;
677         }
678
679         _RuntimeInfoEventArg* pEventArg = (_RuntimeInfoEventArg*) data;
680         if(pEventArg == null)
681         {
682                 SysLogException(NID_SYS, E_OUT_OF_MEMORY, "It is failed to create instance of _RuntimeInfoEventArg");
683                 return null;
684         }
685         pEventArg->errorCode = r;
686         pEventArg->Type = _RUNTIME_INFO_EVENT_TYPE_INT;
687         pEventArg->intValue = value;
688
689         runtimeInfoEvent.Fire(*pEventArg);
690
691         return null;
692 }
693
694 result
695 _RuntimeInfoImpl::GetValueAsync(const String& key, IRuntimeInfoGetIntAsyncResultListener* listener)
696 {
697         result r = E_SUCCESS;
698
699         SysTryReturnResult(NID_SYS, listener != null, E_INVALID_ARG, "listener is null");
700
701         if (key == _CPU_CORE_ALL_USAGE)
702         {
703                 if(listener != null)
704                 {
705                         runtimeInfoEvent.AddListener(*listener);
706                 }
707
708                 int thr_id = 0;
709                 pthread_t p_thread;
710                 _RuntimeInfoEventArg* pEventArg = new (std::nothrow) _RuntimeInfoEventArg();
711                 pEventArg->pListener = listener;
712                 thr_id = pthread_create(&p_thread, null, GetCpuUsageAsync, pEventArg);
713                 pthread_detach(p_thread);
714         }
715         else
716         {
717                 SysLogException(NID_SYS, E_INVALID_ARG, "Required key[%ls] is not valid", key.GetPointer());
718                 r = E_INVALID_ARG;
719         }
720         return r;
721 }
722
723 result
724 _RuntimeInfoImpl::GetValueAsync(const String& key, IRuntimeInfoGetLonglongAsyncResultListener* listener)
725 {
726         int thr_id = 0;
727         pthread_t p_thread;
728         result r = E_SUCCESS;
729         String directoryPath;
730
731         SysTryReturnResult(NID_SYS, listener != null, E_INVALID_ARG, "listener is null");
732
733         if(key == _STORAGE_ALLOCATED_INTERNAL_APPLICATION)
734         {
735                 directoryPath.Append(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_APPLICATIONS));
736         }       
737         else if (key == _STORAGE_ALLOCATED_INTERNAL_AUDIO)
738         {
739                 directoryPath.Append(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_SOUNDS));
740         }
741         else if (key == _STORAGE_ALLOCATED_INTERNAL_VIDEO)
742         {
743                 directoryPath.Append(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_VIDEOS));
744         }
745         else if (key == _STORAGE_ALLOCATED_INTERNAL_IMAGE)
746         {
747                 directoryPath.Append(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_IMAGES));
748         }
749         else if (key == _STORAGE_ALLOCATED_INTERNAL_DOWNLOAD)
750         {
751                 directoryPath.Append(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_DOWNLOADS));
752         }
753         else if (key == _STORAGE_ALLOCATED_EXTERNAL_APPLICATION)
754         {
755                 directoryPath.Append(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_EXTERNAL_APPLICATIONS));
756         }
757         else if (key == _STORAGE_ALLOCATED_EXTERNAL_AUDIO)
758         {
759                 directoryPath.Append(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_EXTERNAL_SOUNDS));
760         }
761         else if (key == _STORAGE_ALLOCATED_EXTERNAL_VIDEO)
762         {
763                 directoryPath.Append(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_EXTERNAL_VIDEOS));
764         }
765         else if (key == _STORAGE_ALLOCATED_EXTERNAL_IMAGE)
766         {
767                 directoryPath.Append(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_EXTERNAL_IMAGES));
768         }
769         else if (key == _STORAGE_ALLOCATED_EXTERNAL_DOWNLOAD)
770         {
771                 directoryPath.Append(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_EXTERNAL_DOWNLOADS));
772         }
773         else
774         {
775                 SysLogException(NID_SYS, E_INVALID_ARG, "Required key[%ls] is not valid", key.GetPointer());
776                 r = E_INVALID_ARG;
777         }
778
779         SysLog(NID_SYS, "%s", GetErrorMessage(r));
780         SysLog(NID_SYS, "%ls", directoryPath.GetPointer());
781         if(r == E_SUCCESS)
782         {
783                 _RuntimeClient* pRuntimeClient = _RuntimeClient::GetInstance();
784                 pRuntimeClient->GetDirectorySizeValueAsync(directoryPath, listener);
785         }
786
787         return r;
788 }
789
790 _RuntimeInfoImpl*
791 _RuntimeInfoImpl::GetInstance(RuntimeInfo& runtimeinfo)
792 {
793         return runtimeinfo.__pRuntimeInfoImpl;
794 }
795
796 const _RuntimeInfoImpl*
797 _RuntimeInfoImpl::GetInstance(const RuntimeInfo& runtimeinfo)
798 {
799         return runtimeinfo.__pRuntimeInfoImpl;
800 }
801
802 } } //Tizen::System
803