Merge branch 'tizen_3.0' into tizen 48/118048/1 accepted/tizen/common/20170309.175328 accepted/tizen/ivi/20170308.121817 accepted/tizen/mobile/20170308.121752 accepted/tizen/tv/20170308.121802 accepted/tizen/unified/20170310.075645 accepted/tizen/wearable/20170308.121807 submit/tizen/20170308.110622 submit/tizen_unified/20170310.011401
authorPiotr Kosko <p.kosko@samsung.com>
Wed, 8 Mar 2017 10:43:28 +0000 (11:43 +0100)
committerPiotr Kosko <p.kosko@samsung.com>
Wed, 8 Mar 2017 11:04:29 +0000 (12:04 +0100)
Change-Id: Ib4da480084b40a068293bab2dd12163cf8cb909c

packaging/webapi-plugins.spec
src/bluetooth/bluetooth_gatt_service.cc
src/bluetooth/bluetooth_le_adapter.cc
src/common/tools.cc
src/download/download_instance.cc

index 660f4aa..99cd65b 100644 (file)
@@ -10,7 +10,7 @@
 %define crosswalk_extensions_path %{_libdir}/%{crosswalk_extensions}
 
 Name:       webapi-plugins
-Version:    1.75
+Version:    1.76
 Release:    0
 License:    Apache-2.0 and BSD-3-Clause and MIT
 Group:      Development/Libraries
