Update detection for tpk backend 04/45904/4
authorTomasz Iwanek <t.iwanek@samsung.com>
Mon, 10 Aug 2015 13:42:21 +0000 (15:42 +0200)
committerPawel Sikorski <p.sikorski@samsung.com>
Fri, 14 Aug 2015 14:42:33 +0000 (16:42 +0200)
This commit adds detection of package update for tpk
backend.

Update fails due to coping shared directory when there is
one supplied by package. As there is no policy, I'm disabling
shared directory creation and TODO is left.

Change-Id: I5d2bd4f334babf3ce88cad9132dc70719b0feefd

src/common/pkgmgr_registration.cc
src/common/pkgmgr_registration.h
src/tpk/CMakeLists.txt
src/tpk/task.cc
src/tpk/task.h
src/tpk/tpk_app_query_interface.cc [new file with mode: 0644]
src/tpk/tpk_app_query_interface.h [new file with mode: 0644]
src/wgt/wgt_app_query_interface.cc

index 065c683..8cd08af 100644 (file)
@@ -154,4 +154,15 @@ std::string QueryCertificateAuthorCertificate(const std::string& pkgid,
   return old_author_certificate;
 }
 
+bool IsPackageInstalled(const std::string& pkg_id) {
+  pkgmgrinfo_pkginfo_h handle;
+  int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), getuid(),
+                                               &handle);
+  if (ret != PMINFO_R_OK)
+    return false;
+  pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+  return true;
+}
+
+
 }  // namespace common_installer
index 30c88ed..86fc48e 100644 (file)
@@ -25,6 +25,7 @@ bool UnregisterAppInPkgmgr(const boost::filesystem::path& xml_path,
                            const std::string& pkgid, uid_t uid);
 std::string QueryCertificateAuthorCertificate(const std::string& pkgid,
                                               uid_t uid);
+bool IsPackageInstalled(const std::string& pkg_id);
 
 }  // namespace common_installer
 
index 4e3bae3..00188ad 100644 (file)
@@ -10,6 +10,7 @@ SET(SRCS
     step/step_parse.cc
     step/step_create_symbolic_link.cc
     step/step_copy_manifest_xml.cc
+    tpk_app_query_interface.cc
     xml_parser/xml_parser.cc
 )
 ADD_EXECUTABLE(${TARGET_TPK} ${SRCS})
index 90c4681..99f8ef9 100644 (file)
@@ -8,10 +8,9 @@
 #include "common/step/step_backup_icons.h"
 #include "common/step/step_backup_manifest.h"
 #include "common/step/step_create_icons.h"
+#include "common/step/step_create_storage_directories.h"
 #include "common/step/step_copy.h"
 #include "common/step/step_copy_backup.h"
-#include "common/step/step_copy_storage_directories.h"
-#include "common/step/step_create_storage_directories.h"
 #include "common/step/step_check_old_certificate.h"
 #include "common/step/step_generate_xml.h"
 #include "common/step/step_old_manifest.h"
