2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file FSysRuntimeInfo.cpp
20 * @brief This is the implementation file for _RuntimeInfoImpl class.
23 * This file contains the implementation of _RuntimeInfoImpl class.
26 #include <unique_ptr.h>
33 #include <app_storage.h>
35 #include <runtime_info.h>
38 #include <FBaseRtEvent.h>
39 #include <FBaseRtIEventArg.h>
40 #include <FBaseRtIEventListener.h>
41 #include <FBaseRtThread.h>
42 #include <FBaseSysLog.h>
43 #include <FApp_AppInfo.h>
44 #include <FBase_StringConverter.h>
45 #include <FSys_EnvironmentImpl.h>
46 #include <FSys_RuntimeInfoImpl.h>
48 using namespace Tizen::App;
49 using namespace Tizen::Base;
50 using namespace Tizen::Base::Runtime;
54 namespace Tizen { namespace System
57 static const wchar_t* _ALLOCATED_MEMORY = L"AllocatedMemory";
58 static const wchar_t* _MEMORY_ALLOCATED = L"http://tizen.org/runtime/memory.allocated";
59 static const wchar_t* _MEMORY_ALLOCATED_SELF = L"http://tizen.org/runtime/memory.allocated.self";
61 static const wchar_t* _AVAILABLE_EXTERNAL_STORAGE = L"AvailableExternalStorage";
62 static const wchar_t* _STORAGE_AVAILABLE_EXTERNAL = L"http://tizen.org/runtime/storage.available.external";
64 static const wchar_t* _AVAILABLE_INTERNAL_STORAGE = L"AvailableInternalStorage";
65 static const wchar_t* _STORAGE_AVAILABLE_INTERNAL = L"http://tizen.org/runtime/storage.available.internal";
67 static const wchar_t* _AVAILABLE_MEDIA_STORAGE = L"AvailableMediaStorage";
68 static const wchar_t* _STORAGE_AVAILABLE_INTERNAL_MEDIA = L"http://tizen.org/runtime/storage.available.internal.media";
70 static const wchar_t* _BATTERY_LEVEL = L"BatteryLevel";
71 static const wchar_t* _CHARGING = L"IsCharging";
73 static const wchar_t* _CPU_CORE_ALL_USAGE = L"http://tizen.org/runtime/cpu.core.all.usage";
75 static const wchar_t* _MAX_ALLOCATABLE_MEMORY = L"MaxAllocatableMemory";
76 static const wchar_t* _AVAILABLE_VIDEO_MEMORY = L"AvailableVideoMemory";
77 static const wchar_t* _ALLOCATED_VIDEO_MEMORY = L"AllocatedVideoMemory";
78 static const wchar_t* _AVAILABLE_MEMORY = L"AvailableMemory";
79 static const wchar_t* _MEMORY_AVAILABLE = L"http://tizen.org/runtime/memory.available";
80 static const wchar_t* _MEMORY_AVAILABLE_VIDEO = L"http://tizen.org/runtime/memory.available.video";
81 static const wchar_t* _MEMORY_ALLOCATED_VIDEO = L"http://tizen.org/runtime/memory.allocated.video";
83 static const wchar_t* _STORAGE_ALLOCATED_INTERNAL_APPLICATION = L"http://tizen.org/runtime/storage.allocated.internal.application";
84 static const wchar_t* _STORAGE_ALLOCATED_INTERNAL_AUDIO = L"http://tizen.org/runtime/storage.allocated.internal.audio";
85 static const wchar_t* _STORAGE_ALLOCATED_INTERNAL_VIDEO = L"http://tizen.org/runtime/storage.allocated.internal.video";
86 static const wchar_t* _STORAGE_ALLOCATED_INTERNAL_IMAGE = L"http://tizen.org/runtime/storage.allocated.internal.image";
87 static const wchar_t* _STORAGE_ALLOCATED_INTERNAL_DOWNLOAD = L"http://tizen.org/runtime/storage.allocated.internal.download";
88 static const wchar_t* _STORAGE_ALLOCATED_EXTERNAL_APPLICATION = L"http://tizen.org/runtime/storage.allocated.external.application";
89 static const wchar_t* _STORAGE_ALLOCATED_EXTERNAL_AUDIO = L"http://tizen.org/runtime/storage.allocated.external.audio";
90 static const wchar_t* _STORAGE_ALLOCATED_EXTERNAL_VIDEO = L"http://tizen.org/runtime/storage.allocated.external.video";
91 static const wchar_t* _STORAGE_ALLOCATED_EXTERNAL_IMAGE = L"http://tizen.org/runtime/storage.allocated.external.image";
92 static const wchar_t* _STORAGE_ALLOCATED_EXTERNAL_DOWNLOAD = L"http://tizen.org/runtime/storage.allocated.external.download";
94 static const int _RUNTIME_INFO_EVENT_TYPE_INT = 101;
95 static const int _RUNTIME_INFO_EVENT_TYPE_LONGLONG = 102;
98 static const char* const _PROC_SYSTEM_MEMORY_INFO = "/proc/meminfo";
99 static const char* const _PROC_PROCESS_MEMORY_INFO = "/proc/self/status";
100 static const char* const _PROC_STAT = "/proc/stat";
102 static const char* const _PROC_KEY_SYSTEM_MEMORY_TOTAL = "MemTotal";
103 static const char* const _PROC_KEY_SYSTEM_MEMORY_FREE = "MemFree";
104 static const char* const _PROC_KEY_PROCESS_MEMORY = "VmSize";
106 static const char* const _ROOT_PATH = "/";
107 static const char* const _STORAGE_PATH = "/opt/storage/sdcard";
108 static const char* const _MEDIA_PATH = "/opt/usr/media";
109 static const char* const _INTERNAL_PATH = "/opt";
111 static const int _MAX_BUFFER_LENGTH = 1024;
113 static const int _CPU_USAGE_EVALUATION_INTERVAL = 1000000; //1 sec
117 unsigned long long user;
118 unsigned long long system;
119 unsigned long long nice;
120 unsigned long long idle;
121 unsigned long long wait;
122 unsigned long long hi;
123 unsigned long long si;
124 unsigned long long zero;
127 bool read_proc_stat(procstat_t *p)
132 fp = fopen(_PROC_STAT, "r");
138 ret = fscanf(fp, "%s %llu %llu %llu %llu %llu %llu %llu %llu",
166 void diff_proc_stat(procstat_t *a, procstat_t *b, procstat_t *d)
168 d->user = a->user - b->user;
169 d->system = a->system - b->system;
170 d->nice = a->nice - b->nice;
171 d->idle = a->idle - b->idle;
172 d->wait = a->wait - b->wait;
173 d->hi = a->hi - b->hi;
174 d->si = a->si - b->si;
175 d->zero = a->zero - b->zero;
178 class _RuntimeInfoEventArg : public IEventArg
181 _RuntimeInfoEventArg()
185 , errorCode(E_SUCCESS)
186 , DirectoryPath(null)
191 ~_RuntimeInfoEventArg()
193 if(DirectoryPath != null)
195 delete [] DirectoryPath;
201 long long longLongValue;
204 IEventListener* pListener;
207 class _RuntimeInfoEvent : public Event
210 void FireImpl(IEventListener& listener, const IEventArg& arg)
212 const _RuntimeInfoEventArg* runtimeArg = dynamic_cast<const _RuntimeInfoEventArg*> (&arg);
214 if(runtimeArg == null)
216 SysLogException(NID_SYS, E_SYSTEM, "Argument is null.");
220 switch(runtimeArg->Type)
222 case _RUNTIME_INFO_EVENT_TYPE_INT:
224 IRuntimeInfoGetIntAsyncResultListener* pIntListener = dynamic_cast<IRuntimeInfoGetIntAsyncResultListener*>(&listener);
226 if(pIntListener == runtimeArg->pListener)
228 pIntListener->OnResultReceivedForGetValueAsync(runtimeArg->intValue, runtimeArg->errorCode);
229 RemoveListener(listener);
233 case _RUNTIME_INFO_EVENT_TYPE_LONGLONG:
235 IRuntimeInfoGetLonglongAsyncResultListener* pLonglongListener = dynamic_cast<IRuntimeInfoGetLonglongAsyncResultListener*>(&listener);
236 if(pLonglongListener == runtimeArg->pListener)
238 pLonglongListener->OnResultReceivedForGetValueAsync(runtimeArg->longLongValue, runtimeArg->errorCode);
239 RemoveListener(listener);
247 _RuntimeInfoEvent runtimeInfoEvent;
249 _RuntimeInfoImpl::_RuntimeInfoImpl(void)
253 _RuntimeInfoImpl::~_RuntimeInfoImpl(void)
258 _RuntimeInfoImpl::GetValue(const String& key, String& value)
260 return E_OBJ_NOT_FOUND;
264 _RuntimeInfoImpl::GetValue(const String& key, int& value)
268 result r = E_OBJ_NOT_FOUND;
270 if (key == _BATTERY_LEVEL)
272 return GetBatteryLevel(value);
274 else if (key == _ALLOCATED_MEMORY || key == _ALLOCATED_VIDEO_MEMORY)
276 r = GetFromProc(_PROC_PROCESS_MEMORY_INFO, _PROC_KEY_PROCESS_MEMORY, free_size);
277 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get memory size.");
278 value = free_size * 1024;
280 else if (key == _AVAILABLE_MEMORY || key == _AVAILABLE_VIDEO_MEMORY || key == _MAX_ALLOCATABLE_MEMORY)
282 r = GetFromProc(_PROC_SYSTEM_MEMORY_INFO, _PROC_KEY_SYSTEM_MEMORY_FREE, free_size);
283 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get memory size.");
284 value = free_size * 1024;
290 _RuntimeInfoImpl::GetValue(const String& key, long long& value)
293 long long total_size = 0;
294 long long free_size =0;
295 result r = E_OBJ_NOT_FOUND;
297 if (key == _MEMORY_AVAILABLE || key == _MEMORY_AVAILABLE_VIDEO)
299 r = GetFromProcLonglong(_PROC_SYSTEM_MEMORY_INFO, _PROC_KEY_SYSTEM_MEMORY_FREE, free_size);
300 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get memory size.");
301 value = free_size * 1024;
303 else if (key == _MEMORY_ALLOCATED || key == _MEMORY_ALLOCATED_VIDEO)
305 r = GetFromProcLonglong(_PROC_SYSTEM_MEMORY_INFO, _PROC_KEY_SYSTEM_MEMORY_TOTAL, total_size);
306 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get memory size.");
307 r = GetFromProcLonglong(_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 = (total_size - free_size) * 1024;
311 else if (key == _MEMORY_ALLOCATED_SELF)
313 r = GetFromProcLonglong(_PROC_PROCESS_MEMORY_INFO, _PROC_KEY_PROCESS_MEMORY, free_size);
314 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get memory size.");
315 value = free_size * 1024;
317 else if (key == _AVAILABLE_INTERNAL_STORAGE)
319 return GetAvailableInternalStorage(value);
321 else if (key == _AVAILABLE_EXTERNAL_STORAGE)
323 return GetAvailableExternalStorage(value);
325 else if (key == _AVAILABLE_MEDIA_STORAGE)
327 return GetAvailableMediaStorage(value);
329 else if(key == _STORAGE_AVAILABLE_INTERNAL)
331 return GetAvailableInternalStorage(value);
333 else if(key == _STORAGE_AVAILABLE_EXTERNAL)
335 return GetAvailableExternalStorage(value);
337 else if(key == _STORAGE_AVAILABLE_INTERNAL_MEDIA)
339 return GetAvailableMediaStorage(value);
343 SysLogException(NID_SYS, r, "Key[%ls] is not valid.", key.GetPointer());
349 _RuntimeInfoImpl::GetDirectorySize(const char* path)
356 char command[512] = {0,};
360 sprintf(command, "du -sk -P %s >> /tmp/size_of_directory.tmp", path);
362 system("rm -rf /tmp/size_of_directory.tmp");
366 pFile = fopen("/tmp/size_of_directory.tmp", "r");
371 ret = fscanf(pFile, "%lld", &size);
387 system("rm -rf /tmp/size_of_directory.tmp");
392 _RuntimeInfoImpl::GetValue(const String& key, double& value)
394 return E_OBJ_NOT_FOUND;
398 _RuntimeInfoImpl::GetValue(const String& key, bool& value)
400 if (key == _CHARGING)
402 return IsChargingMode(value);
406 return E_OBJ_NOT_FOUND;
411 _RuntimeInfoImpl::GetValue(const String& key, UuId& value)
413 return E_OBJ_NOT_FOUND;
417 _RuntimeInfoImpl::GetBatteryLevel(int& value)
419 int batteryValue = -1;
420 batteryValue = device_get_battery_pct();
421 SysTryReturnResult(NID_SYS, !(batteryValue < 0 || value > 100), E_SYSTEM, "[E_SYSTEM] device_get_battery_pct return %d", batteryValue);
422 value = batteryValue;
428 _RuntimeInfoImpl::IsChargingMode(bool& value)
430 bool chargeState = false;
432 ret = runtime_info_get_value_bool(RUNTIME_INFO_KEY_BATTERY_IS_CHARGING, &chargeState);
433 SysTryReturnResult(NID_SYS, ret == 0, E_SYSTEM, "[E_SYSTEM] runtime_info_get_value_bool returns %d.", ret);
440 _RuntimeInfoImpl::GetAvailableInternalStorage(long long& value)
444 result r = E_SUCCESS;
446 r = GetCapacity(_ROOT_PATH, total, temp);
447 SysTryReturn(NID_SYS, !IsFailed(r), E_SYSTEM, r, "[E_SYSTEM] system error has occurred. ");
451 r = GetCapacity(_INTERNAL_PATH, total, temp);
452 SysTryReturn(NID_SYS, !IsFailed(r), E_SYSTEM, r, "[E_SYSTEM] system error has occurred. ");
459 _RuntimeInfoImpl::GetAvailableExternalStorage(long long& value)
461 int sdCardStatus = 0;
465 ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &sdCardStatus);
466 SysTryReturn(NID_SYS, !(ret < 0), E_SYSTEM, E_SYSTEM, "[E_SYSTEM] vconf_get_int VCONFKEY_SYSMAN_MMC_STATUS failed");
468 if(sdCardStatus == 0)
474 return GetCapacity(_STORAGE_PATH, total, value);
478 _RuntimeInfoImpl::GetAvailableMediaStorage(long long& value)
481 return GetCapacity(_MEDIA_PATH, total, value);
485 _RuntimeInfoImpl::GetCapacity(const char* path, long long& totalSize, long long& availableSize)
488 if (statfs(path, &fs) < 0)
490 SysLogException(NID_SYS, E_SYSTEM, "[E_SYSTEM] statfs() failed");
494 totalSize = static_cast< long long >(fs.f_bsize) * static_cast< long long >(fs.f_blocks);
495 availableSize = static_cast< long long >(fs.f_bsize) * static_cast< long long >(fs.f_bavail);
501 _RuntimeInfoImpl::GetFromProcLonglong(const char* path, const char* key, long long& value)
503 FILE* pStream = null;
504 char line[_MAX_BUFFER_LENGTH] = {0, };
505 char fieldName[_MAX_BUFFER_LENGTH] = {0, };
506 long long keyValue = 0;
507 pStream = fopen(path, "r");
508 SysTryReturnResult(NID_SYS, pStream != null, E_SYSTEM, "%s open is failed.", path);
510 while (fgets(line, sizeof(line), pStream))
512 if (sscanf(line, "%s %lld %*s", fieldName, &keyValue) == 2)
514 if (strncmp(fieldName, key, static_cast< int >(strlen(key))) == 0)
524 SysLogException(NID_SYS, E_OBJ_NOT_FOUND, "it can't find %s field", key);
525 return E_OBJ_NOT_FOUND;
529 _RuntimeInfoImpl::GetFromProc(const char* path, const char* key, int& value)
531 FILE* pStream = null;
532 char line[_MAX_BUFFER_LENGTH] = {0, };
533 char fieldName[_MAX_BUFFER_LENGTH] = {0, };
535 pStream = fopen(path, "r");
536 SysTryReturnResult(NID_SYS, pStream != null, E_SYSTEM, "%s open is failed.", path);
538 while (fgets(line, sizeof(line), pStream))
540 if (sscanf(line, "%s %d %*s", fieldName, &keyValue) == 2)
542 if (strncmp(fieldName, key, static_cast< int >(strlen(key))) == 0)
552 SysLogException(NID_SYS, E_OBJ_NOT_FOUND, "it can't find %s field", key);
553 return E_OBJ_NOT_FOUND;
557 _RuntimeInfoImpl::GetDirectorySizeAsync(void* data)
563 _RuntimeInfoEventArg* pEventArg = (_RuntimeInfoEventArg*)data;
564 long long size = _RuntimeInfoImpl::GetDirectorySize(pEventArg->DirectoryPath);
566 if(pEventArg == null)
568 SysLogException(NID_SYS, E_OUT_OF_MEMORY, "It is failed to create instance of _RuntimeInfoEventArg");
571 pEventArg->Type = _RUNTIME_INFO_EVENT_TYPE_LONGLONG;
572 pEventArg->longLongValue = size;
573 SysLog(NID_SYS, "Fire event %x %s %lld", pEventArg, pEventArg->DirectoryPath, size);
574 runtimeInfoEvent.Fire(*pEventArg);
580 _RuntimeInfoImpl::GetCpuUsageAsync(void* data)
582 result r = E_SUCCESS;
585 procstat_t first, second, diffrence;
586 unsigned long long total, usage;
588 if(read_proc_stat(&first) != false)
590 usleep(_CPU_USAGE_EVALUATION_INTERVAL);
591 if(read_proc_stat(&second) != false)
593 diff_proc_stat(&second, &first, &diffrence);
594 total = diffrence.user + diffrence.system
595 + diffrence.nice + diffrence.idle
596 + diffrence.wait + diffrence.hi
598 usage = 10000 - (diffrence.idle * 10000 / total);
612 _RuntimeInfoEventArg* pEventArg = (_RuntimeInfoEventArg*) data;
613 if(pEventArg == null)
615 SysLogException(NID_SYS, E_OUT_OF_MEMORY, "It is failed to create instance of _RuntimeInfoEventArg");
618 pEventArg->errorCode = r;
619 pEventArg->Type = _RUNTIME_INFO_EVENT_TYPE_INT;
620 pEventArg->intValue = value;
622 runtimeInfoEvent.Fire(*pEventArg);
628 _RuntimeInfoImpl::GetValueAsync(const String& key, IRuntimeInfoGetIntAsyncResultListener* listener)
630 result r = E_SUCCESS;
632 SysTryReturnResult(NID_SYS, listener != null, E_INVALID_ARG, "listener is null");
634 if (key == _CPU_CORE_ALL_USAGE)
638 SysLog(NID_SYS, "%x", listener);
639 runtimeInfoEvent.AddListener(*listener, false);
644 _RuntimeInfoEventArg* pEventArg = new (std::nothrow) _RuntimeInfoEventArg();
645 pEventArg->pListener = listener;
646 thr_id = pthread_create(&p_thread, null, GetCpuUsageAsync, pEventArg);
647 pthread_detach(p_thread);
651 SysLogException(NID_SYS, E_INVALID_ARG, "Required key[%ls] is not valid", key.GetPointer());
658 _RuntimeInfoImpl::GetValueAsync(const String& key, IRuntimeInfoGetLonglongAsyncResultListener* listener)
662 result r = E_SUCCESS;
663 char* directoryPath = null;
665 SysTryReturnResult(NID_SYS, listener != null, E_INVALID_ARG, "listener is null");
667 if(key == _STORAGE_ALLOCATED_INTERNAL_APPLICATION)
669 directoryPath = _StringConverter::CopyToCharArrayN(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_APPLICATIONS));
671 else if (key == _STORAGE_ALLOCATED_INTERNAL_AUDIO)
673 directoryPath = _StringConverter::CopyToCharArrayN(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_SOUNDS));
675 else if (key == _STORAGE_ALLOCATED_INTERNAL_VIDEO)
677 directoryPath = _StringConverter::CopyToCharArrayN(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_VIDEOS));
679 else if (key == _STORAGE_ALLOCATED_INTERNAL_IMAGE)
681 directoryPath = _StringConverter::CopyToCharArrayN(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_IMAGES));
683 else if (key == _STORAGE_ALLOCATED_INTERNAL_DOWNLOAD)
685 directoryPath = _StringConverter::CopyToCharArrayN(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_DOWNLOADS));
687 else if (key == _STORAGE_ALLOCATED_EXTERNAL_APPLICATION)
689 directoryPath = _StringConverter::CopyToCharArrayN(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_EXTERNAL_APPLICATIONS));
691 else if (key == _STORAGE_ALLOCATED_EXTERNAL_AUDIO)
693 directoryPath = _StringConverter::CopyToCharArrayN(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_EXTERNAL_SOUNDS));
695 else if (key == _STORAGE_ALLOCATED_EXTERNAL_VIDEO)
697 directoryPath = _StringConverter::CopyToCharArrayN(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_EXTERNAL_VIDEOS));
699 else if (key == _STORAGE_ALLOCATED_EXTERNAL_IMAGE)
701 directoryPath = _StringConverter::CopyToCharArrayN(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_EXTERNAL_IMAGES));
704 else if (key == _STORAGE_ALLOCATED_EXTERNAL_DOWNLOAD)
706 directoryPath = _StringConverter::CopyToCharArrayN(_EnvironmentImpl::GetPredefinedPath(PREDEFINED_DIRECTORY_EXTERNAL_DOWNLOADS));
710 SysLogException(NID_SYS, E_INVALID_ARG, "Required key[%ls] is not valid", key.GetPointer());
714 SysLog(NID_SYS, "%s", GetErrorMessage(r));
715 SysLog(NID_SYS, "%s", directoryPath);
720 SysLog(NID_SYS, "test %x", listener);
721 runtimeInfoEvent.AddListener(*listener);
724 _RuntimeInfoEventArg* pEventArg = new (std::nothrow) _RuntimeInfoEventArg();
725 pEventArg->pListener = listener;
726 pEventArg->DirectoryPath = directoryPath;
728 thr_id = pthread_create(&p_thread, null, GetDirectorySizeAsync, pEventArg);
729 SysLog(NID_SYS, "%d", thr_id);
730 pthread_detach(p_thread);
737 _RuntimeInfoImpl::GetInstance(RuntimeInfo& runtimeinfo)
739 return runtimeinfo.__pRuntimeInfoImpl;
742 const _RuntimeInfoImpl*
743 _RuntimeInfoImpl::GetInstance(const RuntimeInfo& runtimeinfo)
745 return runtimeinfo.__pRuntimeInfoImpl;