Workaround for update installation detection 11/40011/2 accepted/tizen/common/20150529.082356 accepted/tizen/mobile/20150529.101113 accepted/tizen/tv/20150529.101058 submit/tizen/20150529.052307
authorTomasz Iwanek <t.iwanek@samsung.com>
Tue, 26 May 2015 13:31:41 +0000 (15:31 +0200)
committerTomasz Iwanek <t.iwanek@samsung.com>
Wed, 27 May 2015 14:34:01 +0000 (16:34 +0200)
This workaround is provided as pkgmgr requested.

This should be removed as soon as pkgmgr will handle
update detection and be passing correct options.

Removal of this should be easy as it is not modifing any flow
in installer.

Depends on pkgmgr: https://review.tizen.org/gerrit/#/c/38771/

Change-Id: Idae3b4ffd7842babc555c717986fe9beac39fece

src/wgt/CMakeLists.txt
src/wgt/update_workaround.cc [new file with mode: 0644]
src/wgt/update_workaround.h [new file with mode: 0644]
src/wgt/wgt_backend.cc

index a54575c..2cb946c 100644 (file)
@@ -2,6 +2,7 @@
 SET(SRCS
   step/step_parse.cc
   step/step_create_symbolic_link.cc
+  update_workaround.cc
   wgt_backend.cc
 )
 
diff --git a/src/wgt/update_workaround.cc b/src/wgt/update_workaround.cc
new file mode 100644 (file)
index 0000000..944cc02
--- /dev/null
@@ -0,0 +1,125 @@
+// 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 "wgt/update_workaround.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 <manifest_handlers/application_manifest_constants.h>
+#include <manifest_handlers/tizen_application_handler.h>
+#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 "utils/file_util.h"
+#include "utils/logging.h"
+
+namespace bf = boost::filesystem;
+namespace bs = boost::system;
+
+namespace {
+
+std::pair<std::string, int> GetInstallationPackagePath(int argc, char** argv) {
+  int index = -1;
+  std::string path;
+  for (unsigned i = 0; i < argc; ++i) {
+    if (!strcmp(argv[i], "-i")) {
+      index = i;
+      if (i + 1 < argc) {
+        path = argv[i + 1];
+      }
+      break;
+    }
+  }
+  return std::make_pair(path, index);
+}
+
+std::string GetAppIdFromPath(const std::string& path) {
+  bf::path tmp_path = common_installer::utils::GenerateTmpDir("/tmp");
+  bs::error_code code;
+  bf::create_directories(tmp_path, code);
+  if (code)
+    return {};
+  if (!common_installer::utils::ExtractToTmpDir(path.c_str(), tmp_path,
+      "config.xml")) {
+    bf::remove_all(tmp_path, code);
+    return {};
+  }
+  bf::path config_path = tmp_path / "config.xml";
+  std::vector<parser::ManifestHandler*> handlers = {
+    new wgt::parse::WidgetHandler(),
+    new wgt::parse::TizenApplicationHandler()
+  };
+  std::unique_ptr<parser::ManifestHandlerRegistry> registry(
+      new parser::ManifestHandlerRegistry(handlers));
+  std::unique_ptr<parser::ManifestParser> parser(
+      new parser::ManifestParser(std::move(registry)));
+  if (!parser->ParseManifest(config_path)) {
+    bf::remove_all(tmp_path, code);
+    return {};
+  }
+  auto info = std::static_pointer_cast<const wgt::parse::TizenApplicationInfo>(
+      parser->GetManifestData(
+          wgt::application_widget_keys::kTizenApplicationKey));
+  if (!info) {
+    bf::remove_all(tmp_path, code);
+    return {};
+  }
+  std::string pkg_id = info->package();
+
+  bf::remove_all(tmp_path, code);
+  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;
+}
+
+void OverwriteArgvForUpdate(int index, char** argv) {
+  // overwriting argv to fake update
+  argv[index][1] = 'a';
+}
+
+}  // namespace
+
+namespace workaround {
+
+void OverwriteArgvIfNeeded(int argc, char** argv) {
+  std::string path;
+  int index;
+  std::tie(path, index) =
+      GetInstallationPackagePath(argc, argv);
+  if (path.empty()) {
+    // not the installaton
+    return;
+  }
+  std::string pkg_id = GetAppIdFromPath(path);
+  if (pkg_id.empty())
+    return;
+  bool should_hack = IsPackageInstalled(pkg_id);
+  if (should_hack) {
+    LOG(INFO) << "Update detected - hacking argv to update installation";
+    OverwriteArgvForUpdate(index, argv);
+  }
+}
+
+}  // namespace workaround
diff --git a/src/wgt/update_workaround.h b/src/wgt/update_workaround.h
new file mode 100644 (file)
index 0000000..bb455af
--- /dev/null
@@ -0,0 +1,14 @@
+// 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 WGT_UPDATE_WORKAROUND_H_
+#define WGT_UPDATE_WORKAROUND_H_
+
+namespace workaround {
+
+void OverwriteArgvIfNeeded(int argc, char** argv);
+
+}  // namespace workaround
+
+#endif  // WGT_UPDATE_WORKAROUND_H_
index 34c1f39..fb2d699 100644 (file)
 #include "common/step/step_unzip.h"
 #include "common/step/step_update_app.h"
 #include "common/step/step_update_security.h"
+
+#include "wgt/update_workaround.h"
+
 #include "wgt/step/step_parse.h"
 #include "wgt/step/step_create_symbolic_link.h"
 
-
 namespace ci = common_installer;
 
 int main(int argc, char** argv) {
+  // TODO(t.iwanek): remove this when update installation detection is ready
+  workaround::OverwriteArgvIfNeeded(argc, argv);
+
   int result = ci::PkgMgrInterface::Init(argc, argv);
   if (result) {
     LOG(ERROR) << "Cannot connect to PkgMgrInstaller";