@@ -42,28 +41,22 @@ const char kPkgType[] = "tpk";
 
 namespace tpk {
 
-/* Constructor
- */
 Task::Task() {
 }
 
-
-/* Destructor
- */
-::tpk::Task::~Task() {
+Task::~Task() {
 }
 
-
 bool Task::Init(int argc, char** argv) {
-  pkgmgr_ = ci::PkgMgrInterface::Create(argc, argv);
+  query_interface_.reset(new TpkAppQueryInterface());
+  pkgmgr_ = ci::PkgMgrInterface::Create(argc, argv, query_interface_.get());
   if (!pkgmgr_) {
-    LOG(ERROR) << "Options of pkgmgr installer cannot be parsed";
+    LOG(ERROR) << "Cannot connect to PkgMgrInstaller";
     return false;
   }
   return true;
 }
 
-
 bool Task::Run() {
   switch (pkgmgr_->GetRequestType()) {
     case ci::RequestType::Install:
@@ -113,7 +106,8 @@ bool Task::Update() {
   ai.AddStep<ci::backup::StepBackupManifest>();
   ai.AddStep<ci::backup::StepBackupIcons>();
   ai.AddStep<ci::backup::StepCopyBackup>();
-  ai.AddStep<ci::filesystem::StepCopyStorageDirectories>();
+  ai.AddStep<ci::filesystem::StepCreateStorageDirectories>();
+  // TODO(t.iwanek): handle coping storage directories
   ai.AddStep<tpk::filesystem::StepCreateSymbolicLink>();
   ai.AddStep<ci::filesystem::StepCreateIcons>();
   ai.AddStep<ci::security::StepUpdateSecurity>();
index e3cfc12..e913190 100644 (file)
@@ -2,12 +2,15 @@
 #ifndef TPK_TASK_H_
 #define TPK_TASK_H_
 
+#include <memory>
+
 #ifdef HOSTTEST
 #include "test/mock_pkgmgr_installer.h"
 #endif
 #include "common/utils/logging.h"
 
 #include "common/pkgmgr_interface.h"
+#include "tpk/tpk_app_query_interface.h"
 
 namespace tpk {
 
@@ -25,6 +28,7 @@ class Task {
   bool Reinstall();
 
   common_installer::PkgMgrPtr pkgmgr_;
+  std::unique_ptr<TpkAppQueryInterface> query_interface_;
 
   SCOPE_LOG_TAG(TpkTask)
 };  //  class Task
diff --git a/src/tpk/tpk_app_query_interface.cc b/src/tpk/tpk_app_query_interface.cc
new file mode 100644 (file)
index 0000000..79cbc16
--- /dev/null
@@ -0,0 +1,94 @@
+// Copyright (c) 2015 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 "tpk/tpk_app_query_interface.h"
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/system/error_code.hpp>
+
+#include <memory>
+#include <string>
+
+#include "common/pkgmgr_registration.h"
+#include "common/utils/file_util.h"
+#include "common/utils/logging.h"
+#include "tpk/xml_parser/xml_parser.h"
+
+namespace bf = boost::filesystem;
+namespace bs = boost::system;
+namespace ci = common_installer;
+namespace xp = xml_parser;
+
+namespace {
+
+const char kManifestFileName[] = "tizen-manifest.xml";
+
+std::string GetInstallationPackagePath(int argc, char** argv) {
+  std::string path;
+  for (int i = 0; i < argc; ++i) {
+    if (!strcmp(argv[i], "-i")) {
+      if (i + 1 < argc) {
+        path = argv[i + 1];
+        break;
+      }
+    }
+  }
+  return path;
+}
+
+std::string GetPkgIdFromPath(const std::string& path) {
+  bf::path tmp_path = common_installer::GenerateTmpDir("/tmp");
+  bs::error_code code;
+  bf::create_directories(tmp_path, code);
+  if (code)
+    return {};
+  if (!common_installer::ExtractToTmpDir(path.c_str(), tmp_path,
+      kManifestFileName)) {
+    bf::remove_all(tmp_path, code);
+    return {};
+  }
+  bf::path manifest_path = tmp_path / kManifestFileName;
+  if (!bf::exists(manifest_path)) {
+    bf::remove_all(tmp_path, code);
+    return {};
+  }
+  xp::XmlParser parser;
+  std::unique_ptr<xp::XmlTree> tree(parser.ParseAndGetNewTree(
+      manifest_path.c_str()));
+  if (!tree) {
+    bf::remove_all(tmp_path, code);
+    return {};
+  }
+  xp::XmlElement* manifest = tree->GetRootElement();
+  if (!manifest) {
+    bf::remove_all(tmp_path, code);
+    return {};
+  }
+  std::string pkg_id = manifest->attr("package");
+  bf::remove_all(tmp_path, code);
+  return pkg_id;
+}
+
+}  // namespace
+
+namespace tpk {
+
+bool TpkAppQueryInterface::IsAppInstalledByArgv(int argc, char** argv) {
+  std::string path = GetInstallationPackagePath(argc, argv);
+  if (path.empty()) {
+    // not the installaton
+    return false;
+  }
+  std::string pkg_id = GetPkgIdFromPath(path);
+  if (pkg_id.empty())
+    return false;
+  return ci::IsPackageInstalled(pkg_id);
+}
+
+}  // namespace tpk
+
diff --git a/src/tpk/tpk_app_query_interface.h b/src/tpk/tpk_app_query_interface.h
new file mode 100644 (file)
index 0000000..bfe2a14
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright (c) 2015 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 TPK_TPK_APP_QUERY_INTERFACE_H_
+#define TPK_TPK_APP_QUERY_INTERFACE_H_
+
+#include "common/app_query_interface.h"
+
+namespace tpk {
+
+class TpkAppQueryInterface : public common_installer::AppQueryInterface {
+ public:
+  bool IsAppInstalledByArgv(int argc, char** argv) override;
+};
+
+}  // namespace tpk
+
+#endif  // TPK_TPK_APP_QUERY_INTERFACE_H_
index 5cccbb0..67cd524 100644 (file)
 #include <manifest_handlers/widget_handler.h>
 #include <manifest_parser/manifest_parser.h>
 
-#include <pkgmgr-info.h>
-
-#include <cstring>
 #include <memory>
 #include <string>
-#include <utility>
 #include <vector>
 
+#include "common/pkgmgr_registration.h"
 #include "common/utils/file_util.h"
 #include "common/utils/logging.h"
 
 namespace bf = boost::filesystem;
 namespace bs = boost::system;
+namespace ci = common_installer;
 
 namespace {
 
@@ -45,7 +43,7 @@ std::string GetInstallationPackagePath(int argc, char** argv) {
   return path;
 }
 
-std::string GetAppIdFromPath(const std::string& path) {
+std::string GetPkgIdFromPath(const std::string& path) {
   bf::path tmp_path = common_installer::GenerateTmpDir("/tmp");
   bs::error_code code;
   bf::create_directories(tmp_path, code);
@@ -82,16 +80,6 @@ std::string GetAppIdFromPath(const std::string& path) {
   return pkg_id;
 }
 
-bool IsPackageInstalled(const std::string& pkg_id) {
-  pkgmgrinfo_pkginfo_h handle;
-  int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), getuid(),
-                                               &handle);
-  if (ret != PMINFO_R_OK)
-    return false;
-  pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-  return true;
-}
-
 }  // namespace
 
 namespace wgt {
@@ -102,10 +90,10 @@ bool WgtAppQueryInterface::IsAppInstalledByArgv(int argc, char** argv) {
     // not the installaton
     return false;
   }
-  std::string pkg_id = GetAppIdFromPath(path);
+  std::string pkg_id = GetPkgIdFromPath(path);
   if (pkg_id.empty())
     return false;
-  return IsPackageInstalled(pkg_id);
+  return ci::IsPackageInstalled(pkg_id);
 }
 
 }  // namespace wgt