index fce5b56..98d0b53 100755 (executable)
@@ -576,7 +576,7 @@ common::PlatformResult BluetoothGATTService::GetServiceAllUuids(
 
 void BluetoothGATTService::OnCharacteristicValueChanged(
     bt_gatt_h characteristic, char* value, int length, void* user_data) {
-  LoggerD("Entered, characteristic: [%p], len: [d], user_data: [%p]", characteristic, length, user_data);
+  LoggerD("Entered, characteristic: [%p], len: [%d], user_data: [%p]", characteristic, length, user_data);
 
   auto service = static_cast<BluetoothGATTService*>(user_data);
 
@@ -586,7 +586,7 @@ void BluetoothGATTService::OnCharacteristicValueChanged(
   }
 
   picojson::value result = picojson::value(picojson::object());
-  picojson::object result_obj = result.get<picojson::object>();
+  picojson::object& result_obj = result.get<picojson::object>();
 
   result_obj.insert(std::make_pair(kHandle, picojson::value((double)(long)characteristic)));
 
index 7447289..b63fc32 100755 (executable)
@@ -105,7 +105,7 @@ class BluetoothLEServiceData : public ParsedDataHolder {
   static bool ParseUUID(const picojson::value& obj,
                         BluetoothLEServiceData* out) {
     LoggerD("Entered");
-    const auto& uuid = obj.get("serviceuuid");
+    const auto& uuid = obj.get("uuid");
     if (uuid.is<std::string>()) {
       out->uuid_ = uuid.get<std::string>();
     } else {
@@ -261,7 +261,7 @@ class BluetoothLEAdvertiseData : public ParsedDataHolder {
   static bool ParseServiceUUIDs(const picojson::value& obj,
                                 BluetoothLEAdvertiseData* out) {
     LoggerD("Entered");
-    const auto& service_uuids = obj.get("serviceuuids");
+    const auto& service_uuids = obj.get("uuids");
     if (service_uuids.is<picojson::array>()) {
       for (const auto& i : service_uuids.get<picojson::array>()) {
         if (i.is<std::string>()) {
index 8a6a3d3..638352f 100644 (file)
@@ -266,6 +266,13 @@ PlatformResult CheckAccess(const std::string& privilege) {
 PlatformResult CheckAccess(const std::vector<std::string>& privileges) {
   LoggerD("Enter");
 
+  // Local cache of mapped privilege strings. This routine can be called many times, especially
+  // during application launch, generating a high overhead of retrieving mapped privileges from
+  // the underlying databases. This is especially the case since the same mappings can end up
+  // being retrieved several times.
+  using MappedPrivilegeCache = std::map<std::string, std::vector<std::string>>;
+  static MappedPrivilegeCache mapped_privilege_cache;
+
   std::string api_version;
   PlatformResult res = common::tools::GetPkgApiVersion(&api_version);
   if (res.IsError()) {
@@ -283,30 +290,45 @@ PlatformResult CheckAccess(const std::vector<std::string>& privileges) {
       g_list_free(mapped_glist);
     };
 
-    input_glist = g_list_append(input_glist, (void*)input_priv.c_str());
-    int ret = privilege_manager_get_mapped_privilege_list(api_version.c_str(),
-                                                          PRVMGR_PACKAGE_TYPE_WRT,
-                                                          input_glist,
-                                                          &mapped_glist);
-    if (ret != PRVMGR_ERR_NONE) {
-      return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get mapped privilege list");
-    }
-
-    LoggerD("Mapped privileges:");
-    std::vector<std::string> mapped_vector;
-    auto push_elem = [](gpointer data, gpointer user_data) -> void {
-      if (data && user_data) {
-        std::vector<std::string>* mapped_vector =
-            static_cast<std::vector<std::string>*>(user_data);
-        char* char_data = static_cast<char*>(data);
-        mapped_vector->push_back(char_data);
-        LoggerD("mapped to: %s", char_data);
+    std::vector<std::string>* mapped_vector_ptr = nullptr;
+
+    // Check if mapped privilege is in local cache first
+    MappedPrivilegeCache::const_iterator it = mapped_privilege_cache.find(input_priv);
+    if (mapped_privilege_cache.end() == it) {
+      LoggerD("Mapped privileges - need to be fetched from database");
+      // Not in cache - retrieve from underlying databases.
+      input_glist = g_list_append(input_glist, (void*)input_priv.c_str());
+      int ret = privilege_manager_get_mapped_privilege_list(api_version.c_str(),
+                                                            PRVMGR_PACKAGE_TYPE_WRT,
+                                                            input_glist,
+                                                            &mapped_glist);
+      if (PRVMGR_ERR_NONE != ret) {
+        return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get mapped privilege list");
       }
-    };
-    g_list_foreach (mapped_glist, push_elem, &mapped_vector);
 
-    if (!AccessControl::GetInstance().CheckAccess(mapped_vector)){
-      for (const auto& mapped_priv : mapped_vector) {
+      // initialize empty cache vector
+      mapped_privilege_cache[input_priv] = std::vector<std::string>();
+      LoggerD("Mapped privileges:");
+      auto push_elem = [](gpointer data, gpointer user_data) -> void {
+        if (data && user_data) {
+          std::vector<std::string>* mapped_vector =
+              static_cast<std::vector<std::string>*>(user_data);
+          char* char_data = static_cast<char*>(data);
+          mapped_vector->push_back(char_data);
+          LoggerD("mapped to: %s", char_data);
+        }
+      };
+      // fill the vector with data
+      g_list_foreach (mapped_glist, push_elem, &mapped_privilege_cache[input_priv]);
+      mapped_vector_ptr = &mapped_privilege_cache[input_priv];
+    } else {
+      // Retrieve from local cache
+      LoggerD("Mapped privileges already in cache");
+      mapped_vector_ptr = (std::vector<std::string>*) &(it->second);
+    }
+
+    if (!AccessControl::GetInstance().CheckAccess(*mapped_vector_ptr)){
+      for (const auto& mapped_priv : *mapped_vector_ptr) {
         LoggerD("Access to privilege: %s has been denied.", mapped_priv.c_str());
       }
       return PlatformResult(ErrorCode::SECURITY_ERR, "Permission denied");
@@ -318,6 +340,12 @@ PlatformResult CheckAccess(const std::vector<std::string>& privileges) {
 PlatformResult GetPkgApiVersion(std::string* api_version) {
   LoggerD("Entered");
 
+  // Local cache of API version string.  This can be expensive to retrieve from
+  // underlying databases and this routine can be called many times during
+  // application launch.
+  static std::string cached_api_version;
+  static int cached_pid = -1;
+
   char* app_id = nullptr;
   char* pkgid = nullptr;
   char* api_ver = nullptr;
@@ -340,32 +368,40 @@ PlatformResult GetPkgApiVersion(std::string* api_version) {
   };
 
   pid_t pid = getpid();
-  int ret = app_manager_get_app_id(pid, &app_id);
-  if (ret != APP_MANAGER_ERROR_NONE) {
-    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get app id");
-  }
+  if (cached_pid == pid) {
+    *api_version = cached_api_version;  // Retrieve from local cache
+  } else {
+    int ret = app_manager_get_app_id(pid, &app_id);
+    if (ret != APP_MANAGER_ERROR_NONE) {
+      return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get app id");
+    }
 
-  ret = app_info_create(app_id, &app_handle);
-  if (ret != APP_MANAGER_ERROR_NONE) {
-    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get app info");
-  }
+    ret = app_info_create(app_id, &app_handle);
+    if (ret != APP_MANAGER_ERROR_NONE) {
+      return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get app info");
+    }
 
-  ret = app_info_get_package(app_handle, &pkgid);
-  if ((ret != APP_MANAGER_ERROR_NONE) || (pkgid == nullptr)) {
-    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get pkg id");
-  }
+    ret = app_info_get_package(app_handle, &pkgid);
+    if ((ret != APP_MANAGER_ERROR_NONE) || (pkgid == nullptr)) {
+      return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get pkg id");
+    }
 
-  ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, getuid(), &pkginfo_handle);
-  if (ret != PMINFO_R_OK) {
-    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get pkginfo_h");
-  }
+    ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, getuid(), &pkginfo_handle);
+    if (ret != PMINFO_R_OK) {
+      return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get pkginfo_h");
+    }
+
+    ret = pkgmgrinfo_pkginfo_get_api_version(pkginfo_handle, &api_ver);
+    if (ret != PMINFO_R_OK) {
+      return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get api version");
+    }
+
+    cached_api_version = api_ver;  // Save in local cache
+    cached_pid = pid;
 
-  ret = pkgmgrinfo_pkginfo_get_api_version(pkginfo_handle, &api_ver);
-  if (ret != PMINFO_R_OK) {
-    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get api version");
+    *api_version = api_ver;
   }
 
-  *api_version = api_ver;
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
index eeb071b..0950619 100755 (executable)
@@ -443,7 +443,17 @@ gboolean DownloadInstance::OnFailed(void* user_data) {
                       ("download_get_error error: %d (%s)", error, get_error_message(error)));
   }
 
-  int ret = download_destroy(diPtr->download_id);
+  int ret = download_unset_state_changed_cb(diPtr->download_id);
+  if (ret != DOWNLOAD_ERROR_NONE) {
+    LoggerE("%s", get_error_message(ret));
+  }
+
+  ret = download_unset_progress_cb(diPtr->download_id);
+  if (ret != DOWNLOAD_ERROR_NONE) {
+    LoggerE("%s", get_error_message(ret));
+  }
+
+  ret = download_destroy(diPtr->download_id);
   if (DOWNLOAD_ERROR_NONE != ret) {
     LoggerE("%s", get_error_message(ret));
   }