Simple validation of features 82/72782/12
authorTomasz Iwanek <t.iwanek@samsung.com>
Thu, 2 Jun 2016 09:54:12 +0000 (11:54 +0200)
committerjongmyeong ko <jongmyeong.ko@samsung.com>
Mon, 20 Jun 2016 07:27:42 +0000 (00:27 -0700)
Validation is added in StepParseManifest instead of:
 - parser - parsing should not check platform details
 - separate step - there is no feature field in manifest_x

Verification requires installing tpk package with some features and testing
via manipulating /etc/config/model-config.xml

There is only check if feature of given type exists in model-config.xml

Requires:
 - https://review.tizen.org/gerrit/72780
 - https://review.tizen.org/gerrit/74004

Change-Id: I521c0e18f76bf7eeecc56ee10cb31ce9f848378a

CMakeLists.txt
packaging/app-installers.spec
src/common/CMakeLists.txt
src/common/feature_validator.cc [new file with mode: 0644]
src/common/feature_validator.h [new file with mode: 0644]
src/common/step/configuration/step_parse_manifest.cc
src/common/step/configuration/step_parse_manifest.h

index d1b2ba2..10f1ed1 100644 (file)
@@ -58,6 +58,7 @@ PKG_CHECK_MODULES(DBUS_DEPS REQUIRED dbus-1)
 PKG_CHECK_MODULES(GDBUS_DEPS REQUIRED glib-2.0 gio-2.0)
 PKG_CHECK_MODULES(GUM_DEPS REQUIRED libgum)
 PKG_CHECK_MODULES(APP2SD_DEPS REQUIRED app2sd)
+PKG_CHECK_MODULES(CAPI_SYSTEM_INFO_DEPS REQUIRED capi-system-info)
 
 FIND_PACKAGE(Boost REQUIRED COMPONENTS system filesystem regex program_options)
 FIND_PACKAGE(GTest REQUIRED)
index 219c831..90fe6c9 100644 (file)
@@ -36,6 +36,7 @@ BuildRequires:  pkgconfig(dbus-1)
 BuildRequires:  pkgconfig(aul)
 BuildRequires:  pkgconfig(libgum)
 BuildRequires:  pkgconfig(app2sd)
+BuildRequires:  pkgconfig(capi-system-info)
 
 Requires: ca-certificates-tizen
 Requires: libtzplatform-config
