From 6a9c24525cbdcd631bd531d59cca771e8c125b1e Mon Sep 17 00:00:00 2001 From: legendlee1314 Date: Tue, 27 Aug 2013 10:57:42 +0800 Subject: [PATCH] [SystemInfo] Implement storage on mobile --- system_info/system_info.gyp | 2 + system_info/system_info_storage.cc | 201 +---------------------------- system_info/system_info_storage.h | 21 +-- system_info/system_info_storage_desktop.cc | 200 ++++++++++++++++++++++++++++ system_info/system_info_storage_mobile.cc | 107 +++++++++++++++ 5 files changed, 329 insertions(+), 202 deletions(-) create mode 100644 system_info/system_info_storage_desktop.cc create mode 100644 system_info/system_info_storage_mobile.cc diff --git a/system_info/system_info.gyp b/system_info/system_info.gyp index d65c17d..6dfed55 100644 --- a/system_info/system_info.gyp +++ b/system_info/system_info.gyp @@ -75,6 +75,8 @@ 'system_info_sim_mobile.cc', 'system_info_storage.cc', 'system_info_storage.h', + 'system_info_storage_desktop.cc', + 'system_info_storage_mobile.cc', 'system_info_utils.cc', 'system_info_utils.h', 'system_info_wifi_network.cc', diff --git a/system_info/system_info_storage.cc b/system_info/system_info_storage.cc index c53e3d6..d5be171 100644 --- a/system_info/system_info_storage.cc +++ b/system_info/system_info_storage.cc @@ -4,34 +4,15 @@ #include "system_info/system_info_storage.h" -#include -#include -#include - #include "common/picojson.h" #include "system_info/system_info_utils.h" -namespace { - -const char* sMountTable = "/proc/mounts"; - -} // namespace - -SysInfoStorage::SysInfoStorage(ContextAPI* api) - : stopping_(false) { - api_ = api; - udev_ = udev_new(); - units_ = picojson::value(picojson::array(0)); -} - -SysInfoStorage::~SysInfoStorage() { - if (udev_) - udev_unref(udev_); -} - void SysInfoStorage::Get(picojson::value& error, picojson::value& data) { if (!Update(error)) { + if (error.get("message").to_str().empty()) + system_info::SetPicoJsonObjectValue(error, "message", + picojson::value("Get storage faild.")); return; } @@ -39,174 +20,6 @@ void SysInfoStorage::Get(picojson::value& error, system_info::SetPicoJsonObjectValue(error, "message", picojson::value("")); } -bool SysInfoStorage::Update(picojson::value& error) { - picojson::array& units_arr = units_.get(); - units_arr.clear(); - - struct mntent *entry; - FILE *aFile; - - aFile = setmntent(sMountTable, "r"); - if (!aFile) { - system_info::SetPicoJsonObjectValue(error, "message", - picojson::value("Read mount table failed.")); - return false; - } - - while (entry = getmntent(aFile)) { - if (entry->mnt_fsname[0] == '/') { - picojson::value unit = picojson::value(picojson::object()); - GetDetails(entry->mnt_fsname, entry->mnt_dir, error, unit); - if (!error.get("message").to_str().empty()) { - endmntent(aFile); - return false; - } - units_arr.push_back(unit); - } - } - - endmntent(aFile); - return true; -} - -std::string -SysInfoStorage::GetDevPathFromMountPath(const std::string& mnt_path) { - struct udev_enumerate *enumerate; - struct udev_list_entry *devices, *dev_list_entry; - - if (mnt_path.empty() || mnt_path[0] != '/' || mnt_path.size() <=1) { - return ""; - } - - enumerate = udev_enumerate_new(udev_); - udev_enumerate_add_match_subsystem(enumerate, "block"); - udev_enumerate_scan_devices(enumerate); - devices = udev_enumerate_get_list_entry(enumerate); - - udev_list_entry_foreach(dev_list_entry, devices) { - struct udev_device *dev; - const char *path; - std::string dev_path, str; - - path = udev_list_entry_get_name(dev_list_entry); - dev = udev_device_new_from_syspath(udev_, path); - - dev_path = system_info::GetUdevProperty(dev, "DEVPATH"); - if (dev_path.empty()) { - udev_device_unref(dev); - udev_enumerate_unref(enumerate); - return ""; - } - - dev_path = "/sys" + dev_path; - - str = system_info::GetUdevProperty(dev, "DEVNAME"); - if (!str.empty() && (str == mnt_path)) { - udev_device_unref(dev); - udev_enumerate_unref(enumerate); - return dev_path; - } - - str = system_info::GetUdevProperty(dev, "DEVLINKS"); - if (!str.empty() && (std::string::npos != str.find(mnt_path))) { - udev_device_unref(dev); - udev_enumerate_unref(enumerate); - return dev_path; - } - } - - udev_enumerate_unref(enumerate); - return ""; -} - -void SysInfoStorage::GetDetails(const std::string& mnt_fsname, - const std::string& mnt_dir, - picojson::value& error, - picojson::value& unit) { - struct udev_device* dev; - struct udev_list_entry *attr_list_entry; - struct udev_list_entry *attr_entry; - const char* str; - bool is_removable; - - std::string dev_path = GetDevPathFromMountPath(mnt_fsname); - if (dev_path.empty()) { - system_info::SetPicoJsonObjectValue(error, "message", - picojson::value("Get storage DEVPATH failed.")); - return; - } - - dev = udev_device_new_from_syspath(udev_, dev_path.c_str()); - if (!dev) { - system_info::SetPicoJsonObjectValue(error, "message", - picojson::value("Get storage udev from device_id failed.")); - } - - attr_list_entry = udev_device_get_properties_list_entry(dev); - - // FIXME(guanxian): may need to fix problems of encrypted or LVM storages - struct udev_device* parent_dev = - udev_device_get_parent_with_subsystem_devtype(dev, "block", "disk"); - str = udev_device_get_sysattr_value(parent_dev, "removable"); - if (!str) { - system_info::SetPicoJsonObjectValue(error, "message", - picojson::value("Get storage attribute removable failed.")); - udev_device_unref(parent_dev); - udev_device_unref(dev); - return; - } - - is_removable = (1 == atoi(str)); - system_info::SetPicoJsonObjectValue(unit, "isRemovable", - picojson::value(is_removable)); - // deprecated, same as isRemovable - system_info::SetPicoJsonObjectValue(unit, "isRemoveable", - picojson::value(is_removable)); - - system_info::SetPicoJsonObjectValue(unit, "type", picojson::value("UNKNOWN")); - if (!is_removable) { - system_info::SetPicoJsonObjectValue(unit, "type", - picojson::value("INTERNAL")); - } else { - attr_entry = udev_list_entry_get_by_name(attr_list_entry, "ID_BUS"); - if (attr_entry) { - str = udev_list_entry_get_value(attr_entry); - if (str && (strcmp(str, "usb") == 0)) { - system_info::SetPicoJsonObjectValue(unit, "type", - picojson::value("USB_HOST")); - } - } - // FIXME(halton): Add MMC type support, we do not find a correct - // attribute to identify. - } - - str = udev_device_get_sysattr_value(dev, "size"); - if (!str) { - system_info::SetPicoJsonObjectValue(error, "message", - picojson::value("Get storage attribute size failed.")); - udev_device_unref(dev); - return; - } - system_info::SetPicoJsonObjectValue(unit, "capacity", - picojson::value(static_cast(atoll(str)*512))); - - struct statvfs buf; - int ret = statvfs(mnt_dir.c_str(), &buf); - if (-1 == ret) { - system_info::SetPicoJsonObjectValue(error, "message", - picojson::value("Get storage availableCapacity failed.")); - udev_device_unref(dev); - return; - } - - udev_device_unref(dev); - system_info::SetPicoJsonObjectValue(unit, "availableCapacity", - picojson::value(static_cast(buf.f_bavail * buf.f_bsize))); - - // set message to confirm no errors - system_info::SetPicoJsonObjectValue(error, "message", picojson::value("")); -} - gboolean SysInfoStorage::OnUpdateTimeout(gpointer user_data) { SysInfoStorage* instance = static_cast(user_data); @@ -215,9 +28,9 @@ gboolean SysInfoStorage::OnUpdateTimeout(gpointer user_data) { return FALSE; } - // can't to take a reference (&), just copy + // Can't to take a reference (&), just copy. picojson::array old_units_arr = instance->units_.get(); - picojson::value error = picojson::value(picojson::object());; + picojson::value error = picojson::value(picojson::object()); instance->Update(error); bool is_changed = false; @@ -225,7 +38,7 @@ gboolean SysInfoStorage::OnUpdateTimeout(gpointer user_data) { if (old_units_arr.size() != units_arr.size()) { is_changed = true; } else { - for (int i = 0; i < units_arr.size(); i++) { + for (unsigned int i = 0; i < units_arr.size(); ++i) { if (old_units_arr[i] != units_arr[i]) { is_changed = true; break; @@ -234,7 +47,7 @@ gboolean SysInfoStorage::OnUpdateTimeout(gpointer user_data) { } if (is_changed) { - picojson::value output = picojson::value(picojson::object());; + picojson::value output = picojson::value(picojson::object()); picojson::value data = picojson::value(picojson::object()); system_info::SetPicoJsonObjectValue(data, "units", instance->units_); diff --git a/system_info/system_info_storage.h b/system_info/system_info_storage.h index 64076f2..de9348e 100644 --- a/system_info/system_info_storage.h +++ b/system_info/system_info_storage.h @@ -6,7 +6,9 @@ #define SYSTEM_INFO_SYSTEM_INFO_STORAGE_H_ #include +#if defined(GENERIC_DESKTOP) #include +#endif #include #include "common/extension_adapter.h" @@ -21,10 +23,7 @@ class SysInfoStorage { return instance; } ~SysInfoStorage(); - // Get support void Get(picojson::value& error, picojson::value& data); - - // Listerner support inline void StartListening() { stopping_ = false; // FIXME(halton): Use udev D-Bus interface to monitor. @@ -37,18 +36,24 @@ class SysInfoStorage { private: explicit SysInfoStorage(ContextAPI* api); bool Update(picojson::value& error); + static gboolean OnUpdateTimeout(gpointer user_data); + + bool stopping_; + ContextAPI* api_; + picojson::value units_; + +#if defined(GENERIC_DESKTOP) void GetDetails(const std::string& mnt_fsname, const std::string& mnt_dir, picojson::value& error, picojson::value& unit); - static gboolean OnUpdateTimeout(gpointer user_data); std::string GetDevPathFromMountPath(const std::string& mnt_path); - ContextAPI* api_; struct udev* udev_; - - bool stopping_; - picojson::value units_; +#elif defined(TIZEN_MOBILE) + bool GetInternal(picojson::value& error, picojson::value& unit); + bool GetMMC(picojson::value& error, picojson::value& unit); +#endif DISALLOW_COPY_AND_ASSIGN(SysInfoStorage); }; diff --git a/system_info/system_info_storage_desktop.cc b/system_info/system_info_storage_desktop.cc new file mode 100644 index 0000000..dc355d2 --- /dev/null +++ b/system_info/system_info_storage_desktop.cc @@ -0,0 +1,200 @@ +// Copyright (c) 2013 Intel Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "system_info/system_info_storage.h" + +#include +#include +#include + +#include "common/picojson.h" +#include "system_info/system_info_utils.h" + +namespace { + +const char* sMountTable = "/proc/mounts"; + +} // namespace + +SysInfoStorage::SysInfoStorage(ContextAPI* api) + : stopping_(false) { + api_ = api; + udev_ = udev_new(); + units_ = picojson::value(picojson::array(0)); +} + +SysInfoStorage::~SysInfoStorage() { + if (udev_) + udev_unref(udev_); +} + +bool SysInfoStorage::Update(picojson::value& error) { + picojson::array& units_arr = units_.get(); + units_arr.clear(); + + FILE *aFile; + aFile = setmntent(sMountTable, "r"); + if (!aFile) { + system_info::SetPicoJsonObjectValue(error, "message", + picojson::value("Read mount table failed.")); + return false; + } + + struct mntent *entry; + while (entry = getmntent(aFile)) { + if (entry->mnt_fsname[0] == '/') { + picojson::value unit = picojson::value(picojson::object()); + GetDetails(entry->mnt_fsname, entry->mnt_dir, error, unit); + if (!error.get("message").to_str().empty()) { + endmntent(aFile); + return false; + } + units_arr.push_back(unit); + } + } + + endmntent(aFile); + return true; +} + +std::string +SysInfoStorage::GetDevPathFromMountPath(const std::string& mnt_path) { + struct udev_enumerate *enumerate; + struct udev_list_entry *devices, *dev_list_entry; + + if (mnt_path.empty() || mnt_path[0] != '/' || mnt_path.size() <=1) { + return ""; + } + + enumerate = udev_enumerate_new(udev_); + udev_enumerate_add_match_subsystem(enumerate, "block"); + udev_enumerate_scan_devices(enumerate); + devices = udev_enumerate_get_list_entry(enumerate); + + udev_list_entry_foreach(dev_list_entry, devices) { + const char *path; + struct udev_device *dev; + std::string dev_path, str; + + path = udev_list_entry_get_name(dev_list_entry); + dev = udev_device_new_from_syspath(udev_, path); + + dev_path = system_info::GetUdevProperty(dev, "DEVPATH"); + if (dev_path.empty()) { + udev_device_unref(dev); + udev_enumerate_unref(enumerate); + return ""; + } + + dev_path = "/sys" + dev_path; + + str = system_info::GetUdevProperty(dev, "DEVNAME"); + if (!str.empty() && (str == mnt_path)) { + udev_device_unref(dev); + udev_enumerate_unref(enumerate); + return dev_path; + } + + str = system_info::GetUdevProperty(dev, "DEVLINKS"); + if (!str.empty() && (std::string::npos != str.find(mnt_path))) { + udev_device_unref(dev); + udev_enumerate_unref(enumerate); + return dev_path; + } + } + + udev_enumerate_unref(enumerate); + return ""; +} + +void SysInfoStorage::GetDetails(const std::string& mnt_fsname, + const std::string& mnt_dir, + picojson::value& error, + picojson::value& unit) { + struct udev_device* dev; + struct udev_list_entry *attr_entry; + struct udev_list_entry *attr_list_entry; + + std::string dev_path = GetDevPathFromMountPath(mnt_fsname); + if (dev_path.empty()) { + system_info::SetPicoJsonObjectValue(error, "message", + picojson::value("Get storage DEVPATH failed.")); + return; + } + + dev = udev_device_new_from_syspath(udev_, dev_path.c_str()); + if (!dev) { + system_info::SetPicoJsonObjectValue(error, "message", + picojson::value("Get storage udev from device_id failed.")); + } + + attr_list_entry = udev_device_get_properties_list_entry(dev); + + // FIXME(guanxian): May need to fix problems of encrypted or LVM storages. + struct udev_device* parent_dev = + udev_device_get_parent_with_subsystem_devtype(dev, "block", "disk"); + + const char* str; + str = udev_device_get_sysattr_value(parent_dev, "removable"); + if (!str) { + system_info::SetPicoJsonObjectValue(error, "message", + picojson::value("Get storage attribute removable failed.")); + udev_device_unref(parent_dev); + udev_device_unref(dev); + return; + } + + bool is_removable; + is_removable = (1 == atoi(str)); + system_info::SetPicoJsonObjectValue(unit, "isRemovable", + picojson::value(is_removable)); + // Deprecated, same as isRemovable. + system_info::SetPicoJsonObjectValue(unit, "isRemoveable", + picojson::value(is_removable)); + + system_info::SetPicoJsonObjectValue(unit, "type", + picojson::value("UNKNOWN")); + + if (!is_removable) { + system_info::SetPicoJsonObjectValue(unit, "type", + picojson::value("INTERNAL")); + } else { + attr_entry = udev_list_entry_get_by_name(attr_list_entry, "ID_BUS"); + if (attr_entry) { + str = udev_list_entry_get_value(attr_entry); + if (str && (strcmp(str, "usb") == 0)) { + system_info::SetPicoJsonObjectValue(unit, "type", + picojson::value("USB_HOST")); + } + } + // FIXME(halton): Add MMC type support, we do not find a correct + // attribute to identify. + } + + str = udev_device_get_sysattr_value(dev, "size"); + if (!str) { + system_info::SetPicoJsonObjectValue(error, "message", + picojson::value("Get storage attribute size failed.")); + udev_device_unref(dev); + return; + } + system_info::SetPicoJsonObjectValue(unit, "capacity", + picojson::value(static_cast(atoll(str)*512))); + + struct statvfs buf; + int ret = statvfs(mnt_dir.c_str(), &buf); + if (-1 == ret) { + system_info::SetPicoJsonObjectValue(error, "message", + picojson::value("Get storage availableCapacity failed.")); + udev_device_unref(dev); + return; + } + + udev_device_unref(dev); + system_info::SetPicoJsonObjectValue(unit, "availableCapacity", + picojson::value(static_cast(buf.f_bavail * buf.f_bsize))); + + // Set message to confirm no errors. + system_info::SetPicoJsonObjectValue(error, "message", picojson::value("")); +} diff --git a/system_info/system_info_storage_mobile.cc b/system_info/system_info_storage_mobile.cc new file mode 100644 index 0000000..478bd80 --- /dev/null +++ b/system_info/system_info_storage_mobile.cc @@ -0,0 +1,107 @@ +// Copyright (c) 2013 Intel Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "system_info/system_info_storage.h" + +#include +#include + +#include "common/picojson.h" +#include "system_info/system_info_utils.h" + +namespace { + +const char* sStorageInternalPath = "/opt/usr/media"; +const char* sStorageSDCardPath = "/opt/storage/sdcard"; + +} // namespace + +SysInfoStorage::SysInfoStorage(ContextAPI* api) + : stopping_(false) { + api_ = api; + units_ = picojson::value(picojson::array(0)); +} + +SysInfoStorage::~SysInfoStorage() { +} + +bool SysInfoStorage::Update(picojson::value& error) { + picojson::array& units_arr = units_.get(); + units_arr.clear(); + + picojson::value unit_intern = picojson::value(picojson::object()); + if (GetInternal(error, unit_intern)) + units_arr.push_back(unit_intern); + + picojson::value unit_mmc = picojson::value(picojson::object()); + if (GetMMC(error, unit_mmc)) + units_arr.push_back(unit_mmc); + + system_info::SetPicoJsonObjectValue(error, "message", picojson::value("")); + return true; +} + +bool SysInfoStorage::GetInternal(picojson::value& error, + picojson::value& unit) { + struct statfs fs; + if (statfs(sStorageInternalPath, &fs) < 0) { + system_info::SetPicoJsonObjectValue(error, "message", + picojson::value("Internal Storage path Error")); + return false; + } + + double available_capacity = static_cast(fs.f_bsize) * + static_cast(fs.f_bavail); + double capacity = static_cast(fs.f_bsize) * + static_cast(fs.f_blocks); + + system_info::SetPicoJsonObjectValue(unit, "type", + picojson::value("INTERNAL")); + system_info::SetPicoJsonObjectValue(unit, "capacity", + picojson::value(capacity)); + system_info::SetPicoJsonObjectValue(unit, "availableCapacity", + picojson::value(available_capacity)); + // FIXME(guanxian): Internal storage unit is not removale. + system_info::SetPicoJsonObjectValue(unit, "isRemoveable", + picojson::value(false)); + system_info::SetPicoJsonObjectValue(unit, "isRemovable", + picojson::value(false)); + + return true; +} + +bool SysInfoStorage::GetMMC(picojson::value& error, picojson::value& unit) { + int sdcard_state; + if ((vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &sdcard_state) != 0) || + (sdcard_state != VCONFKEY_SYSMAN_MMC_MOUNTED)) { + return false; + } + + struct statfs fs; + if (statfs(sStorageInternalPath, &fs) < 0) { + system_info::SetPicoJsonObjectValue(error, "message", + picojson::value("MMC mount path error")); + return false; + } + + statfs(sStorageSDCardPath, &fs); + double available_capacity = static_cast(fs.f_bsize) * + static_cast(fs.f_bavail); + double capacity = static_cast(fs.f_bsize) * + static_cast(fs.f_blocks); + + system_info::SetPicoJsonObjectValue(unit, "type", + picojson::value("MMC")); + system_info::SetPicoJsonObjectValue(unit, "capacity", + picojson::value(capacity)); + system_info::SetPicoJsonObjectValue(unit, "availableCapacity", + picojson::value(available_capacity)); + // FIXME(guanxian): MMC Internal storage unit is not removale. + system_info::SetPicoJsonObjectValue(unit, "isRemoveable", + picojson::value(true)); + system_info::SetPicoJsonObjectValue(unit, "isRemovable", + picojson::value(true)); + + return true; +} -- 2.7.4