index f527b65..88e86ba 100644 (file)
@@ -5,6 +5,7 @@ SET(SRCS
   backup_paths.cc
   certificate_validation.cc
   external_storage.cc
+  feature_validator.cc
   installer_context.cc
   pkgdir_tool_request.cc
   plugins/plugin_factory.cc
@@ -110,6 +111,7 @@ APPLY_PKG_CONFIG(${TARGET_LIBNAME_COMMON} PUBLIC
   GDBUS_DEPS
   GUM_DEPS
   APP2SD_DEPS
+  CAPI_SYSTEM_INFO_DEPS
   Boost
 )
 
diff --git a/src/common/feature_validator.cc b/src/common/feature_validator.cc
new file mode 100644 (file)
index 0000000..9e6900e
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/feature_validator.h"
+
+#include <boost/scope_exit.hpp>
+
+#include <system_info.h>
+
+namespace {
+
+const char kTrueFeature[] = "true";
+
+}  // namespace
+
+namespace common_installer {
+
+FeatureValidator::FeatureValidator(
+    const std::map<std::string, std::string>& features)
+    : features_(features) {
+}
+
+bool FeatureValidator::Validate(std::string* error) {
+  for (auto& pair : features_) {
+    const auto& feature = pair.first;
+    const auto& value = pair.second;
+
+    system_info_type_e type;
+    int ret = system_info_get_platform_type(feature.c_str(), &type);
+    if (ret != SYSTEM_INFO_ERROR_NONE) {
+      *error = std::string("Unknown feature: ") + feature;
+      return false;
+    }
+    bool ok = false;
+    switch (type) {
+    case SYSTEM_INFO_BOOL:
+      ok = ValidateBoolean(feature, value, error);
+      break;
+    case SYSTEM_INFO_INT:
+      ok = ValidateInteger(feature, value, error);
+      break;
+    case SYSTEM_INFO_STRING:
+      ok = ValidateString(feature, value, error);
+      break;
+    case SYSTEM_INFO_DOUBLE:
+      // There is no double typed feature on platform, no way to interpret it
+      ok = true;
+      break;
+    default:
+      ok = false;
+      *error = "Unknown type of feature";
+    }
+    if (!ok)
+      return false;
+  }
+  return true;
+}
+
+bool FeatureValidator::ValidateBoolean(
+    const std::string& feature, const std::string& value, std::string* error) {
+  bool supported = false;
+  int ret = system_info_get_platform_bool(feature.c_str(), &supported);
+  if (ret != SYSTEM_INFO_ERROR_NONE) {
+    *error = std::string("Failed to call system_info_get_platform_bool()") +
+        " for " + feature + ", error code: " + std::to_string(ret);
+    return false;
+  }
+  return true;
+}
+
+bool FeatureValidator::ValidateInteger(
+    const std::string& feature, const std::string& value, std::string* error) {
+  int platform_value = 0;
+  int ret = system_info_get_platform_int(feature.c_str(), &platform_value);
+  if (ret != SYSTEM_INFO_ERROR_NONE) {
+    *error = std::string("Failed to call system_info_get_platform_int()") +
+        " for " + feature + ", error code: " + std::to_string(ret);
+    return false;
+  }
+  return true;
+}
+
+bool FeatureValidator::ValidateString(
+    const std::string& feature, const std::string& value, std::string* error) {
+  char* text = nullptr;
+  BOOST_SCOPE_EXIT_ALL(text) {
+    free(text);
+  };
+  int ret = system_info_get_platform_string(feature.c_str(), &text);
+  if (ret != SYSTEM_INFO_ERROR_NONE) {
+    *error = std::string("Failed to call system_info_get_platform_string()") +
+        " for " + feature + ", error code: " + std::to_string(ret);
+    return false;
+  }
+  return true;
+}
+
+}  // namespace common_installer
diff --git a/src/common/feature_validator.h b/src/common/feature_validator.h
new file mode 100644 (file)
index 0000000..77314e8
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_FEATURE_VALIDATOR_H_
+#define COMMON_FEATURE_VALIDATOR_H_
+
+#include <map>
+#include <string>
+
+namespace common_installer {
+
+class FeatureValidator {
+ public:
+  explicit FeatureValidator(const std::map<std::string, std::string>& features);
+  bool Validate(std::string* error);
+
+ private:
+  bool ValidateBoolean(
+      const std::string& feature, const std::string& value, std::string* error);
+  bool ValidateInteger(
+      const std::string& feature, const std::string& value, std::string* error);
+  bool ValidateString(
+      const std::string& feature, const std::string& value, std::string* error);
+
+  const std::map<std::string, std::string>& features_;
+};
+
+}  // namespace common_installer
+
+#endif  // COMMON_FEATURE_VALIDATOR_H_
index 29eb916..7613f5f 100644 (file)
@@ -11,6 +11,7 @@
 #include <tpk_manifest_handlers/application_manifest_constants.h>
 #include <tpk_manifest_handlers/author_handler.h>
 #include <tpk_manifest_handlers/description_handler.h>
+#include <tpk_manifest_handlers/feature_handler.h>
 #include <tpk_manifest_handlers/package_handler.h>
 #include <tpk_manifest_handlers/privileges_handler.h>
 #include <tpk_manifest_handlers/profile_handler.h>
@@ -32,6 +33,7 @@
 
 #include "common/app_installer.h"
 #include "common/backup_paths.h"
+#include "common/feature_validator.h"
 #include "common/installer_context.h"
 #include "common/pkgmgr_registration.h"
 #include "common/step/step.h"
@@ -562,6 +564,23 @@ bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
   return true;
 }
 
+bool StepParseManifest::CheckFeatures() {
+  auto feature_info =
+        std::static_pointer_cast<const tpk::parse::FeatureInfo>(
+            parser_->GetManifestData(tpk::parse::FeatureInfo::Key()));
+  if (!feature_info)
+    return true;
+
+  std::string error;
+  FeatureValidator validator(feature_info->features());
+  if (!validator.Validate(&error)) {
+    LOG(ERROR) << "Feature validation error. " << error;
+    return false;
+  }
+
+  return true;
+}
+
 template <typename T>
 bool StepParseManifest::FillAppControl(application_x* app,
                                        const T& app_control_list) {
@@ -786,6 +805,9 @@ Step::Status StepParseManifest::process() {
     return Step::Status::PARSE_ERROR;
   }
 
+  if (!CheckFeatures())
+    return Status::PARSE_ERROR;
+
   if (manifest_location_ == ManifestLocation::INSTALLED) {
     // recovery of tep value for installed package
     std::string old_tep =
index bd72285..79d81dc 100644 (file)
@@ -71,6 +71,8 @@ class StepParseManifest : public common_installer::Step {
   bool FillUIApplication(manifest_x* manifest);
   bool FillWatchApplication(manifest_x* manifest);
 
+  bool CheckFeatures();
+
   template <typename T>
       bool FillAppControl(application_x* manifest, const T& app_control_list);
   template <typename T>