[Tizen] Initial migration of Common component from xwalk 33/163733/8
authorss440 <ss440.han@samsung.com>
Wed, 13 Dec 2017 06:13:28 +0000 (15:13 +0900)
committerYoungsoo Choi <kenshin.choi@samsung.com>
Fri, 29 Dec 2017 01:29:23 +0000 (01:29 +0000)
This common module is base of Runtime and Extension component.

Change-Id: If0163dc1671ef81bb353ddc496ec92aaaa705352
Signed-off-by: ss440 <ss440.han@samsung.com>
Signed-off-by: Youngsoo Choi <kenshin.choi@samsung.com>
34 files changed:
electron.gyp
packaging/electron-efl.spec
tizen/build/common.gypi [new file with mode: 0644]
tizen/build/cynara-client.gypi [new file with mode: 0644]
tizen/build/pkg-config.gypi [new file with mode: 0644]
tizen/build/xwalk_js2c.gypi [new file with mode: 0644]
tizen/common/CPPLINT.cfg [new file with mode: 0644]
tizen/common/app_control.cc [new file with mode: 0644]
tizen/common/app_control.h [new file with mode: 0644]
tizen/common/app_db.cc [new file with mode: 0644]
tizen/common/app_db.h [new file with mode: 0644]
tizen/common/app_db_sqlite.h [new file with mode: 0644]
tizen/common/application_data.cc [new file with mode: 0644]
tizen/common/application_data.h [new file with mode: 0644]
tizen/common/arraysize.h [new file with mode: 0644]
tizen/common/command_line.cc [new file with mode: 0644]
tizen/common/command_line.h [new file with mode: 0644]
tizen/common/common.gyp [new file with mode: 0644]
tizen/common/file_utils.cc [new file with mode: 0644]
tizen/common/file_utils.h [new file with mode: 0644]
tizen/common/locale_manager.cc [new file with mode: 0644]
tizen/common/locale_manager.h [new file with mode: 0644]
tizen/common/logger.h [new file with mode: 0644]
tizen/common/picojson.h [new file with mode: 0644]
tizen/common/platform_info.cc [new file with mode: 0644]
tizen/common/platform_info.h [new file with mode: 0644]
tizen/common/profiler.cc [new file with mode: 0644]
tizen/common/profiler.h [new file with mode: 0644]
tizen/common/resource_manager.cc [new file with mode: 0644]
tizen/common/resource_manager.h [new file with mode: 0644]
tizen/common/string_utils.cc [new file with mode: 0644]
tizen/common/string_utils.h [new file with mode: 0644]
tizen/common/url.cc [new file with mode: 0644]
tizen/common/url.h [new file with mode: 0644]

index e53c89a..011644e 100644 (file)
             },
           ],
         }],  # OS=="linux"
+        [ 'is_tizen==1', {
+          'dependencies': [
+            'tizen/common/common.gyp:*',
+          ],
+        }],  # is_tizen==1
       ],
     },  # target <(project_name)
     {
index 8f2ff28..06ec377 100755 (executable)
@@ -16,21 +16,39 @@ BuildRequires: python-accel-armv7l-cross-arm
 %ifarch aarch64
 BuildRequires: python-accel-aarch64-cross-aarch64
 %endif
+BuildRequires: pkgconfig(appsvc)
+BuildRequires: pkgconfig(aul)
+BuildRequires: pkgconfig(bundle)
+BuildRequires: pkgconfig(capi-appfw-application)
+BuildRequires: pkgconfig(capi-appfw-app-manager)
+BuildRequires: pkgconfig(capi-appfw-package-manager)
+BuildRequires: pkgconfig(capi-system-system-settings)
+BuildRequires: pkgconfig(capi-system-info)
 BuildRequires: pkgconfig(chromium-efl)
+BuildRequires: pkgconfig(cynara-client)
 BuildRequires: pkgconfig(dbus-glib-1)
+BuildRequires: pkgconfig(dlog)
 BuildRequires: pkgconfig(ecore-evas)
 BuildRequires: pkgconfig(efl-extension)
 BuildRequires: pkgconfig(elementary)
 BuildRequires: pkgconfig(evas)
 BuildRequires: pkgconfig(expat)
+BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(gmodule-2.0)
 BuildRequires: pkgconfig(icu-i18n)
 # It's added to use TZ_SYS_RO_PACKAGES.
 BuildRequires: pkgconfig(libtzplatform-config)
+BuildRequires: pkgconfig(libwebappenc)
+BuildRequires: pkgconfig(manifest-parser)
 BuildRequires: pkgconfig(nss)
+BuildRequires: pkgconfig(pkgmgr-info)
+BuildRequires: pkgconfig(sqlite3)
+BuildRequires: pkgconfig(uuid)
+BuildRequires: pkgconfig(ttrace)
 %if "%{?TIZEN_PRODUCT_TV}" == "1"
 BuildRequires: pkgconfig(vd-win-util)
 %endif
+BuildRequires: pkgconfig(wgt-manifest-handlers)
 
 Requires: /usr/bin/systemctl
 
diff --git a/tizen/build/common.gypi b/tizen/build/common.gypi
new file mode 100644 (file)
index 0000000..0bb2245
--- /dev/null
@@ -0,0 +1,57 @@
+{
+  'variables': {
+    'build_type%': 'Debug',
+#    'extension_path%': '<(extension_path)',
+#    'injected_bundle_path%': '<(injected_bundle_path)',
+  },
+  'target_defaults': {
+    'variables': {
+      'build_type%': '<(build_type)',
+    },
+    'conditions': [
+      ['is_tizen==1', {
+        'cflags': [ '-fPIC' ],
+        'cflags_cc': [ '-fPIC']
+      }],
+      ['build_type== "Debug"', {
+        'defines': ['_DEBUG', 'TIZEN_DEBUG_ENABLE', ],
+        'cflags': [ '-O0', '-g', ],
+      }],
+      ['build_type == "Release"', {
+        'defines': ['NDEBUG', ],
+        'cflags': [
+          '-O2',
+          # Don't emit the GCC version ident directives, they just end up
+          # in the .comment section taking up binary size.
+          '-fno-ident',
+          # Put data and code in their own sections, so that unused symbols
+          # can be removed at link time with --gc-sections.
+          '-fdata-sections',
+          '-ffunction-sections',
+        ],
+      }],
+    ],
+    'includes': [
+      'cynara-client.gypi',
+      'pkg-config.gypi',
+#      'xwalk_js2c.gypi',
+    ],
+    'include_dirs': [
+      '../',
+      '<(SHARED_INTERMEDIATE_DIR)',
+    ],
+#    'defines': [
+#      'EXTENSION_PATH="<(extension_path)"',
+#      'INJECTED_BUNDLE_PATH="<(injected_bundle_path)"',
+#    ],
+    'cflags': [
+      '-std=c++0x',
+      '-fPIC',
+      '-fvisibility=hidden',
+      '-Wall',
+    ],
+    'libraries' : [
+      '-L./lib',
+    ],
+  },
+}
\ No newline at end of file
diff --git a/tizen/build/cynara-client.gypi b/tizen/build/cynara-client.gypi
new file mode 100644 (file)
index 0000000..b0fac97
--- /dev/null
@@ -0,0 +1,16 @@
+{
+    'variables': {
+        'pkg-config': 'pkg-config',
+    },
+    'cflags': [
+        '<!@(<(pkg-config) --cflags cynara-client)'
+    ],
+    'link_settings': {
+        'ldflags': [
+            '<!@(<(pkg-config) --libs-only-L --libs-only-other cynara-client)',
+        ],
+        'libraries': [
+            '<!@(<(pkg-config) --libs-only-l cynara-client)',
+        ],
+    },
+} # cynara-client
diff --git a/tizen/build/pkg-config.gypi b/tizen/build/pkg-config.gypi
new file mode 100644 (file)
index 0000000..47410ef
--- /dev/null
@@ -0,0 +1,18 @@
+{
+  'variables': {
+    'packages%': [],
+  },
+
+  'cflags': [
+    '>!@(if [ -n ">@(packages)" ]; then pkg-config --cflags >@(packages); fi)'
+  ],
+
+  'link_settings': {
+    'ldflags': [
+      '>!@(if [ -n ">@(packages)" ]; then pkg-config --libs-only-L --libs-only-other >@(packages); fi)',
+    ],
+    'libraries': [
+      '>!@(if [ -n ">@(packages)" ]; then pkg-config --libs-only-l >@(packages); fi)',
+    ],
+  },
+}
diff --git a/tizen/build/xwalk_js2c.gypi b/tizen/build/xwalk_js2c.gypi
new file mode 100644 (file)
index 0000000..9b2b930
--- /dev/null
@@ -0,0 +1,23 @@
+{
+  'rules': [
+    {
+      'rule_name': 'xwalk_js2c',
+      'extension': 'js',
+      'inputs': [
+        '../tools/generate_api.py',
+      ],
+      'outputs': [
+        '<(SHARED_INTERMEDIATE_DIR)/<(RULE_INPUT_ROOT).cc'
+      ],
+      'process_outputs_as_sources': 1,
+      'action': [
+        'python',
+        '<@(_inputs)',
+        '<(RULE_INPUT_PATH)',
+        'kSource_<(RULE_INPUT_ROOT)',
+        '<@(_outputs)',
+      ],
+      'message': 'Generating code from <(RULE_INPUT_PATH)',
+    },
+  ],
+}
diff --git a/tizen/common/CPPLINT.cfg b/tizen/common/CPPLINT.cfg
new file mode 100644 (file)
index 0000000..c2b1111
--- /dev/null
@@ -0,0 +1 @@
+exclude_files=picojson\.h
\ No newline at end of file
diff --git a/tizen/common/app_control.cc b/tizen/common/app_control.cc
new file mode 100644 (file)
index 0000000..6b2e4dc
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "common/app_control.h"
+
+#include <appsvc.h>
+#include <app_control_internal.h>
+#include <bundle_internal.h>
+
+#include <algorithm>
+#include <memory>
+#include <map>
+#include <regex>  // NOLINT
+#include <utility>
+#include <vector>
+
+#include "common/file_utils.h"
+#include "common/logger.h"
+#include "common/string_utils.h"
+
+namespace common {
+
+namespace {
+static bool BundleAddData(bundle* target,
+                          const std::string& key,
+                          const std::string& value) {
+  int result = appsvc_add_data(target, key.c_str(), value.c_str());
+  if (result < 0) {
+    LOGGER(ERROR) << "Failed to add data to appsvc.";
+    return false;
+  } else {
+    return true;
+  }
+}
+
+static bool BundleAddDataArray(bundle* target,
+                               const std::string& key,
+                               const std::vector<std::string>& value_array) {
+  int n = value_array.size();
+  std::vector<const char*> v;
+  std::for_each(value_array.begin(), value_array.end(),
+                [&v](const std::string& str) {
+                  v.push_back(static_cast<const char*>(str.c_str()));
+                });
+
+  int result = appsvc_add_data_array(target, key.c_str(), v.data(), n);
+  if (result < 0) {
+    LOGGER(ERROR) << "Failed to add an array of data to appsvc.";
+    return false;
+  } else {
+    return true;
+  }
+}
+
+static const std::string GetOperationFromScheme(const std::string& scheme) {
+  static std::map<const std::string, const std::string> table = {
+      {"sms", APP_CONTROL_OPERATION_COMPOSE},
+      {"mmsto", APP_CONTROL_OPERATION_COMPOSE},
+      {"mailto", APP_CONTROL_OPERATION_COMPOSE},
+      {"tel", APP_CONTROL_OPERATION_CALL}};
+  auto found = table.find(scheme);
+  if (found == table.end()) {
+    // default operation
+    return APP_CONTROL_OPERATION_VIEW;
+  }
+  return found->second;
+}
+
+static void AppendExtraDatafromUrl(AppControl* request,
+                                   const std::string& url) {
+  static std::vector<std::pair<std::string, std::string>> patterns = {
+      {".*[?&]body=([^&]+).*", APP_CONTROL_DATA_TEXT},
+      {".*[?&]cc=([^&]+).*", APP_CONTROL_DATA_CC},
+      {".*[?&]bcc=([^&]+).*", APP_CONTROL_DATA_BCC},
+      {".*[?&]subject=([^&]+).*", APP_CONTROL_DATA_SUBJECT},
+      {".*[?&]to=([^&]+).*", APP_CONTROL_DATA_TO},
+      {"sms:([^?&]+).*", APP_CONTROL_DATA_TO},
+      {"mmsto:([^?&]+).*", APP_CONTROL_DATA_TO},
+      {"mailto:([^?&]+).*", APP_CONTROL_DATA_TO}};
+
+  for (auto& param : patterns) {
+    std::regex pattern(param.first, std::regex_constants::icase);
+    std::smatch result;
+    if (std::regex_match(url, result, pattern) && result.size() >= 2) {
+      std::string extra_data = result[1].str();
+      request->AddData(param.second, utils::UrlDecode(extra_data));
+    }
+  }
+}
+
+}  // namespace
+
+AppControl::AppControl(app_control_h app_control) {
+  app_control_clone(&app_control_, app_control);
+  app_control_to_bundle(app_control_, &app_control_bundle_);
+}
+
+AppControl::AppControl() {
+  app_control_create(&app_control_);
+  app_control_to_bundle(app_control_, &app_control_bundle_);
+}
+
+AppControl::~AppControl() {
+  if (app_control_ != NULL) {
+    app_control_destroy(app_control_);
+  }
+}
+
+std::string AppControl::operation() const {
+  const char* operation = appsvc_get_operation(app_control_bundle_);
+
+  if (operation != NULL) {
+    return std::string(operation);
+  } else {
+    return std::string();
+  }
+}
+
+void AppControl::set_operation(const std::string& operation) {
+  appsvc_set_operation(app_control_bundle_, operation.c_str());
+}
+
+std::string AppControl::mime() const {
+  const char* mime = appsvc_get_mime(app_control_bundle_);
+
+  if (mime != NULL) {
+    return std::string(mime);
+  } else {
+    return std::string();
+  }
+}
+
+void AppControl::set_mime(const std::string& mime) {
+  appsvc_set_mime(app_control_bundle_, mime.c_str());
+}
+
+std::string AppControl::uri() const {
+  const char* uri = appsvc_get_uri(app_control_bundle_);
+
+  if (uri != NULL) {
+    return std::string(uri);
+  } else {
+    return std::string();
+  }
+}
+
+void AppControl::set_uri(const std::string& uri) {
+  appsvc_set_uri(app_control_bundle_, uri.c_str());
+}
+
+std::string AppControl::category() const {
+  const char* category = appsvc_get_category(app_control_bundle_);
+
+  if (category != NULL) {
+    return std::string(category);
+  } else {
+    return std::string();
+  }
+}
+
+void AppControl::set_category(const std::string& category) {
+  appsvc_set_category(app_control_bundle_, category.c_str());
+}
+
+std::string AppControl::data(const std::string& key) const {
+  const char* data = appsvc_get_data(app_control_bundle_, key.c_str());
+
+  if (data != NULL) {
+    return std::string(data);
+  } else {
+    return std::string();
+  }
+}
+
+std::vector<std::string> AppControl::data_array(const std::string& key) const {
+  int data_array_len = 0;
+  const char** data_array =
+      appsvc_get_data_array(app_control_bundle_, key.c_str(), &data_array_len);
+  std::vector<std::string> data_vector;
+  if (data_array) {  // checking whether the 'data_array' is valid
+    if (data_array_len > 0) {
+      for (int i = 0; i < data_array_len; i++) {
+        data_vector.push_back(data_array[i]);
+      }
+    }
+  }
+  return data_vector;
+}
+
+std::string AppControl::encoded_bundle() {
+  bundle_raw* encoded_data;
+  int len;
+  bundle_encode(app_control_bundle_, &encoded_data, &len);
+  std::unique_ptr<bundle_raw*, decltype(bundle_free_encoded_rawdata)*> ptr{
+      &encoded_data, bundle_free_encoded_rawdata};
+  return std::string(reinterpret_cast<char*>(encoded_data), len);
+}
+
+bool AppControl::IsDataArray(const std::string& key) {
+  return appsvc_data_is_array(app_control_bundle_, key.c_str());
+}
+
+bool AppControl::AddData(const std::string& key, const std::string& value) {
+  return BundleAddData(app_control_bundle_, key, value);
+}
+
+bool AppControl::AddDataArray(const std::string& key,
+                              const std::vector<std::string>& value_array) {
+  return BundleAddDataArray(app_control_bundle_, key, value_array);
+}
+
+bool AppControl::Reply(
+    const std::map<std::string, std::vector<std::string>>& data) {
+  bundle* result;
+  if (appsvc_create_result_bundle(app_control_bundle_, &result) !=
+      APPSVC_RET_OK) {
+    LOGGER(ERROR) << "Failed to craete result bundle.";
+    return false;
+  }
+  auto it = data.begin();
+  for (; it != data.end(); ++it) {
+    const std::string& key = it->first;
+    if (it->second.size() == 1) {
+      BundleAddData(result, key, it->second[0]);
+    } else {
+      BundleAddDataArray(result, key, it->second);
+    }
+  }
+
+  int ret = appsvc_send_result(result, APPSVC_RES_OK);
+  bundle_free(result);
+
+  return ret == APPSVC_RET_OK ? true : false;
+}
+
+bool AppControl::LaunchRequest() {
+  return (app_control_send_launch_request(app_control_, NULL, NULL) ==
+          APP_CONTROL_ERROR_NONE);
+}
+
+std::unique_ptr<AppControl> AppControl::MakeAppcontrolFromURL(
+    const std::string& url) {
+  std::string smsto_scheme("smsto");
+
+  std::string request_url(url);
+  std::string scheme = utils::SchemeName(request_url);
+  // smsto: does not supported by platform. change to sms:
+  if (scheme == smsto_scheme) {
+    request_url = "sms" + request_url.substr(smsto_scheme.length());
+    scheme = "sms";
+  }
+
+  std::unique_ptr<AppControl> request(new AppControl());
+  request->set_uri(request_url);
+  request->set_operation(GetOperationFromScheme(scheme));
+  AppendExtraDatafromUrl(request.get(), request_url);
+
+  return std::move(request);
+}
+
+}  // namespace common
diff --git a/tizen/common/app_control.h b/tizen/common/app_control.h
new file mode 100644 (file)
index 0000000..573d24a
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_APP_CONTROL_H_
+#define XWALK_COMMON_APP_CONTROL_H_
+
+#include <app_control.h>
+#include <bundle.h>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace common {
+
+class AppControl {
+ public:
+  static std::unique_ptr<AppControl> MakeAppcontrolFromURL(
+      const std::string& url);
+  explicit AppControl(app_control_h app_control);
+  AppControl();
+  ~AppControl();
+  // disable copy
+  AppControl(const AppControl& src) = delete;
+  AppControl& operator=(const AppControl&) = delete;
+
+  std::string operation() const;
+  void set_operation(const std::string& operation);
+  std::string mime() const;
+  void set_mime(const std::string& mime);
+  std::string uri() const;
+  void set_uri(const std::string& uri);
+  std::string category() const;
+  void set_category(const std::string& category);
+  std::string data(const std::string& key) const;
+  std::vector<std::string> data_array(const std::string& key) const;
+  std::string encoded_bundle();
+
+  bool IsDataArray(const std::string& key);
+  bool AddData(const std::string& key, const std::string& value);
+  bool AddDataArray(const std::string& key,
+                    const std::vector<std::string>& value_array);
+  bool Reply(const std::map<std::string, std::vector<std::string>>& data);
+  bool LaunchRequest();
+
+ private:
+  app_control_h app_control_;
+  bundle* app_control_bundle_;
+};
+
+}  // namespace common
+
+#endif  // XWALK_COMMON_APP_CONTROL_H_
diff --git a/tizen/common/app_db.cc b/tizen/common/app_db.cc
new file mode 100644 (file)
index 0000000..2ff096f
--- /dev/null
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "common/app_db.h"
+
+#include <app.h>
+#include <sqlite3.h>
+#include <unistd.h>
+#include <fstream>
+#include <memory>
+
+#include "common/logger.h"
+#include "common/string_utils.h"
+#include "common/file_utils.h"
+#include "common/picojson.h"
+#include "common/app_db_sqlite.h"
+
+namespace common {
+
+const char* kCreateDbQuery =
+    "CREATE TABLE IF NOT EXISTS appdb ("
+    "section TEXT, "
+    "key TEXT, "
+    "value TEXT,"
+    "PRIMARY KEY(section, key));";
+
+SqliteDB::SqliteDB(const std::string& app_data_path)
+    : app_data_path_(app_data_path), sqldb_(NULL) {
+  if (app_data_path_.empty()) {
+    std::unique_ptr<char, decltype(std::free)*> path{app_get_data_path(),
+                                                     std::free};
+    if (path.get() != NULL)
+      app_data_path_ = path.get();
+  }
+  Initialize();
+}
+
+SqliteDB::~SqliteDB() {
+  if (sqldb_ != NULL) {
+    sqlite3_close(sqldb_);
+    sqldb_ = NULL;
+  }
+}
+
+void SqliteDB::MigrationAppdb() {
+  // file check
+  std::string migration_path = app_data_path_ + ".runtime.migration";
+  if (!common::utils::Exists(migration_path)) {
+    return;
+  } else {
+    LOGGER(DEBUG) << "Migration file found : " << migration_path;
+  }
+
+  std::ifstream migration_file(migration_path);
+  if (!migration_file.is_open()) {
+    LOGGER(ERROR) << "Fail to open file";
+    return;
+  }
+  picojson::value v;
+  std::string err;
+  err = picojson::parse(v, migration_file);
+  if (!err.empty()) {
+    LOGGER(ERROR) << "Fail to parse file :" << err;
+    return;
+  }
+
+  LOGGER(DEBUG) << "Start to get list data";
+
+  picojson::array data_list;
+
+  if (!v.get("preference").is<picojson::null>()) {
+    picojson::array preference_list =
+        v.get("preference").get<picojson::array>();
+    data_list.insert(data_list.end(), preference_list.begin(),
+                     preference_list.end());
+  }
+  if (!v.get("certificate").is<picojson::null>()) {
+    picojson::array certificate_list =
+        v.get("certificate").get<picojson::array>();
+    data_list.insert(data_list.end(), certificate_list.begin(),
+                     certificate_list.end());
+  }
+  if (!v.get("security_origin").is<picojson::null>()) {
+    picojson::array security_origin_list =
+        v.get("security_origin").get<picojson::array>();
+    data_list.insert(data_list.end(), security_origin_list.begin(),
+                     security_origin_list.end());
+  }
+
+  for (auto it = data_list.begin(); it != data_list.end(); ++it) {
+    if (!it->is<picojson::object>())
+      continue;
+    std::string section = it->get("section").to_str();
+    std::string key = it->get("key").to_str();
+    std::string value = it->get("value").to_str();
+
+    LOGGER(DEBUG) << "INPUT[" << section << "][" << key << "][" << value << "]";
+    Set(section, key, value);
+  }
+
+  LOGGER(DEBUG) << "Migration complete";
+
+  if (0 != remove(migration_path.c_str())) {
+    LOGGER(ERROR) << "Fail to remove migration file";
+  }
+}
+
+void SqliteDB::Initialize() {
+  if (app_data_path_.empty()) {
+    LOGGER(ERROR) << "app data path was empty";
+    return;
+  }
+  std::string db_path = app_data_path_ + "/.appdb.db";
+  int ret = sqlite3_open(db_path.c_str(), &sqldb_);
+  if (ret != SQLITE_OK) {
+    LOGGER(ERROR) << "Fail to open app db :" << sqlite3_errmsg(sqldb_);
+    sqldb_ = NULL;
+    return;
+  }
+  sqlite3_busy_handler(sqldb_,
+                       [](void*, int count) {
+                         if (count < 5) {
+                           LOGGER(ERROR)
+                               << "App db was busy, Wait the lock count("
+                               << count << ")";
+                           usleep(100000 * (count + 1));
+                           return 1;
+                         } else {
+                           LOGGER(ERROR) << "App db was busy, Fail to access";
+                           return 0;
+                         }
+                       },
+                       NULL);
+
+  char* errmsg = NULL;
+  ret = sqlite3_exec(sqldb_, kCreateDbQuery, NULL, NULL, &errmsg);
+  if (ret != SQLITE_OK) {
+    LOGGER(ERROR) << "Error to create appdb : " << (errmsg ? errmsg : "");
+    if (errmsg)
+      sqlite3_free(errmsg);
+  }
+  MigrationAppdb();
+}
+
+bool SqliteDB::HasKey(const std::string& section,
+                      const std::string& key) const {
+  char* buffer = NULL;
+  sqlite3_stmt* stmt = NULL;
+  bool result = false;
+
+  int ret = 0;
+  buffer = sqlite3_mprintf(
+      "select count(*) from appdb where section = %Q and key = %Q",
+      section.c_str(), key.c_str());
+  if (buffer == NULL) {
+    LOGGER(ERROR) << "error to make query";
+    return false;
+  }
+
+  std::unique_ptr<char, decltype(sqlite3_free)*> scoped_data{buffer,
+                                                             sqlite3_free};
+
+  ret = sqlite3_prepare(sqldb_, buffer, strlen(buffer), &stmt, NULL);
+  if (ret != SQLITE_OK) {
+    LOGGER(ERROR) << "Fail to prepare query : " << sqlite3_errmsg(sqldb_);
+    return false;
+  }
+
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_ROW) {
+    int value = sqlite3_column_int(stmt, 0);
+    result = value > 0;
+  }
+
+  sqlite3_finalize(stmt);
+  return result;
+}
+
+std::string SqliteDB::Get(const std::string& section,
+                          const std::string& key) const {
+  char* buffer = NULL;
+  sqlite3_stmt* stmt = NULL;
+  std::string result;
+
+  int ret = 0;
+  buffer =
+      sqlite3_mprintf("select value from appdb where section = %Q and key = %Q",
+                      section.c_str(), key.c_str());
+  if (buffer == NULL) {
+    LOGGER(ERROR) << "error to make query";
+    return result;
+  }
+
+  std::unique_ptr<char, decltype(sqlite3_free)*> scoped_data{buffer,
+                                                             sqlite3_free};
+
+  ret = sqlite3_prepare(sqldb_, buffer, strlen(buffer), &stmt, NULL);
+  if (ret != SQLITE_OK) {
+    LOGGER(ERROR) << "Fail to prepare query : " << sqlite3_errmsg(sqldb_);
+    return result;
+  }
+
+  ret = sqlite3_step(stmt);
+  if (ret == SQLITE_ROW) {
+    result = std::string(
+        reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
+  }
+
+  sqlite3_finalize(stmt);
+  return result;
+}
+
+void SqliteDB::Set(const std::string& section,
+                   const std::string& key,
+                   const std::string& value) {
+  char* buffer = NULL;
+  sqlite3_stmt* stmt = NULL;
+
+  int ret = 0;
+  buffer = sqlite3_mprintf(
+      "replace into appdb (section, key, value) values (?, ?, ?);");
+  if (buffer == NULL) {
+    LOGGER(ERROR) << "error to make query";
+    return;
+  }
+
+  std::unique_ptr<char, decltype(sqlite3_free)*> scoped_data{buffer,
+                                                             sqlite3_free};
+
+  ret = sqlite3_prepare(sqldb_, buffer, strlen(buffer), &stmt, NULL);
+  if (ret != SQLITE_OK) {
+    LOGGER(ERROR) << "Fail to prepare query : " << sqlite3_errmsg(sqldb_);
+    return;
+  }
+
+  std::unique_ptr<sqlite3_stmt, decltype(sqlite3_finalize)*> scoped_stmt{
+      stmt, sqlite3_finalize};
+
+  ret = sqlite3_bind_text(stmt, 1, section.c_str(), section.length(),
+                          SQLITE_STATIC);
+  if (ret != SQLITE_OK) {
+    LOGGER(ERROR) << "Fail to prepare query bind argument : "
+                  << sqlite3_errmsg(sqldb_);
+    return;
+  }
+  ret = sqlite3_bind_text(stmt, 2, key.c_str(), key.length(), SQLITE_STATIC);
+  if (ret != SQLITE_OK) {
+    LOGGER(ERROR) << "Fail to prepare query bind argument : "
+                  << sqlite3_errmsg(sqldb_);
+    return;
+  }
+  ret =
+      sqlite3_bind_text(stmt, 3, value.c_str(), value.length(), SQLITE_STATIC);
+  if (ret != SQLITE_OK) {
+    LOGGER(ERROR) << "Fail to prepare query bind argument : "
+                  << sqlite3_errmsg(sqldb_);
+    return;
+  }
+  ret = sqlite3_step(stmt);
+  if (ret != SQLITE_DONE) {
+    LOGGER(ERROR) << "Fail to insert data : " << sqlite3_errmsg(sqldb_);
+  }
+}
+
+void SqliteDB::Remove(const std::string& section, const std::string& key) {
+  char* buffer = NULL;
+
+  buffer = sqlite3_mprintf("delete from appdb where section = %Q and key = %Q",
+                           section.c_str(), key.c_str());
+
+  if (buffer == NULL) {
+    LOGGER(ERROR) << "error to make query";
+    return;
+  }
+
+  std::unique_ptr<char, decltype(sqlite3_free)*> scoped_data{buffer,
+                                                             sqlite3_free};
+
+  char* errmsg = NULL;
+  int ret = sqlite3_exec(sqldb_, buffer, NULL, NULL, &errmsg);
+  if (ret != SQLITE_OK) {
+    LOGGER(ERROR) << "Error to delete value : " << (errmsg ? errmsg : "");
+    if (errmsg)
+      sqlite3_free(errmsg);
+  }
+}
+
+void SqliteDB::GetKeys(const std::string& section,
+                       std::list<std::string>* keys) const {
+  char* buffer = NULL;
+  sqlite3_stmt* stmt = NULL;
+
+  int ret = 0;
+  buffer = sqlite3_mprintf("select key from appdb where section = %Q",
+                           section.c_str());
+  if (buffer == NULL) {
+    LOGGER(ERROR) << "error to make query";
+    return;
+  }
+
+  std::unique_ptr<char, decltype(sqlite3_free)*> scoped_data{buffer,
+                                                             sqlite3_free};
+
+  ret = sqlite3_prepare(sqldb_, buffer, strlen(buffer), &stmt, NULL);
+  if (ret != SQLITE_OK) {
+    LOGGER(ERROR) << "Fail to prepare query : " << sqlite3_errmsg(sqldb_);
+    return;
+  }
+
+  ret = sqlite3_step(stmt);
+  while (ret == SQLITE_ROW) {
+    const char* value =
+        reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
+    keys->push_back(std::string(value));
+    ret = sqlite3_step(stmt);
+  }
+
+  sqlite3_finalize(stmt);
+  return;
+}
+
+AppDB* AppDB::GetInstance() {
+  static SqliteDB instance;
+  return &instance;
+}
+
+}  // namespace common
diff --git a/tizen/common/app_db.h b/tizen/common/app_db.h
new file mode 100644 (file)
index 0000000..9dfac06
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_APP_DB_H_
+#define XWALK_COMMON_APP_DB_H_
+
+#include <list>
+#include <string>
+
+namespace common {
+
+class AppDB {
+ public:
+  static AppDB* GetInstance();
+  virtual bool HasKey(const std::string& section,
+                      const std::string& key) const = 0;
+  virtual std::string Get(const std::string& section,
+                          const std::string& key) const = 0;
+  virtual void Set(const std::string& section,
+                   const std::string& key,
+                   const std::string& value) = 0;
+  virtual void GetKeys(const std::string& section,
+                       std::list<std::string>* keys) const = 0;
+  virtual void Remove(const std::string& section, const std::string& key) = 0;
+};
+}  // namespace common
+
+#endif  // XWALK_COMMON_APP_DB_H_
diff --git a/tizen/common/app_db_sqlite.h b/tizen/common/app_db_sqlite.h
new file mode 100644 (file)
index 0000000..7174580
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_APP_DB_SQLITE_H_
+#define XWALK_COMMON_APP_DB_SQLITE_H_
+
+#include <list>
+#include <string>
+
+#include "common/app_db.h"
+
+class sqlite3;
+
+namespace common {
+class SqliteDB : public AppDB {
+ public:
+  explicit SqliteDB(const std::string& app_data_path = std::string());
+  ~SqliteDB();
+  virtual bool HasKey(const std::string& section, const std::string& key) const;
+  virtual std::string Get(const std::string& section,
+                          const std::string& key) const;
+  virtual void Set(const std::string& section,
+                   const std::string& key,
+                   const std::string& value);
+  virtual void GetKeys(const std::string& section,
+                       std::list<std::string>* keys) const;
+  virtual void Remove(const std::string& section, const std::string& key);
+
+ private:
+  void Initialize();
+  void MigrationAppdb();
+  std::string app_data_path_;
+  sqlite3* sqldb_;
+};
+
+}  //  namespace common
+
+#endif  // XWALK_COMMON_APP_DB_SQLITE_H_
diff --git a/tizen/common/application_data.cc b/tizen/common/application_data.cc
new file mode 100644 (file)
index 0000000..48b4f3a
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "common/application_data.h"
+
+#include <package_manager.h>
+#include <wgt_manifest_handlers/application_manifest_constants.h>
+#include <wgt_manifest_handlers/widget_config_parser.h>
+#include <app_manager.h>
+#include <app_common.h>
+
+#include <vector>
+
+#include "common/file_utils.h"
+#include "common/logger.h"
+#include "common/profiler.h"
+#include "common/platform_info.h"
+
+namespace common {
+
+namespace {
+
+const char* kPathSeparator = "/";
+const char* kConfigXml = "config.xml";
+const char* kWgtPath = "wgt";
+
+const char* kImeCategory = "http://tizen.org/category/ime";
+const char* kIdleClockCategory = "com.samsung.wmanager.WATCH_CLOCK";
+const char* kWearableClockCategory = "http://tizen.org/category/wearable_clock";
+
+}  // namespace
+
+ApplicationData::ApplicationData(const std::string& appid)
+    : app_id_(appid), loaded_(false) {
+  SCOPE_PROFILE();
+  char* res_path = app_get_resource_path();
+  if (res_path != NULL) {
+    application_path_ = std::string(res_path) + kWgtPath + kPathSeparator;
+    free(res_path);
+  }
+}
+
+ApplicationData::~ApplicationData() {}
+
+std::shared_ptr<const wgt::parse::AppControlInfoList>
+ApplicationData::app_control_info_list() const {
+  return app_control_info_list_;
+}
+
+std::shared_ptr<const wgt::parse::CategoryInfoList>
+ApplicationData::category_info_list() const {
+  return category_info_list_;
+}
+
+std::shared_ptr<const wgt::parse::MetaDataInfo>
+ApplicationData::meta_data_info() const {
+  return meta_data_info_;
+}
+
+std::shared_ptr<const wgt::parse::AllowedNavigationInfo>
+ApplicationData::allowed_navigation_info() const {
+  return allowed_navigation_info_;
+}
+
+std::shared_ptr<const wgt::parse::PermissionsInfo>
+ApplicationData::permissions_info() const {
+  return permissions_info_;
+}
+
+std::shared_ptr<const wgt::parse::SettingInfo> ApplicationData::setting_info()
+    const {
+  return setting_info_;
+}
+
+std::shared_ptr<const wgt::parse::LaunchScreenInfo>
+ApplicationData::splash_screen_info() const {
+  return splash_screen_info_;
+}
+
+std::shared_ptr<const wgt::parse::TizenApplicationInfo>
+ApplicationData::tizen_application_info() const {
+  return tizen_application_info_;
+}
+
+std::shared_ptr<const wgt::parse::WidgetInfo> ApplicationData::widget_info()
+    const {
+  return widget_info_;
+}
+
+std::shared_ptr<const wgt::parse::ContentInfo> ApplicationData::content_info()
+    const {
+  return content_info_;
+}
+
+std::shared_ptr<const wgt::parse::WarpInfo> ApplicationData::warp_info() const {
+  return warp_info_;
+}
+
+std::shared_ptr<const wgt::parse::CSPInfo> ApplicationData::csp_info() const {
+  return csp_info_;
+}
+
+std::shared_ptr<const wgt::parse::CSPInfo> ApplicationData::csp_report_info()
+    const {
+  return csp_report_info_;
+}
+
+const std::string ApplicationData::pkg_id() const {
+  if (pkg_id_.empty()) {
+    app_info_h app_info;
+    int ret = app_info_create(app_id_.c_str(), &app_info);
+    if (ret == APP_MANAGER_ERROR_NONE) {
+      char* pkg = NULL;
+      ret = app_info_get_package(app_info, &pkg);
+      if (ret == APP_MANAGER_ERROR_NONE && pkg != NULL) {
+        pkg_id_ = pkg;
+        free(pkg);
+      }
+      app_info_destroy(app_info);
+    }
+  }
+  return pkg_id_;
+}
+
+ApplicationData::AppType ApplicationData::GetAppType() {
+  if (category_info_list_) {
+    auto category_list = category_info_list_->categories;
+    auto it = category_list.begin();
+    auto end = category_list.end();
+    for (; it != end; ++it) {
+      if (TIZEN_FEATURE_web_ime_support && *it == kImeCategory) {
+        return IME;
+      }
+      if (TIZEN_FEATURE_watch_face_support &&
+          (*it == kIdleClockCategory || *it == kWearableClockCategory)) {
+        return WATCH;
+      }
+    }
+  }
+  return UI;
+}
+
+bool ApplicationData::LoadManifestData() {
+  if (loaded_) {
+    return true;
+  }
+
+  SCOPE_PROFILE();
+
+  std::string config_xml_path(application_path_ + kConfigXml);
+  if (!utils::Exists(config_xml_path)) {
+    LOGGER(ERROR) << "Failed to load manifest data : No such file '"
+                  << config_xml_path << "'.";
+    return false;
+  }
+
+  std::unique_ptr<wgt::parse::WidgetConfigParser> widget_config_parser;
+  widget_config_parser.reset(new wgt::parse::WidgetConfigParser());
+  if (!widget_config_parser->ParseManifest(config_xml_path)) {
+    LOGGER(ERROR) << "Failed to load widget config parser data: "
+                  << widget_config_parser->GetErrorMessage();
+    return false;
+  }
+
+  app_control_info_list_ =
+      std::static_pointer_cast<const wgt::parse::AppControlInfoList>(
+          widget_config_parser->GetManifestData(
+              wgt::parse::AppControlInfo::Key()));
+
+  category_info_list_ =
+      std::static_pointer_cast<const wgt::parse::CategoryInfoList>(
+          widget_config_parser->GetManifestData(
+              wgt::parse::CategoryInfoList::Key()));
+
+  meta_data_info_ = std::static_pointer_cast<const wgt::parse::MetaDataInfo>(
+      widget_config_parser->GetManifestData(wgt::parse::MetaDataInfo::Key()));
+
+  allowed_navigation_info_ =
+      std::static_pointer_cast<const wgt::parse::AllowedNavigationInfo>(
+          widget_config_parser->GetManifestData(
+              wgt::parse::AllowedNavigationInfo::Key()));
+
+  permissions_info_ =
+      std::static_pointer_cast<const wgt::parse::PermissionsInfo>(
+          widget_config_parser->GetManifestData(
+              wgt::parse::PermissionsInfo::Key()));
+
+  setting_info_ = std::static_pointer_cast<const wgt::parse::SettingInfo>(
+      widget_config_parser->GetManifestData(wgt::parse::SettingInfo::Key()));
+
+  splash_screen_info_ =
+      std::static_pointer_cast<const wgt::parse::LaunchScreenInfo>(
+          widget_config_parser->GetManifestData(
+              wgt::parse::LaunchScreenInfo::Key()));
+
+  tizen_application_info_ =
+      std::static_pointer_cast<const wgt::parse::TizenApplicationInfo>(
+          widget_config_parser->GetManifestData(
+              wgt::parse::TizenApplicationInfo::Key()));
+
+  widget_info_ = std::static_pointer_cast<const wgt::parse::WidgetInfo>(
+      widget_config_parser->GetManifestData(wgt::parse::WidgetInfo::Key()));
+
+  content_info_ = std::static_pointer_cast<const wgt::parse::ContentInfo>(
+      widget_config_parser->GetManifestData(wgt::parse::ContentInfo::Key()));
+
+  warp_info_ = std::static_pointer_cast<const wgt::parse::WarpInfo>(
+      widget_config_parser->GetManifestData(wgt::parse::WarpInfo::Key()));
+
+  csp_info_ = std::static_pointer_cast<const wgt::parse::CSPInfo>(
+      widget_config_parser->GetManifestData(wgt::parse::CSPInfo::Key()));
+
+  csp_report_info_ = std::static_pointer_cast<const wgt::parse::CSPInfo>(
+      widget_config_parser->GetManifestData(
+          wgt::parse::CSPInfo::Report_only_key()));
+
+  // Set default empty object
+  if (widget_info_.get() == NULL) {
+    widget_info_.reset(new wgt::parse::WidgetInfo);
+  }
+  if (setting_info_.get() == NULL) {
+    setting_info_.reset(new wgt::parse::SettingInfo);
+  }
+
+  app_type_ = GetAppType();
+  loaded_ = true;
+
+  return true;
+}
+
+// static
+ApplicationDataManager* ApplicationDataManager::GetInstance() {
+  static ApplicationDataManager self;
+  return &self;
+}
+
+ApplicationDataManager::ApplicationDataManager() {}
+
+ApplicationDataManager::~ApplicationDataManager() {}
+
+ApplicationData* ApplicationDataManager::GetApplicationData(
+    const std::string& appid) {
+  auto it = cache_.find(appid);
+  if (it == cache_.end()) {
+    cache_[appid].reset(new ApplicationData(appid));
+  }
+  return cache_[appid].get();
+}
+
+}  // namespace common
diff --git a/tizen/common/application_data.h b/tizen/common/application_data.h
new file mode 100644 (file)
index 0000000..8f43cae
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_APPLICATION_DATA_H_
+#define XWALK_COMMON_APPLICATION_DATA_H_
+
+#include <wgt_manifest_handlers/application_icons_handler.h>
+#include <wgt_manifest_handlers/appwidget_handler.h>
+#include <wgt_manifest_handlers/app_control_handler.h>
+#include <wgt_manifest_handlers/category_handler.h>
+#include <wgt_manifest_handlers/content_handler.h>
+#include <wgt_manifest_handlers/csp_handler.h>
+#include <wgt_manifest_handlers/ime_handler.h>
+#include <wgt_manifest_handlers/launch_screen_handler.h>
+#include <wgt_manifest_handlers/metadata_handler.h>
+#include <wgt_manifest_handlers/navigation_handler.h>
+#include <wgt_manifest_handlers/permissions_handler.h>
+#include <wgt_manifest_handlers/service_handler.h>
+#include <wgt_manifest_handlers/setting_handler.h>
+#include <wgt_manifest_handlers/tizen_application_handler.h>
+#include <wgt_manifest_handlers/warp_handler.h>
+#include <wgt_manifest_handlers/widget_handler.h>
+
+#include <memory>
+#include <string>
+
+namespace common {
+
+class ApplicationData {
+ public:
+  enum AppType { UI = 0, IME, WATCH };
+
+  explicit ApplicationData(const std::string& appid);
+  ~ApplicationData();
+
+  bool LoadManifestData();
+
+  std::shared_ptr<const wgt::parse::AppControlInfoList> app_control_info_list()
+      const;
+  std::shared_ptr<const wgt::parse::CategoryInfoList> category_info_list()
+      const;
+  std::shared_ptr<const wgt::parse::MetaDataInfo> meta_data_info() const;
+  std::shared_ptr<const wgt::parse::AllowedNavigationInfo>
+  allowed_navigation_info() const;
+  std::shared_ptr<const wgt::parse::PermissionsInfo> permissions_info() const;
+  std::shared_ptr<const wgt::parse::SettingInfo> setting_info() const;
+  std::shared_ptr<const wgt::parse::LaunchScreenInfo> splash_screen_info()
+      const;
+  std::shared_ptr<const wgt::parse::TizenApplicationInfo>
+  tizen_application_info() const;
+  std::shared_ptr<const wgt::parse::WidgetInfo> widget_info() const;
+  std::shared_ptr<const wgt::parse::ContentInfo> content_info() const;
+  std::shared_ptr<const wgt::parse::WarpInfo> warp_info() const;
+  std::shared_ptr<const wgt::parse::CSPInfo> csp_info() const;
+  std::shared_ptr<const wgt::parse::CSPInfo> csp_report_info() const;
+
+  const std::string application_path() const { return application_path_; }
+  const std::string pkg_id() const;
+  const std::string app_id() const { return app_id_; }
+  ApplicationData::AppType app_type() { return app_type_; }
+
+ private:
+  std::shared_ptr<const wgt::parse::AppControlInfoList> app_control_info_list_;
+  std::shared_ptr<const wgt::parse::CategoryInfoList> category_info_list_;
+  std::shared_ptr<const wgt::parse::MetaDataInfo> meta_data_info_;
+  std::shared_ptr<const wgt::parse::AllowedNavigationInfo>
+      allowed_navigation_info_;
+  std::shared_ptr<const wgt::parse::PermissionsInfo> permissions_info_;
+  std::shared_ptr<const wgt::parse::SettingInfo> setting_info_;
+  std::shared_ptr<const wgt::parse::LaunchScreenInfo> splash_screen_info_;
+  std::shared_ptr<const wgt::parse::TizenApplicationInfo>
+      tizen_application_info_;
+  std::shared_ptr<const wgt::parse::WidgetInfo> widget_info_;
+  std::shared_ptr<const wgt::parse::ContentInfo> content_info_;
+  std::shared_ptr<const wgt::parse::WarpInfo> warp_info_;
+  std::shared_ptr<const wgt::parse::CSPInfo> csp_info_;
+  std::shared_ptr<const wgt::parse::CSPInfo> csp_report_info_;
+  ApplicationData::AppType GetAppType();
+
+  std::string application_path_;
+  mutable std::string pkg_id_;
+  std::string app_id_;
+  ApplicationData::AppType app_type_;
+  bool loaded_;
+};
+
+class ApplicationDataManager {
+ public:
+  static ApplicationDataManager* GetInstance();
+
+  ApplicationData* GetApplicationData(const std::string& appid);
+
+ private:
+  ApplicationDataManager();
+  virtual ~ApplicationDataManager();
+
+  std::map<std::string, std::unique_ptr<ApplicationData>> cache_;
+};
+
+}  // namespace common
+
+#endif  // XWALK_COMMON_APPLICATION_DATA_H_
diff --git a/tizen/common/arraysize.h b/tizen/common/arraysize.h
new file mode 100644 (file)
index 0000000..2134b1d
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_ARRAYSIZE_H_
+#define XWALK_COMMON_ARRAYSIZE_H_
+
+// The ARRAYSIZE(arr) macro returns the # of elements in an array arr.
+// The expression is a compile-time constant, and therefore can be
+// used in defining new arrays, for example.  If you use arraysize on
+// a pointer by mistake, you will get a compile-time error.
+//
+// One caveat is that ARRAYSIZE() doesn't accept any array of an
+// anonymous type or a type defined inside a function.  In these rare
+// cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below.  This is
+// due to a limitation in C++'s template system.  The limitation might
+// eventually be removed, but it hasn't happened yet.
+
+// This template function declaration is used in defining arraysize.
+// Note that the function doesn't need an implementation, as we only
+// use its type.
+template <typename T, size_t N>
+char (&ArraySizeHelper(T (&array)[N]))[N];
+
+#define ARRAYSIZE(array) (sizeof(ArraySizeHelper(array)))
+
+#endif  // XWALK_COMMON_ARRAYSIZE_H_
diff --git a/tizen/common/command_line.cc b/tizen/common/command_line.cc
new file mode 100644 (file)
index 0000000..6ee518a
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "common/command_line.h"
+
+#include <cstring>
+
+#include "common/file_utils.h"
+
+namespace common {
+
+namespace {
+
+const char* kOptionPrefix = "--";
+const char* kOptionValueSeparator = "=";
+
+static bool IsValidOptionString(const char* argument) {
+  if (NULL != argument &&
+      strncmp(argument, kOptionPrefix, strlen(kOptionPrefix)) == 0) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+}  // namespace
+
+CommandLine* CommandLine::current_process_commandline_ = NULL;
+
+CommandLine::CommandLine(int argc, char* argv[]) : argc_(argc), argv_(argv) {
+  // Append option or push each arg(not option) into arguments_
+  for (int i = 1; i < argc; ++i) {
+    if (IsValidOptionString(argv[i])) {
+      AppendOption(argv[i]);
+    } else {
+      arguments_.push_back(argv[i]);
+    }
+  }
+
+  // Parse program name and appid from argv_ or arguments_
+  program_ = std::string(argv[0]);
+}
+
+CommandLine::~CommandLine() {}
+
+void CommandLine::AppendOption(const char* value) {
+  std::string option_string(value);
+  std::string option_name;
+  std::string option_value;
+
+  int value_separator_pos =
+      option_string.find(kOptionValueSeparator, strlen(kOptionPrefix));
+  if (value_separator_pos >= 0) {
+    int substr_len = value_separator_pos - strlen(kOptionPrefix);
+    option_name = option_string.substr(strlen(kOptionPrefix), substr_len);
+    option_value = option_string.substr(value_separator_pos + 1);
+  } else {
+    option_name =
+        option_string.substr(strlen(kOptionPrefix), value_separator_pos);
+  }
+
+  options_[option_name] = option_value;
+}
+
+bool CommandLine::HasOptionName(const std::string& option_name) {
+  return (options_.find(option_name) != options_.end());
+}
+
+std::string CommandLine::GetOptionValue(const std::string& option_name) {
+  if (HasOptionName(option_name)) {
+    return options_[option_name];
+  } else {
+    return std::string();
+  }
+}
+
+std::string CommandLine::GetCommandString() {
+  std::string result;
+  result.append(program_);
+  result.append(" ");
+  for (auto& it : options_) {
+    result.append(kOptionPrefix);
+    result.append(it.first);
+    if (!it.second.empty()) {
+      result.append(kOptionValueSeparator);
+      result.append(it.second);
+    }
+    result.append(" ");
+  }
+  for (auto& it : arguments_) {
+    result.append(it);
+    result.append(" ");
+  }
+  return result;
+}
+
+std::string CommandLine::GetAppIdFromCommandLine(const std::string& program) {
+  if (argc_ > 0) {
+    std::string tmp = utils::BaseName(program_);
+    if (tmp == program) {
+      if (arguments_.size() > 0) {
+        // Suppose that appid is at the first of arguments_
+        return arguments_[0];
+      }
+    } else {
+      return tmp;
+    }
+  }
+  return std::string();
+}
+
+// static
+void CommandLine::Reset() {
+  if (!!current_process_commandline_) {
+    delete current_process_commandline_;
+    current_process_commandline_ = NULL;
+  }
+}
+
+// static
+void CommandLine::Init(int argc, char* argv[]) {
+  if (!current_process_commandline_) {
+    current_process_commandline_ = new CommandLine(argc, argv);
+  }
+}
+
+// static
+CommandLine* CommandLine::ForCurrentProcess() {
+  return current_process_commandline_;
+}
+
+}  // namespace common
diff --git a/tizen/common/command_line.h b/tizen/common/command_line.h
new file mode 100644 (file)
index 0000000..6854808
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_COMMAND_LINE_H_
+#define XWALK_COMMON_COMMAND_LINE_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace common {
+
+class CommandLine {
+ public:
+  // CommandLine only uses long options
+  typedef std::map<std::string, std::string> OptionMap;
+  // Arguments which except for option strings
+  typedef std::vector<std::string> Arguments;
+
+  static void Init(int argc, char* argv[]);
+  static CommandLine* ForCurrentProcess();
+  static void Reset();
+
+  // Test if options_ has 'option_name'
+  bool HasOptionName(const std::string& option_name);
+  // Get the option's value
+  std::string GetOptionValue(const std::string& option_name);
+  // Get command string include options and arguments
+  std::string GetCommandString();
+
+  std::string GetAppIdFromCommandLine(const std::string& program);
+
+  std::string program() const { return program_; }
+  const OptionMap& options() const { return options_; }
+  const Arguments& arguments() const { return arguments_; }
+  char** argv() const { return argv_; }
+  int argc() const { return argc_; }
+
+ private:
+  CommandLine(int argc, char* argv[]);
+  virtual ~CommandLine();
+
+  void AppendOption(const char* value);
+
+  // The singleton CommandLine instance of current process
+  static CommandLine* current_process_commandline_;
+
+  std::string program_;
+  OptionMap options_;
+  Arguments arguments_;
+  int argc_;
+  char** argv_;
+};
+
+}  // namespace common
+
+#endif  // XWALK_COMMON_COMMAND_LINE_H_
diff --git a/tizen/common/common.gyp b/tizen/common/common.gyp
new file mode 100644 (file)
index 0000000..9ea448b
--- /dev/null
@@ -0,0 +1,79 @@
+{
+  'includes':[
+    '../build/common.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'xwalk_tizen_common',
+      'type': 'shared_library',
+      'sources': [
+        'command_line.h',
+        'command_line.cc',
+        'file_utils.h',
+        'file_utils.cc',
+        'string_utils.h',
+        'string_utils.cc',
+        'logger.h',
+        'picojson.h',
+        'profiler.h',
+        'profiler.cc',
+        'url.h',
+        'url.cc',
+        'app_control.h',
+        'app_control.cc',
+        'app_db.h',
+        'app_db.cc',
+        'app_db_sqlite.h',
+        'application_data.h',
+        'application_data.cc',
+        'locale_manager.h',
+        'locale_manager.cc',
+        'resource_manager.h',
+        'resource_manager.cc',
+        'platform_info.h',
+        'platform_info.cc',
+      ],
+      'cflags': [
+        '-fvisibility=default',
+      ],
+      'variables': {
+        'packages': [
+          'appsvc',
+          'aul',
+          'capi-appfw-application',
+          'capi-appfw-app-manager',
+          'capi-appfw-package-manager',
+          'capi-system-system-settings',
+          'capi-system-info',
+          'cynara-client',
+          'dlog',
+          'uuid',
+          'libwebappenc',
+          'manifest-parser',
+          'wgt-manifest-handlers',
+          'pkgmgr-info',
+          'glib-2.0',
+          'ttrace',
+        ],
+      },
+#      'conditions': [
+#        ['tizen_feature_web_ime_support == 1', {
+#          'defines': ['IME_FEATURE_SUPPORT'],
+#        }],
+#        ['tizen_feature_watch_face_support == 1', {
+#          'defines': ['WATCH_FACE_FEATURE_SUPPORT'],
+#        }],
+#      ],
+      'direct_dependent_settings': {
+#        'libraries': [
+#          '-lxwalk_tizen_common',
+#        ],
+        'variables': {
+          'packages': [
+            'dlog',
+          ],
+        },
+      },
+    },
+  ],
+}
diff --git a/tizen/common/file_utils.cc b/tizen/common/file_utils.cc
new file mode 100644 (file)
index 0000000..2b00d3c
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "common/file_utils.h"
+
+#include <sys/types.h>
+#include <libgen.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <sstream>
+#include <string>
+
+namespace common {
+namespace utils {
+
+bool Exists(const std::string& path) {
+  return (access(path.c_str(), F_OK) != -1);
+}
+
+std::string BaseName(const std::string& path) {
+  char* p = basename(const_cast<char*>(path.c_str()));
+  return std::string(p);
+}
+
+std::string DirName(const std::string& path) {
+  char* p = dirname(const_cast<char*>(path.c_str()));
+  return std::string(p);
+}
+
+std::string SchemeName(const std::string& uri) {
+  size_t pos = uri.find(":");
+  if (pos != std::string::npos && pos < uri.length()) {
+    return std::string(uri.substr(0, pos));
+  } else {
+    return uri;
+  }
+}
+
+std::string ExtName(const std::string& path) {
+  size_t last_dot = path.find_last_of(".");
+  if (last_dot != 0 && last_dot != std::string::npos) {
+    std::string ext = path.substr(last_dot);
+    size_t end_of_ext = ext.find_first_of("?#");
+    if (end_of_ext != std::string::npos)
+      ext = ext.substr(0, end_of_ext);
+    std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
+    return ext;
+  } else {
+    return std::string();
+  }
+}
+
+std::string GetUserRuntimeDir() {
+  uid_t uid = getuid();
+  std::stringstream ss;
+  ss << "/run/user/" << uid;
+  std::string path = ss.str();
+  if (!Exists(path)) {
+    path = "/tmp";
+  }
+  return path;
+}
+
+}  // namespace utils
+}  // namespace common
diff --git a/tizen/common/file_utils.h b/tizen/common/file_utils.h
new file mode 100644 (file)
index 0000000..b3c25d5
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_FILE_UTILS_H_
+#define XWALK_COMMON_FILE_UTILS_H_
+
+#include <string>
+
+namespace common {
+namespace utils {
+
+bool Exists(const std::string& path);
+
+std::string BaseName(const std::string& path);
+
+std::string DirName(const std::string& path);
+
+std::string SchemeName(const std::string& uri);
+
+std::string ExtName(const std::string& path);
+
+std::string GetUserRuntimeDir();
+
+}  // namespace utils
+}  // namespace common
+
+#endif  // XWALK_COMMON_FILE_UTILS_H_
diff --git a/tizen/common/locale_manager.cc b/tizen/common/locale_manager.cc
new file mode 100644 (file)
index 0000000..3efbb77
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "common/locale_manager.h"
+
+#include <system_settings.h>
+
+#include <algorithm>
+#include <memory>
+
+#include "common/file_utils.h"
+#include "common/logger.h"
+
+namespace common {
+
+namespace {
+
+std::string localeToBCP47LangTag(const std::string locale) {
+  // Cut off codepage information from given string (if any exists)
+  // i.e. change en_US.UTF-8 into en_US */
+  std::string lang = locale.substr(0, locale.find_first_of("."));
+
+  // Replace all '_' with '-'
+  std::replace(lang.begin(), lang.end(), '_', '-');
+  return lang;
+}
+
+}  // namespace
+
+LocaleManager::LocaleManager() {
+  UpdateSystemLocale();
+}
+
+LocaleManager::~LocaleManager() {
+  system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE);
+}
+
+void LocaleManager::EnableAutoUpdate(bool enable) {
+  if (enable) {
+    auto callback = [](system_settings_key_e, void* user_data) {
+      LocaleManager* locale = static_cast<LocaleManager*>(user_data);
+      locale->UpdateSystemLocale();
+    };
+    system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE,
+                                   callback, this);
+  } else {
+    system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE);
+  }
+}
+
+void LocaleManager::SetDefaultLocale(const std::string& locale) {
+  if (!default_locale_.empty() && system_locales_.size() > 0 &&
+      system_locales_.back() == default_locale_) {
+    system_locales_.pop_back();
+  }
+  default_locale_ = locale;
+  if (!default_locale_.empty()) {
+    system_locales_.push_back(locale);
+  }
+}
+
+void LocaleManager::UpdateSystemLocale() {
+  char* str = NULL;
+  if (SYSTEM_SETTINGS_ERROR_NONE !=
+          system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE,
+                                           &str) ||
+      str == NULL) {
+    return;
+  }
+  std::string lang = localeToBCP47LangTag(str);
+  free(str);
+
+  if (lang.length() == 0) {
+    LOGGER(ERROR) << "Language tag was invalid";
+    return;
+  }
+
+  system_locales_.clear();
+  while (true) {
+    LOGGER(DEBUG) << "Processing language description: " << lang;
+    system_locales_.push_back(lang);
+
+    // compatibility with lower language Tag by SDK
+    std::string lower = lang;
+    std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
+    if (lower != lang) {
+      system_locales_.push_back(lower);
+    }
+    size_t position = lang.find_last_of("-");
+    if (position == std::string::npos) {
+      break;
+    }
+    lang = lang.substr(0, position);
+  }
+  if (!default_locale_.empty()) {
+    system_locales_.push_back(default_locale_);
+  }
+}
+
+std::string LocaleManager::GetLocalizedString(const StringMap& strmap) {
+  if (strmap.empty()) {
+    return std::string();
+  }
+
+  // find string with system locales
+  for (auto& locale : system_locales_) {
+    auto it = strmap.find(locale);
+    if (it != strmap.end()) {
+      return it->second;
+    }
+  }
+
+  // find string with empty locale
+  auto it = strmap.find("");
+  if (it != strmap.end()) {
+    return it->second;
+  }
+
+  // If localized string is not found, return first string.
+  return strmap.begin()->second;
+}
+
+}  // namespace common
diff --git a/tizen/common/locale_manager.h b/tizen/common/locale_manager.h
new file mode 100644 (file)
index 0000000..e890858
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_LOCALE_MANAGER_H_
+#define XWALK_COMMON_LOCALE_MANAGER_H_
+
+#include <list>
+#include <map>
+#include <string>
+
+namespace common {
+
+class LocaleManager {
+ public:
+  typedef std::map<std::string, std::string> StringMap;
+
+  LocaleManager();
+  virtual ~LocaleManager();
+  void SetDefaultLocale(const std::string& locale);
+  void EnableAutoUpdate(bool enable);
+  void UpdateSystemLocale();
+  const std::list<std::string>& system_locales() const {
+    return system_locales_;
+  }
+
+  std::string GetLocalizedString(const StringMap& strmap);
+
+ private:
+  std::string default_locale_;
+  std::list<std::string> system_locales_;
+};
+
+}  // namespace common
+
+#endif  // XWALK_COMMON_LOCALE_MANAGER_H_
diff --git a/tizen/common/logger.h b/tizen/common/logger.h
new file mode 100644 (file)
index 0000000..bce7013
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_LOGGER_H_
+#define XWALK_COMMON_LOGGER_H_
+
+#include <dlog.h>
+#include <sstream>
+
+#undef LOGGER_TAG
+#define LOGGER_TAG "ELECTRON"
+
+#define _LOGGER_LOG(prio, fmt, args...) \
+  LOG_(LOG_ID_MAIN, prio, LOGGER_TAG, fmt, ##args)
+
+#define _LOGGER_SLOG(prio, fmt, args...) \
+  SECURE_LOG_(LOG_ID_MAIN, prio, LOGGER_TAG, fmt, ##args)
+
+#define LoggerD(fmt, args...) _LOGGER_LOG(DLOG_DEBUG, fmt, ##args)
+#define LoggerI(fmt, args...) _LOGGER_LOG(DLOG_INFO, fmt, ##args)
+#define LoggerW(fmt, args...) _LOGGER_LOG(DLOG_WARN, fmt, ##args)
+#define LoggerE(fmt, args...) _LOGGER_LOG(DLOG_ERROR, fmt, ##args)
+
+#define SLoggerD(fmt, args...) _LOGGER_SLOG(DLOG_DEBUG, fmt, ##args)
+#define SLoggerI(fmt, args...) _LOGGER_SLOG(DLOG_INFO, fmt, ##args)
+#define SLoggerW(fmt, args...) _LOGGER_SLOG(DLOG_WARN, fmt, ##args)
+#define SLoggerE(fmt, args...) _LOGGER_SLOG(DLOG_ERROR, fmt, ##args)
+
+namespace common {
+namespace utils {
+
+class LogMessageVodify {
+ public:
+  LogMessageVodify() {}
+  void operator&(const std::ostream&)const {}
+};
+
+class LogMessage {
+ public:
+  LogMessage(int severity,
+             const char* tag,
+             const char* file,
+             const char* func,
+             const int line)
+      : severity_(severity), tag_(tag), file_(file), func_(func), line_(line) {}
+  LogMessage(int severity, const char* tag)
+      : severity_(severity), tag_(tag), file_(NULL), func_(NULL), line_(0) {}
+  ~LogMessage() {
+    if (file_) {
+      __dlog_print(LOG_ID_MAIN, severity_, tag_, "%s: %s(%d) > %s", file_,
+                   func_, line_, stream_.str().c_str());
+    } else {
+      __dlog_print(LOG_ID_MAIN, severity_, tag_, "%s", stream_.str().c_str());
+    }
+  }
+  std::ostream& stream() { return stream_; }
+
+ private:
+  const int severity_;
+  const char* tag_;
+  const char* file_;
+  const char* func_;
+  const int line_;
+  std::ostringstream stream_;
+};
+
+}  // namespace utils
+}  // namespace common
+
+#ifndef __MODULE__
+#define __MODULE__ \
+  (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
+#endif
+
+#define LOGGER(severity)                                                 \
+  common::utils::LogMessageVodify() &                                    \
+      common::utils::LogMessage(DLOG_##severity, LOGGER_TAG, __MODULE__, \
+                                __FUNCTION__, __LINE__)                  \
+          .stream()
+
+#define LOGGER_RAW(level, tag)        \
+  common::utils::LogMessageVodify() & \
+      common::utils::LogMessage(level, tag).stream()
+
+#endif  // XWALK_COMMON_LOGGER_H_
diff --git a/tizen/common/picojson.h b/tizen/common/picojson.h
new file mode 100644 (file)
index 0000000..57dc3a5
--- /dev/null
@@ -0,0 +1,1110 @@
+/*
+ * Copyright 2009-2010 Cybozu Labs, Inc.
+ * Copyright 2011 Kazuho Oku
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CYBOZU LABS, INC. ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL CYBOZU LABS, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of Cybozu Labs, Inc.
+ *
+ */
+#ifndef picojson_h
+#define picojson_h
+
+#include <algorithm>
+#include <cassert>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <iterator>
+#include <map>
+#include <string>
+#include <vector>
+
+#ifdef _MSC_VER
+#define SNPRINTF _snprintf_s
+#pragma warning(push)
+#pragma warning(disable : 4244)  // conversion from int to char
+#else
+#define SNPRINTF snprintf
+#endif
+
+namespace picojson {
+
+enum {
+  null_type,
+  boolean_type,
+  number_type,
+  string_type,
+  array_type,
+  object_type
+};
+
+struct null {};
+
+class value {
+ public:
+  typedef std::vector<value> array;
+  typedef std::map<std::string, value> object;
+  union _storage {
+    bool boolean_;
+    double number_;
+    std::string* string_;
+    array* array_;
+    object* object_;
+  };
+
+ protected:
+  int type_;
+  _storage u_;
+
+ public:
+  value();
+  value(int type, bool);
+  explicit value(bool b);
+  explicit value(double n);
+  explicit value(const std::string& s);
+  explicit value(const array& a);
+  explicit value(const object& o);
+  explicit value(const char* s);
+  value(const char* s, size_t len);
+  ~value();
+  value(const value& x);
+  value& operator=(const value& x);
+  void swap(value& x);
+  template <typename T>
+  bool is() const;
+  template <typename T>
+  const T& get() const;
+  template <typename T>
+  T& get();
+  bool evaluate_as_boolean() const;
+  const value& get(size_t idx) const;
+  const value& get(const std::string& key) const;
+  bool contains(size_t idx) const;
+  bool contains(const std::string& key) const;
+  std::string to_str() const;
+  template <typename Iter>
+  void serialize(Iter os) const;
+  std::string serialize() const;
+
+ private:
+  template <typename T>
+  value(const T*);  // intentionally defined to block implicit conversion of
+                    // pointer to bool
+};
+
+typedef value::array array;
+typedef value::object object;
+
+inline value::value() : type_(null_type) {}
+
+inline value::value(int type, bool) : type_(type) {
+  switch (type) {
+#define INIT(p, v) \
+  case p##type:    \
+    u_.p = v;      \
+    break
+    INIT(boolean_, false);
+    INIT(number_, 0.0);
+    INIT(string_, new std::string());
+    INIT(array_, new array());
+    INIT(object_, new object());
+#undef INIT
+    default:
+      break;
+  }
+}
+
+inline value::value(bool b) : type_(boolean_type) {
+  u_.boolean_ = b;
+}
+
+inline value::value(double n) : type_(number_type) {
+  u_.number_ = n;
+}
+
+inline value::value(const std::string& s) : type_(string_type) {
+  u_.string_ = new std::string(s);
+}
+
+inline value::value(const array& a) : type_(array_type) {
+  u_.array_ = new array(a);
+}
+
+inline value::value(const object& o) : type_(object_type) {
+  u_.object_ = new object(o);
+}
+
+inline value::value(const char* s) : type_(string_type) {
+  u_.string_ = new std::string(s);
+}
+
+inline value::value(const char* s, size_t len) : type_(string_type) {
+  u_.string_ = new std::string(s, len);
+}
+
+inline value::~value() {
+  switch (type_) {
+#define DEINIT(p) \
+  case p##type:   \
+    delete u_.p;  \
+    break
+    DEINIT(string_);
+    DEINIT(array_);
+    DEINIT(object_);
+#undef DEINIT
+    default:
+      break;
+  }
+}
+
+inline value::value(const value& x) : type_(x.type_) {
+  switch (type_) {
+#define INIT(p, v) \
+  case p##type:    \
+    u_.p = v;      \
+    break
+    INIT(string_, new std::string(*x.u_.string_));
+    INIT(array_, new array(*x.u_.array_));
+    INIT(object_, new object(*x.u_.object_));
+#undef INIT
+    default:
+      u_ = x.u_;
+      break;
+  }
+}
+
+inline value& value::operator=(const value& x) {
+  if (this != &x) {
+    this->~value();
+    new (this) value(x);
+  }
+  return *this;
+}
+
+inline void value::swap(value& x) {
+  std::swap(type_, x.type_);
+  std::swap(u_, x.u_);
+}
+
+#define IS(ctype, jtype)                 \
+  template <>                            \
+  inline bool value::is<ctype>() const { \
+    return type_ == jtype##_type;        \
+  }
+IS(null, null)
+IS(bool, boolean)
+IS(int, number)
+IS(double, number)
+IS(std::string, string)
+IS(array, array)
+IS(object, object)
+#undef IS
+
+#define GET(ctype, var)                                            \
+  template <>                                                      \
+  inline const ctype& value::get<ctype>() const {                  \
+    assert("type mismatch! call vis<type>() before get<type>()" && \
+           is<ctype>());                                           \
+    return var;                                                    \
+  }                                                                \
+  template <>                                                      \
+  inline ctype& value::get<ctype>() {                              \
+    assert("type mismatch! call is<type>() before get<type>()" &&  \
+           is<ctype>());                                           \
+    return var;                                                    \
+  }
+GET(bool, u_.boolean_)
+GET(double, u_.number_)
+GET(std::string, *u_.string_)
+GET(array, *u_.array_)
+GET(object, *u_.object_)
+#undef GET
+
+inline bool value::evaluate_as_boolean() const {
+  switch (type_) {
+    case null_type:
+      return false;
+    case boolean_type:
+      return u_.boolean_;
+    case number_type:
+      return u_.number_ != 0;
+    case string_type:
+      return !u_.string_->empty();
+    default:
+      return true;
+  }
+}
+
+inline const value& value::get(size_t idx) const {
+  static value s_null;
+  assert(is<array>());
+  return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
+}
+
+inline const value& value::get(const std::string& key) const {
+  static value s_null;
+  assert(is<object>());
+  object::const_iterator i = u_.object_->find(key);
+  return i != u_.object_->end() ? i->second : s_null;
+}
+
+inline bool value::contains(size_t idx) const {
+  assert(is<array>());
+  return idx < u_.array_->size();
+}
+
+inline bool value::contains(const std::string& key) const {
+  assert(is<object>());
+  object::const_iterator i = u_.object_->find(key);
+  return i != u_.object_->end();
+}
+
+inline std::string value::to_str() const {
+  switch (type_) {
+    case null_type:
+      return "null";
+    case boolean_type:
+      return u_.boolean_ ? "true" : "false";
+    case number_type: {
+      char buf[256];
+      double tmp;
+      SNPRINTF(buf, sizeof(buf),
+               fabs(u_.number_) < (1ULL << 53) && modf(u_.number_, &tmp) == 0
+                   ? "%.f"
+                   : "%.17g",
+               u_.number_);
+      return buf;
+    }
+    case string_type:
+      return *u_.string_;
+    case array_type:
+      return "array";
+    case object_type:
+      return "object";
+    default:
+      assert(0);
+#ifdef _MSC_VER
+      __assume(0);
+#endif
+  }
+  return std::string();
+}
+
+template <typename Iter>
+void copy(const std::string& s, Iter oi) {
+  std::copy(s.begin(), s.end(), oi);
+}
+
+template <typename Iter>
+void serialize_str(const std::string& s, Iter oi) {
+  *oi++ = '"';
+  for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) {
+    switch (*i) {
+#define MAP(val, sym) \
+  case val:           \
+    copy(sym, oi);    \
+    break
+      MAP('"', "\\\"");
+      MAP('\\', "\\\\");
+      MAP('/', "\\/");
+      MAP('\b', "\\b");
+      MAP('\f', "\\f");
+      MAP('\n', "\\n");
+      MAP('\r', "\\r");
+      MAP('\t', "\\t");
+#undef MAP
+      default:
+        if ((unsigned char)*i < 0x20 || *i == 0x7f) {
+          char buf[7];
+          SNPRINTF(buf, sizeof(buf), "\\u%04x", *i & 0xff);
+          copy(buf, buf + 6, oi);
+        } else {
+          *oi++ = *i;
+        }
+        break;
+    }
+  }
+  *oi++ = '"';
+}
+
+template <typename Iter>
+void value::serialize(Iter oi) const {
+  switch (type_) {
+    case string_type:
+      serialize_str(*u_.string_, oi);
+      break;
+    case array_type: {
+      *oi++ = '[';
+      for (array::const_iterator i = u_.array_->begin(); i != u_.array_->end();
+           ++i) {
+        if (i != u_.array_->begin()) {
+          *oi++ = ',';
+        }
+        i->serialize(oi);
+      }
+      *oi++ = ']';
+      break;
+    }
+    case object_type: {
+      *oi++ = '{';
+      for (object::const_iterator i = u_.object_->begin();
+           i != u_.object_->end(); ++i) {
+        if (i != u_.object_->begin()) {
+          *oi++ = ',';
+        }
+        serialize_str(i->first, oi);
+        *oi++ = ':';
+        i->second.serialize(oi);
+      }
+      *oi++ = '}';
+      break;
+    }
+    default:
+      copy(to_str(), oi);
+      break;
+  }
+}
+
+inline std::string value::serialize() const {
+  std::string s;
+  serialize(std::back_inserter(s));
+  return s;
+}
+
+template <typename Iter>
+class input {
+ protected:
+  Iter cur_, end_;
+  int last_ch_;
+  bool ungot_;
+  int line_;
+
+ public:
+  input(const Iter& first, const Iter& last)
+      : cur_(first), end_(last), last_ch_(-1), ungot_(false), line_(1) {}
+  int getc() {
+    if (ungot_) {
+      ungot_ = false;
+      return last_ch_;
+    }
+    if (cur_ == end_) {
+      last_ch_ = -1;
+      return -1;
+    }
+    if (last_ch_ == '\n') {
+      line_++;
+    }
+    last_ch_ = *cur_++ & 0xff;
+    return last_ch_;
+  }
+  void ungetc() {
+    if (last_ch_ != -1) {
+      assert(!ungot_);
+      ungot_ = true;
+    }
+  }
+  Iter cur() const { return cur_; }
+  int line() const { return line_; }
+  void skip_ws() {
+    while (1) {
+      int ch = getc();
+      if (!(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) {
+        ungetc();
+        break;
+      }
+    }
+  }
+  bool expect(int expect) {
+    skip_ws();
+    if (getc() != expect) {
+      ungetc();
+      return false;
+    }
+    return true;
+  }
+  bool match(const std::string& pattern) {
+    for (std::string::const_iterator pi(pattern.begin()); pi != pattern.end();
+         ++pi) {
+      if (getc() != *pi) {
+        ungetc();
+        return false;
+      }
+    }
+    return true;
+  }
+};
+
+template <typename Iter>
+inline int _parse_quadhex(input<Iter>& in) {
+  int uni_ch = 0, hex;
+  for (int i = 0; i < 4; i++) {
+    if ((hex = in.getc()) == -1) {
+      return -1;
+    }
+    if ('0' <= hex && hex <= '9') {
+      hex -= '0';
+    } else if ('A' <= hex && hex <= 'F') {
+      hex -= 'A' - 0xa;
+    } else if ('a' <= hex && hex <= 'f') {
+      hex -= 'a' - 0xa;
+    } else {
+      in.ungetc();
+      return -1;
+    }
+    uni_ch = uni_ch * 16 + hex;
+  }
+  return uni_ch;
+}
+
+template <typename String, typename Iter>
+inline bool _parse_codepoint(String& out, input<Iter>& in) {
+  int uni_ch;
+  if ((uni_ch = _parse_quadhex(in)) == -1) {
+    return false;
+  }
+  if (0xd800 <= uni_ch && uni_ch <= 0xdfff) {
+    if (0xdc00 <= uni_ch) {
+      // a second 16-bit of a surrogate pair appeared
+      return false;
+    }
+    // first 16-bit of surrogate pair, get the next one
+    if (in.getc() != '\\' || in.getc() != 'u') {
+      in.ungetc();
+      return false;
+    }
+    int second = _parse_quadhex(in);
+    if (!(0xdc00 <= second && second <= 0xdfff)) {
+      return false;
+    }
+    uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff);
+    uni_ch += 0x10000;
+  }
+  if (uni_ch < 0x80) {
+    out.push_back(uni_ch);
+  } else {
+    if (uni_ch < 0x800) {
+      out.push_back(0xc0 | (uni_ch >> 6));
+    } else {
+      if (uni_ch < 0x10000) {
+        out.push_back(0xe0 | (uni_ch >> 12));
+      } else {
+        out.push_back(0xf0 | (uni_ch >> 18));
+        out.push_back(0x80 | ((uni_ch >> 12) & 0x3f));
+      }
+      out.push_back(0x80 | ((uni_ch >> 6) & 0x3f));
+    }
+    out.push_back(0x80 | (uni_ch & 0x3f));
+  }
+  return true;
+}
+
+template <typename String, typename Iter>
+inline bool _parse_string(String& out, input<Iter>& in) {
+  while (1) {
+    int ch = in.getc();
+    if (ch < ' ') {
+      in.ungetc();
+      return false;
+    } else if (ch == '"') {
+      return true;
+    } else if (ch == '\\') {
+      if ((ch = in.getc()) == -1) {
+        return false;
+      }
+      switch (ch) {
+#define MAP(sym, val)   \
+  case sym:             \
+    out.push_back(val); \
+    break
+        MAP('"', '\"');
+        MAP('\\', '\\');
+        MAP('/', '/');
+        MAP('b', '\b');
+        MAP('f', '\f');
+        MAP('n', '\n');
+        MAP('r', '\r');
+        MAP('t', '\t');
+#undef MAP
+        case 'u':
+          if (!_parse_codepoint(out, in)) {
+            return false;
+          }
+          break;
+        default:
+          return false;
+      }
+    } else {
+      out.push_back(ch);
+    }
+  }
+  return false;
+}
+
+template <typename Context, typename Iter>
+inline bool _parse_array(Context& ctx, input<Iter>& in) {
+  if (!ctx.parse_array_start()) {
+    return false;
+  }
+  if (in.expect(']')) {
+    return true;
+  }
+  size_t idx = 0;
+  do {
+    if (!ctx.parse_array_item(in, idx)) {
+      return false;
+    }
+    idx++;
+  } while (in.expect(','));
+  return in.expect(']');
+}
+
+template <typename Context, typename Iter>
+inline bool _parse_object(Context& ctx, input<Iter>& in) {
+  if (!ctx.parse_object_start()) {
+    return false;
+  }
+  if (in.expect('}')) {
+    return true;
+  }
+  do {
+    std::string key;
+    if (!in.expect('"') || !_parse_string(key, in) || !in.expect(':')) {
+      return false;
+    }
+    if (!ctx.parse_object_item(in, key)) {
+      return false;
+    }
+  } while (in.expect(','));
+  return in.expect('}');
+}
+
+template <typename Iter>
+inline bool _parse_number(double& out, input<Iter>& in) {
+  std::string num_str;
+  while (1) {
+    int ch = in.getc();
+    if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-' || ch == '.' ||
+        ch == 'e' || ch == 'E') {
+      num_str.push_back(ch);
+    } else {
+      in.ungetc();
+      break;
+    }
+  }
+  char* endp;
+  out = strtod(num_str.c_str(), &endp);
+  return endp == num_str.c_str() + num_str.size();
+}
+
+template <typename Context, typename Iter>
+inline bool _parse(Context& ctx, input<Iter>& in) {
+  in.skip_ws();
+  int ch = in.getc();
+  switch (ch) {
+#define IS(ch, text, op)        \
+  case ch:                      \
+    if (in.match(text) && op) { \
+      return true;              \
+    } else {                    \
+      return false;             \
+    }
+    IS('n', "ull", ctx.set_null());
+    IS('f', "alse", ctx.set_bool(false));
+    IS('t', "rue", ctx.set_bool(true));
+#undef IS
+    case '"':
+      return ctx.parse_string(in);
+    case '[':
+      return _parse_array(ctx, in);
+    case '{':
+      return _parse_object(ctx, in);
+    default:
+      if (('0' <= ch && ch <= '9') || ch == '-') {
+        in.ungetc();
+        double f;
+        if (_parse_number(f, in)) {
+          ctx.set_number(f);
+          return true;
+        } else {
+          return false;
+        }
+      }
+      break;
+  }
+  in.ungetc();
+  return false;
+}
+
+class deny_parse_context {
+ public:
+  bool set_null() { return false; }
+  bool set_bool(bool) { return false; }
+  bool set_number(double) { return false; }
+  template <typename Iter>
+  bool parse_string(input<Iter>&) {
+    return false;
+  }
+  bool parse_array_start() { return false; }
+  template <typename Iter>
+  bool parse_array_item(input<Iter>&, size_t) {
+    return false;
+  }
+  bool parse_object_start() { return false; }
+  template <typename Iter>
+  bool parse_object_item(input<Iter>&, const std::string&) {
+    return false;
+  }
+};
+
+class default_parse_context {
+ protected:
+  value* out_;
+
+ public:
+  default_parse_context(value* out) : out_(out) {}
+  bool set_null() {
+    *out_ = value();
+    return true;
+  }
+  bool set_bool(bool b) {
+    *out_ = value(b);
+    return true;
+  }
+  bool set_number(double f) {
+    *out_ = value(f);
+    return true;
+  }
+  template <typename Iter>
+  bool parse_string(input<Iter>& in) {
+    *out_ = value(string_type, false);
+    return _parse_string(out_->get<std::string>(), in);
+  }
+  bool parse_array_start() {
+    *out_ = value(array_type, false);
+    return true;
+  }
+  template <typename Iter>
+  bool parse_array_item(input<Iter>& in, size_t) {
+    array& a = out_->get<array>();
+    a.push_back(value());
+    default_parse_context ctx(&a.back());
+    return _parse(ctx, in);
+  }
+  bool parse_object_start() {
+    *out_ = value(object_type, false);
+    return true;
+  }
+  template <typename Iter>
+  bool parse_object_item(input<Iter>& in, const std::string& key) {
+    object& o = out_->get<object>();
+    default_parse_context ctx(&o[key]);
+    return _parse(ctx, in);
+  }
+
+ private:
+  default_parse_context(const default_parse_context&);
+  default_parse_context& operator=(const default_parse_context&);
+};
+
+class null_parse_context {
+ public:
+  struct dummy_str {
+    void push_back(int) {}
+  };
+
+ public:
+  null_parse_context() {}
+  bool set_null() { return true; }
+  bool set_bool(bool) { return true; }
+  bool set_number(double) { return true; }
+  template <typename Iter>
+  bool parse_string(input<Iter>& in) {
+    dummy_str s;
+    return _parse_string(s, in);
+  }
+  bool parse_array_start() { return true; }
+  template <typename Iter>
+  bool parse_array_item(input<Iter>& in, size_t) {
+    return _parse(*this, in);
+  }
+  bool parse_object_start() { return true; }
+  template <typename Iter>
+  bool parse_object_item(input<Iter>& in, const std::string&) {
+    return _parse(*this, in);
+  }
+
+ private:
+  null_parse_context(const null_parse_context&);
+  null_parse_context& operator=(const null_parse_context&);
+};
+
+// obsolete, use the version below
+template <typename Iter>
+inline std::string parse(value& out, Iter& pos, const Iter& last) {
+  std::string err;
+  pos = parse(out, pos, last, &err);
+  return err;
+}
+
+template <typename Context, typename Iter>
+inline Iter _parse(Context& ctx,
+                   const Iter& first,
+                   const Iter& last,
+                   std::string* err) {
+  input<Iter> in(first, last);
+  if (!_parse(ctx, in) && err != NULL) {
+    char buf[64];
+    SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line());
+    *err = buf;
+    while (1) {
+      int ch = in.getc();
+      if (ch == -1 || ch == '\n') {
+        break;
+      } else if (ch >= ' ') {
+        err->push_back(ch);
+      }
+    }
+  }
+  return in.cur();
+}
+
+template <typename Iter>
+inline Iter parse(value& out,
+                  const Iter& first,
+                  const Iter& last,
+                  std::string* err) {
+  default_parse_context ctx(&out);
+  return _parse(ctx, first, last, err);
+}
+
+inline std::string parse(value& out, std::istream& is) {
+  std::string err;
+  parse(out, std::istreambuf_iterator<char>(is.rdbuf()),
+        std::istreambuf_iterator<char>(), &err);
+  return err;
+}
+
+template <typename T>
+struct last_error_t {
+  static std::string s;
+};
+template <typename T>
+std::string last_error_t<T>::s;
+
+inline void set_last_error(const std::string& s) {
+  last_error_t<bool>::s = s;
+}
+
+inline const std::string& get_last_error() {
+  return last_error_t<bool>::s;
+}
+
+inline bool operator==(const value& x, const value& y) {
+  if (x.is<null>())
+    return y.is<null>();
+#define PICOJSON_CMP(type) \
+  if (x.is<type>())        \
+  return y.is<type>() && x.get<type>() == y.get<type>()
+  PICOJSON_CMP(bool);
+  PICOJSON_CMP(double);
+  PICOJSON_CMP(std::string);
+  PICOJSON_CMP(array);
+  PICOJSON_CMP(object);
+#undef PICOJSON_CMP
+  assert(0);
+#ifdef _MSC_VER
+  __assume(0);
+#endif
+  return false;
+}
+
+inline bool operator!=(const value& x, const value& y) {
+  return !(x == y);
+}
+}
+
+namespace std {
+template <>
+inline void swap(picojson::value& x, picojson::value& y) {
+  x.swap(y);
+}
+}
+
+inline std::istream& operator>>(std::istream& is, picojson::value& x) {
+  picojson::set_last_error(std::string());
+  std::string err = picojson::parse(x, is);
+  if (!err.empty()) {
+    picojson::set_last_error(err);
+    is.setstate(std::ios::failbit);
+  }
+  return is;
+}
+
+inline std::ostream& operator<<(std::ostream& os, const picojson::value& x) {
+  x.serialize(std::ostream_iterator<char>(os));
+  return os;
+}
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif
+#ifdef TEST_PICOJSON
+#ifdef _MSC_VER
+#pragma warning(disable : 4127)  // conditional expression is constant
+#endif
+
+using namespace std;
+
+static void plan(int num) {
+  printf("1..%d\n", num);
+}
+
+static bool success = true;
+
+static void ok(bool b, const char* name = "") {
+  static int n = 1;
+  if (!b)
+    success = false;
+  printf("%s %d - %s\n", b ? "ok" : "ng", n++, name);
+}
+
+template <typename T>
+void is(const T& x, const T& y, const char* name = "") {
+  if (x == y) {
+    ok(true, name);
+  } else {
+    ok(false, name);
+  }
+}
+
+#include <algorithm>
+#include <sstream>
+#include <float.h>
+#include <limits.h>
+
+int main(void) {
+  plan(85);
+
+// constructors
+#define TEST(expr, expected)                             \
+  is(picojson::value expr.serialize(), string(expected), \
+     "picojson::value" #expr)
+
+  TEST((true), "true");
+  TEST((false), "false");
+  TEST((42.0), "42");
+  TEST((string("hello")), "\"hello\"");
+  TEST(("hello"), "\"hello\"");
+  TEST(("hello", 4), "\"hell\"");
+
+  {
+    double a = 1;
+    for (int i = 0; i < 1024; i++) {
+      picojson::value vi(a);
+      std::stringstream ss;
+      ss << vi;
+      picojson::value vo;
+      ss >> vo;
+      double b = vo.get<double>();
+      if ((i < 53 && a != b) || fabs(a - b) / b > 1e-8) {
+        printf("ng i=%d a=%.18e b=%.18e\n", i, a, b);
+      }
+      a *= 2;
+    }
+  }
+
+#undef TEST
+
+#define TEST(in, type, cmp, serialize_test)             \
+  {                                                     \
+    picojson::value v;                                  \
+    const char* s = in;                                 \
+    string err = picojson::parse(v, s, s + strlen(s));  \
+    ok(err.empty(), in " no error");                    \
+    ok(v.is<type>(), in " check type");                 \
+    is<type>(v.get<type>(), cmp, in " correct output"); \
+    is(*s, '\0', in " read to eof");                    \
+    if (serialize_test) {                               \
+      is(v.serialize(), string(in), in " serialize");   \
+    }                                                   \
+  }
+  TEST("false", bool, false, true);
+  TEST("true", bool, true, true);
+  TEST("90.5", double, 90.5, false);
+  TEST("1.7976931348623157e+308", double, DBL_MAX, false);
+  TEST("\"hello\"", string, string("hello"), true);
+  TEST("\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"", string, string("\"\\/\b\f\n\r\t"),
+       true);
+  TEST("\"\\u0061\\u30af\\u30ea\\u30b9\"", string,
+       string("a\xe3\x82\xaf\xe3\x83\xaa\xe3\x82\xb9"), false);
+  TEST("\"\\ud840\\udc0b\"", string, string("\xf0\xa0\x80\x8b"), false);
+#undef TEST
+
+#define TEST(type, expr)                                               \
+  {                                                                    \
+    picojson::value v;                                                 \
+    const char* s = expr;                                              \
+    string err = picojson::parse(v, s, s + strlen(s));                 \
+    ok(err.empty(), "empty " #type " no error");                       \
+    ok(v.is<picojson::type>(), "empty " #type " check type");          \
+    ok(v.get<picojson::type>().empty(), "check " #type " array size"); \
+  }
+  TEST(array, "[]");
+  TEST(object, "{}");
+#undef TEST
+
+  {
+    picojson::value v;
+    const char* s = "[1,true,\"hello\"]";
+    string err = picojson::parse(v, s, s + strlen(s));
+    ok(err.empty(), "array no error");
+    ok(v.is<picojson::array>(), "array check type");
+    is(v.get<picojson::array>().size(), size_t(3), "check array size");
+    ok(v.contains(0), "check contains array[0]");
+    ok(v.get(0).is<double>(), "check array[0] type");
+    is(v.get(0).get<double>(), 1.0, "check array[0] value");
+    ok(v.contains(1), "check contains array[1]");
+    ok(v.get(1).is<bool>(), "check array[1] type");
+    ok(v.get(1).get<bool>(), "check array[1] value");
+    ok(v.contains(2), "check contains array[2]");
+    ok(v.get(2).is<string>(), "check array[2] type");
+    is(v.get(2).get<string>(), string("hello"), "check array[2] value");
+    ok(!v.contains(3), "check not contains array[3]");
+  }
+
+  {
+    picojson::value v;
+    const char* s = "{ \"a\": true }";
+    string err = picojson::parse(v, s, s + strlen(s));
+    ok(err.empty(), "object no error");
+    ok(v.is<picojson::object>(), "object check type");
+    is(v.get<picojson::object>().size(), size_t(1), "check object size");
+    ok(v.contains("a"), "check contains property");
+    ok(v.get("a").is<bool>(), "check bool property exists");
+    is(v.get("a").get<bool>(), true, "check bool property value");
+    is(v.serialize(), string("{\"a\":true}"), "serialize object");
+    ok(!v.contains("z"), "check not contains property");
+  }
+
+#define TEST(json, msg)                                \
+  do {                                                 \
+    picojson::value v;                                 \
+    const char* s = json;                              \
+    string err = picojson::parse(v, s, s + strlen(s)); \
+    is(err, string("syntax error at line " msg), msg); \
+  } while (0)
+  TEST("falsoa", "1 near: oa");
+  TEST("{]", "1 near: ]");
+  TEST("\n\bbell", "2 near: bell");
+  TEST("\"abc\nd\"", "1 near: ");
+#undef TEST
+
+  {
+    picojson::value v1, v2;
+    const char* s;
+    string err;
+    s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
+    err = picojson::parse(v1, s, s + strlen(s));
+    s = "{ \"d\": 2.0, \"b\": true, \"a\": [1,2,\"three\"] }";
+    err = picojson::parse(v2, s, s + strlen(s));
+    ok((v1 == v2), "check == operator in deep comparison");
+  }
+
+  {
+    picojson::value v1, v2;
+    const char* s;
+    string err;
+    s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
+    err = picojson::parse(v1, s, s + strlen(s));
+    s = "{ \"d\": 2.0, \"a\": [1,\"three\"], \"b\": true }";
+    err = picojson::parse(v2, s, s + strlen(s));
+    ok((v1 != v2), "check != operator for array in deep comparison");
+  }
+
+  {
+    picojson::value v1, v2;
+    const char* s;
+    string err;
+    s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
+    err = picojson::parse(v1, s, s + strlen(s));
+    s = "{ \"d\": 2.0, \"a\": [1,2,\"three\"], \"b\": false }";
+    err = picojson::parse(v2, s, s + strlen(s));
+    ok((v1 != v2), "check != operator for object in deep comparison");
+  }
+
+  {
+    picojson::value v1, v2;
+    const char* s;
+    string err;
+    s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
+    err = picojson::parse(v1, s, s + strlen(s));
+    picojson::object& o = v1.get<picojson::object>();
+    o.erase("b");
+    picojson::array& a = o["a"].get<picojson::array>();
+    picojson::array::iterator i;
+    i = std::remove(a.begin(), a.end(), picojson::value(std::string("three")));
+    a.erase(i, a.end());
+    s = "{ \"a\": [1,2], \"d\": 2 }";
+    err = picojson::parse(v2, s, s + strlen(s));
+    ok((v1 == v2), "check erase()");
+  }
+
+  ok(picojson::value(3.0).serialize() == "3",
+     "integral number should be serialized as a integer");
+
+  {
+    const char* s = "{ \"a\": [1,2], \"d\": 2 }";
+    picojson::null_parse_context ctx;
+    string err;
+    picojson::_parse(ctx, s, s + strlen(s), &err);
+    ok(err.empty(), "null_parse_context");
+  }
+
+  {
+    picojson::value v1, v2;
+    v1 = picojson::value(true);
+    swap(v1, v2);
+    ok(v1.is<picojson::null>(), "swap (null)");
+    ok(v2.get<bool>() == true, "swap (bool)");
+
+    v1 = picojson::value("a");
+    v2 = picojson::value(1.0);
+    swap(v1, v2);
+    ok(v1.get<double>() == 1.0, "swap (dobule)");
+    ok(v2.get<string>() == "a", "swap (string)");
+
+    v1 = picojson::value(picojson::object());
+    v2 = picojson::value(picojson::array());
+    swap(v1, v2);
+    ok(v1.is<picojson::array>(), "swap (array)");
+    ok(v2.is<picojson::object>(), "swap (object)");
+  }
+
+  return success ? 0 : 1;
+}
+
+#endif
diff --git a/tizen/common/platform_info.cc b/tizen/common/platform_info.cc
new file mode 100644 (file)
index 0000000..d88fe2d
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include <cstdlib>
+#include <system_info.h>
+#include "common/platform_info.h"
+
+namespace common {
+
+enum _profile getProfile(void) {
+  static enum _profile profile = kPROFILE_UNKNOWN;
+
+  // This is false only for the first execution. Let's optimize it.
+  if (__builtin_expect(profile != kPROFILE_UNKNOWN, 1))
+    return profile;
+
+  char* profileName;
+  system_info_get_platform_string("http://tizen.org/feature/profile",
+                                  &profileName);
+  switch (*profileName) {
+    case 'm':
+    case 'M':
+      profile = kPROFILE_MOBILE;
+      break;
+    case 'w':
+    case 'W':
+      profile = kPROFILE_WEARABLE;
+      break;
+    case 't':
+    case 'T':
+      profile = kPROFILE_TV;
+      break;
+    case 'i':
+    case 'I':
+      profile = kPROFILE_IVI;
+      break;
+    default:  // common or unknown ==> ALL ARE COMMON.
+      profile = kPROFILE_COMMON;
+  }
+  free(profileName);
+
+  return profile;
+}
+
+}  // namespace common
diff --git a/tizen/common/platform_info.h b/tizen/common/platform_info.h
new file mode 100644 (file)
index 0000000..adefc50
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_PLATFORM_INFO_H_
+#define XWALK_COMMON_PLATFORM_INFO_H_
+
+namespace common {
+
+enum _profile {
+  kPROFILE_UNKNOWN = 0,
+  kPROFILE_MOBILE = 0x1,
+  kPROFILE_WEARABLE = 0x2,
+  kPROFILE_TV = 0x4,
+  kPROFILE_IVI = 0x8,
+  kPROFILE_COMMON = 0x10,
+};
+
+// To optimize for GBMs, you may define the following values based on profile
+// (e.g., #define TIZEN_FEATURE_blahblah (1))
+
+#define TIZEN_FEATURE_web_ime_support \
+  (common::getProfile() & ((common::kPROFILE_WEARABLE) | (common::kPROFILE_TV)))
+#define TIZEN_FEATURE_manual_rotate_support \
+  (common::getProfile() & ((common::kPROFILE_MOBILE)))
+#define TIZEN_FEATURE_watch_face_support \
+  (common::getProfile() & ((common::kPROFILE_WEARABLE)))
+#define TIZEN_FEATURE_rotary_event_support \
+  (common::getProfile() & ((common::kPROFILE_WEARABLE)))
+
+extern enum _profile getProfile(void);
+
+}  // namespace common
+#endif  // XWALK_COMMON_PLATFORM_INFO_H_
diff --git a/tizen/common/profiler.cc b/tizen/common/profiler.cc
new file mode 100644 (file)
index 0000000..b468942
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "common/profiler.h"
+
+#include <math.h>
+#include <ttrace.h>
+
+#include "common/logger.h"
+#include "common/string_utils.h"
+
+namespace common {
+
+namespace {
+
+void PrintProfileTime(const char* step, const struct timespec& start) {
+  struct timespec end;
+  clock_gettime(CLOCK_REALTIME, &end);
+  int64_t diff_in_milli = (end.tv_sec - start.tv_sec) * 1000 +
+                          round((end.tv_nsec - start.tv_nsec) * 0.000001);
+  std::ostringstream ss;
+  ss << "END (" << diff_in_milli << "ms)";
+  PrintProfileLog(step, ss.str().c_str());
+}
+
+}  //  namespace
+
+void PrintProfileLog(const char* func, const char* tag) {
+  LOGGER_RAW(DLOG_DEBUG, LOGGER_TAG)
+      << "[PROF] [" << utils::GetCurrentMilliSeconds() << "] " << func << ":"
+      << tag;
+}
+
+ScopeProfile::ScopeProfile(const char* step, const bool isStep)
+    : step_(step), expired_(false), isStep_(isStep) {
+  clock_gettime(CLOCK_REALTIME, &start_);
+
+  if (!isStep) {
+    // Remove return type and parameter info from __PRETTY_FUNCTION__
+    int se = step_.find_first_of('(');
+    int ss = step_.find_last_of(' ', se) + 1;
+    if (ss < se) {
+      step_ = step_.substr(ss, se - ss);
+    }
+  }
+
+  PrintProfileLog(step_.c_str(), "START");
+
+  if (isStep_)
+    traceAsyncBegin(TTRACE_TAG_WEB, 0, "%s%s", "XWALK:", step_.c_str());
+  else
+    traceBegin(TTRACE_TAG_WEB, "%s%s", "XWALK:", step_.c_str());
+}
+
+ScopeProfile::~ScopeProfile() {
+  if (!expired_) {
+    PrintProfileTime(step_.c_str(), start_);
+
+    if (isStep_)
+      traceAsyncEnd(TTRACE_TAG_WEB, 0, "%s%s", "XWALK:", step_.c_str());
+    else
+      traceEnd(TTRACE_TAG_WEB);
+  }
+}
+
+void ScopeProfile::Reset() {
+  clock_gettime(CLOCK_REALTIME, &start_);
+  PrintProfileLog(step_.c_str(), "START-updated");
+
+  if (isStep_)
+    traceAsyncEnd(TTRACE_TAG_WEB, 0, "%s%s", "XWALK:", step_.c_str());
+  else
+    traceEnd(TTRACE_TAG_WEB);
+}
+
+void ScopeProfile::End() {
+  expired_ = true;
+  PrintProfileTime(step_.c_str(), start_);
+}
+
+StepProfile* StepProfile::GetInstance() {
+  static StepProfile instance;
+  return &instance;
+}
+
+StepProfile::StepProfile() {}
+
+StepProfile::~StepProfile() {}
+
+void StepProfile::Start(const char* step) {
+  map_[step].reset(new ScopeProfile(step, true));
+}
+
+void StepProfile::End(const char* step) {
+  map_[step].reset();
+}
+
+}  // namespace common
diff --git a/tizen/common/profiler.h b/tizen/common/profiler.h
new file mode 100644 (file)
index 0000000..48dea0f
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_PROFILER_H_
+#define XWALK_COMMON_PROFILER_H_
+
+#include <time.h>
+
+#include <map>
+#include <memory>
+#include <string>
+
+namespace common {
+
+#define PROFILE_START() PrintProfileLog(__FUNCTION__, "START");
+#define PROFILE_END() PrintProfileLog(__FUNCTION__, "END");
+#define PROFILE(x) PrintProfileLog(__FUNCTION__, x);
+
+void PrintProfileLog(const char* func, const char* tag);
+
+class ScopeProfile {
+ public:
+  explicit ScopeProfile(const char* step, const bool isStep);
+  ~ScopeProfile();
+  void Reset();
+  void End();
+
+ private:
+  std::string step_;
+  struct timespec start_;
+  bool expired_;
+  bool isStep_;
+};
+
+class StepProfile {
+ public:
+  static StepProfile* GetInstance();
+  void Start(const char* step);
+  void End(const char* step);
+
+ private:
+  StepProfile();
+  ~StepProfile();
+  typedef std::map<const std::string, std::unique_ptr<ScopeProfile> >
+      ProfileMapT;
+  ProfileMapT map_;
+};
+
+}  // namespace common
+
+#define SCOPE_PROFILE() \
+  common::ScopeProfile __profile(__PRETTY_FUNCTION__, false);
+
+#define STEP_PROFILE_START(x) common::StepProfile::GetInstance()->Start(x)
+
+#define STEP_PROFILE_END(x) common::StepProfile::GetInstance()->End(x)
+
+#endif  // XWALK_COMMON_PROFILER_H_
diff --git a/tizen/common/resource_manager.cc b/tizen/common/resource_manager.cc
new file mode 100644 (file)
index 0000000..e177ab5
--- /dev/null
@@ -0,0 +1,725 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "common/resource_manager.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <aul.h>
+#include <pkgmgr-info.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <web_app_enc.h>
+
+#include <algorithm>
+#include <functional>
+#include <memory>
+#include <set>
+#include <sstream>
+#include <vector>
+
+#include "common/application_data.h"
+#include "common/app_control.h"
+#include "common/file_utils.h"
+#include "common/locale_manager.h"
+#include "common/logger.h"
+#include "common/string_utils.h"
+#include "common/url.h"
+
+using wgt::parse::AppControlInfo;
+
+namespace common {
+
+namespace {
+
+typedef std::vector<AppControlInfo> AppControlList;
+
+// Scheme type
+const char* kSchemeTypeApp = "app://";
+const char* kSchemeTypeFile = "file://";
+const char* kSchemeTypeHttp = "http://";
+const char* kSchemeTypeHttps = "https://";
+// lendth of scheme identifier ://
+const int kSchemeIdLen = 3;
+// TODO(wy80.choi): comment out below unused const variables if needed.
+// const char* kSchemeTypeWidget = "widget://";
+
+// Default Start Files
+const char* kDefaultStartFiles[] = {"index.htm", "index.html", "index.svg",
+                                    "index.xhtml", "index.xht"};
+
+// Default Encoding
+const char* kDefaultEncoding = "UTF-8";
+
+// EncryptedFileExtensions
+const std::set<std::string> kEncryptedFileExtensions{".html", ".htm", ".css",
+                                                     ".js"};
+
+static std::string GetMimeFromUri(const std::string& uri) {
+  // checking passed uri is local file
+  std::string file_uri_case(kSchemeTypeFile);
+  int ret = AUL_R_EINVAL;
+  char mimetype[128] = {
+      0,
+  };
+  size_t pos = std::string::npos;
+  if (utils::StartsWith(uri, file_uri_case)) {
+    // case 1. uri = file:///xxxx
+    ret =
+        aul_get_mime_from_file(uri.substr(pos + file_uri_case.length()).c_str(),
+                               mimetype, sizeof(mimetype));
+  } else if (utils::StartsWith(uri, "/")) {
+    // case 2. uri = /xxxx
+    ret = aul_get_mime_from_file(uri.c_str(), mimetype, sizeof(mimetype));
+  }
+
+  if (ret == AUL_R_OK) {
+    return std::string(mimetype);
+  } else {
+    return std::string();
+  }
+}
+
+static bool CompareMime(const std::string& info_mime,
+                        const std::string& request_mime) {
+  // suppose that these mimetypes are valid expressions ('type'/'sub-type')
+  if (info_mime == "*" || info_mime == "*/*")
+    return true;
+
+  if (request_mime.empty())
+    return info_mime.empty();
+
+  std::string info_type;
+  std::string info_sub;
+  std::string request_type;
+  std::string request_sub;
+  if (!(utils::SplitString(info_mime, &info_type, &info_sub, '/') &&
+        utils::SplitString(request_mime, &request_type, &request_sub, '/')))
+    return false;
+
+  return info_type == request_type && (info_sub == "*")
+             ? true
+             : (info_sub == request_sub);
+}
+
+static bool CompareUri(const std::string& info_uri,
+                       const std::string& request_uri) {
+  if (info_uri == "*")
+    return true;
+
+  if (request_uri.empty())
+    return info_uri.empty();
+
+  std::string info_scheme = utils::SchemeName(info_uri);
+
+  // if has only scheme or scheme+star. ex) http, http://, http://*
+  if (!info_scheme.empty() &&
+      (info_uri == info_scheme || utils::EndsWith(info_uri, "://") ||
+       utils::EndsWith(info_uri, "://*"))) {
+    return utils::SchemeName(request_uri) == info_scheme;
+  }
+
+  if (utils::EndsWith(info_uri, "*")) {
+    return utils::StartsWith(request_uri,
+                             info_uri.substr(0, info_uri.length() - 1));
+  } else {
+    return request_uri == info_uri;
+  }
+}
+
+static std::string InsertPrefixPath(const std::string& start_uri) {
+  if (start_uri.find("://") != std::string::npos)
+    return start_uri;
+  else
+    return std::string(kSchemeTypeFile) + "/" + start_uri;
+}
+
+}  // namespace
+
+ResourceManager::Resource::Resource(const std::string& uri)
+    : uri_(uri), should_reset_(true), encoding_(kDefaultEncoding) {}
+
+ResourceManager::Resource::Resource(const std::string& uri, bool should_reset)
+    : uri_(uri), should_reset_(should_reset), encoding_(kDefaultEncoding) {}
+
+ResourceManager::Resource::Resource(const std::string& uri,
+                                    const std::string& mime,
+                                    const std::string& encoding)
+    : uri_(uri), mime_(mime), should_reset_(true), encoding_(encoding) {}
+
+ResourceManager::Resource::Resource(const ResourceManager::Resource& res) {
+  *this = res;
+}
+
+ResourceManager::Resource& ResourceManager::Resource::operator=(
+    const ResourceManager::Resource& res) {
+  this->uri_ = res.uri();
+  this->mime_ = res.mime();
+  this->should_reset_ = res.should_reset();
+  this->encoding_ = res.encoding();
+  return *this;
+}
+
+bool ResourceManager::Resource::operator==(const Resource& res) {
+  if (this->uri_ == res.uri() && this->mime_ == res.mime() &&
+      this->should_reset_ == res.should_reset() &&
+      this->encoding_ == res.encoding()) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+ResourceManager::ResourceManager(ApplicationData* application_data,
+                                 LocaleManager* locale_manager)
+    : application_data_(application_data),
+      locale_manager_(locale_manager),
+      security_model_version_(0) {
+  if (application_data != NULL) {
+    appid_ = application_data->tizen_application_info()->id();
+    if (application_data->csp_info() != NULL ||
+        application_data->csp_report_info() != NULL ||
+        application_data->allowed_navigation_info() != NULL) {
+      security_model_version_ = 2;
+    } else {
+      security_model_version_ = 1;
+    }
+  }
+}
+
+std::unique_ptr<ResourceManager::Resource>
+ResourceManager::GetDefaultResource() {
+  std::string src;
+  std::string type;
+  std::string encoding = kDefaultEncoding;
+
+  std::shared_ptr<const wgt::parse::ContentInfo> content_info;
+  if (application_data_) {
+    content_info = application_data_->content_info();
+    if (content_info) {
+      src = content_info->src();
+      type = content_info->type();
+      encoding = content_info->encoding();
+      LOGGER(DEBUG) << "src: " << src;
+      LOGGER(DEBUG) << "type: " << type;
+      LOGGER(DEBUG) << "encoding: " << encoding;
+    } else {
+      LOGGER(DEBUG) << "content_info is null";
+    }
+  }
+
+  // Check that tizen:content src is external page
+  if (utils::StartsWith(src, kSchemeTypeHttp) ||
+      utils::StartsWith(src, kSchemeTypeHttps)) {
+    LOGGER(DEBUG) << "tizen content_info's src is an external page";
+    return std::unique_ptr<Resource>(new Resource(src, type, encoding));
+  }
+
+  // Find based on default start files list, if src is empty or invald
+  if (!content_info || !utils::Exists(resource_base_path_ + src)) {
+    for (auto& start_file : kDefaultStartFiles) {
+      if (utils::Exists(resource_base_path_ + start_file)) {
+        src = InsertPrefixPath(start_file);
+        LOGGER(DEBUG) << "start file: " << src;
+        return std::unique_ptr<Resource>(new Resource(src, type, encoding));
+      }
+    }
+    // shouldn't be entered here
+    LOGGER(ERROR) << "it can't enter here. can't find any default start file";
+    return std::unique_ptr<Resource>(new Resource(src, type, encoding));
+  }
+
+  return std::unique_ptr<Resource>(
+      new Resource(InsertPrefixPath(src), type, encoding));
+}
+
+std::unique_ptr<ResourceManager::Resource> ResourceManager::GetMatchedResource(
+    const AppControlInfo& app_control_info) {
+  if (!app_control_info.src().empty()) {
+    return std::unique_ptr<Resource>(
+        new Resource(InsertPrefixPath(app_control_info.src()),
+                     app_control_info.reload() == "disable" ? false : true));
+  }
+  return GetDefaultResource();
+}
+
+std::unique_ptr<ResourceManager::Resource> ResourceManager::GetStartResource(
+    const AppControl* app_control) {
+  std::string operation = app_control->operation();
+  if (operation.empty()) {
+    LOGGER(ERROR) << "operation(mandatory) is NULL";
+    return GetDefaultResource();
+  }
+
+  std::string mime = app_control->mime();
+  std::string uri = app_control->uri();
+  if (mime.empty() && !uri.empty()) {
+    mime = GetMimeFromUri(uri);
+  }
+
+  LOGGER(DEBUG) << "Passed AppControl data";
+  LOGGER(DEBUG) << " - operation : " << operation;
+  LOGGER(DEBUG) << " - mimetype  : " << mime;
+  LOGGER(DEBUG) << " - uri       : " << uri;
+
+  if (application_data_ == NULL ||
+      application_data_->app_control_info_list() == NULL) {
+    return GetDefaultResource();
+  }
+
+  auto app_control_list = application_data_->app_control_info_list()->controls;
+
+  AppControlList::const_iterator iter = std::find_if(
+      app_control_list.begin(), app_control_list.end(),
+      [&operation, &uri, &mime](AppControlInfo& info) -> bool {
+        return (info.operation() == operation) &&
+               CompareMime(info.mime(), mime) && CompareUri(info.uri(), uri);
+      });
+
+  if (iter != app_control_list.end()) {
+    return GetMatchedResource(*iter);
+  } else {
+    return GetDefaultResource();
+  }
+}
+
+std::string ResourceManager::GetLocalizedPath(const std::string& origin) {
+  std::string file_scheme = std::string() + kSchemeTypeFile + "/";
+  std::string app_scheme = std::string() + kSchemeTypeApp;
+  std::string locale_path = "locales/";
+  auto find = locale_cache_.find(origin);
+  if (find != locale_cache_.end()) {
+    return find->second;
+  }
+  std::string& result = locale_cache_[origin];
+  result = origin;
+  std::string url = origin;
+
+  std::string suffix;
+  size_t pos = url.find_first_of("#?");
+  if (pos != std::string::npos) {
+    suffix = url.substr(pos);
+    url.resize(pos);
+  }
+
+  if (utils::StartsWith(url, app_scheme)) {
+    // remove "app://"
+    url.erase(0, app_scheme.length());
+
+    // remove app id + /
+    std::string check = appid_ + "/";
+    if (utils::StartsWith(url, check)) {
+      url.erase(0, check.length());
+    } else {
+      LOGGER(ERROR) << "Invalid uri: {scheme:app} uri=" << origin;
+      return result;
+    }
+  } else if (utils::StartsWith(url, file_scheme)) {
+    // remove "file:///"
+    url.erase(0, file_scheme.length());
+  }
+
+  if (!url.empty() && url[url.length() - 1] == '/') {
+    url.erase(url.length() - 1, 1);
+  }
+
+  if (url.empty()) {
+    LOGGER(ERROR) << "Invalid uri: uri=" << origin;
+    return result;
+  }
+
+  std::string file_path = utils::UrlDecode(RemoveLocalePath(url));
+  for (auto& locales : locale_manager_->system_locales()) {
+    // check ../locales/
+    std::string app_locale_path = resource_base_path_ + locale_path;
+    if (!Exists(app_locale_path)) {
+      break;
+    }
+
+    // check locale path ../locales/en_us/
+    std::string app_localized_path = app_locale_path + locales + "/";
+    if (!Exists(app_localized_path)) {
+      continue;
+    }
+    std::string resource_path = app_localized_path + file_path;
+    if (Exists(resource_path)) {
+      result = "file://" + resource_path + suffix;
+      return result;
+    }
+  }
+
+  std::string default_locale = resource_base_path_ + file_path;
+  if (Exists(default_locale)) {
+    result = "file://" + default_locale + suffix;
+    return result;
+  }
+
+  LOGGER(ERROR) << "Invalid uri: uri=" << origin << ", decoded=" << file_path;
+  return result;
+}
+
+std::string ResourceManager::RemoveLocalePath(const std::string& path) {
+  std::string locale_path = "locales/";
+  std::string result_path = path.at(0) == '/' ? path : "/" + path;
+  if (!utils::StartsWith(result_path, resource_base_path_)) {
+    return path;
+  }
+
+  result_path = result_path.substr(resource_base_path_.length());
+  if (!utils::StartsWith(result_path, locale_path)) {
+    return result_path;
+  }
+
+  size_t found = result_path.find_first_of('/', locale_path.length());
+  if (found != std::string::npos) {
+    result_path = result_path.substr(found + 1);
+  }
+  return result_path;
+}
+
+void ResourceManager::set_base_resource_path(const std::string& path) {
+  if (path.empty()) {
+    return;
+  }
+
+  resource_base_path_ = path;
+  if (resource_base_path_[resource_base_path_.length() - 1] != '/') {
+    resource_base_path_ += "/";
+  }
+}
+
+bool ResourceManager::Exists(const std::string& path) {
+  auto find = file_existed_cache_.find(path);
+  if (find != file_existed_cache_.end()) {
+    return find->second;
+  }
+  bool ret = file_existed_cache_[path] = utils::Exists(path);
+  return ret;
+}
+
+bool ResourceManager::AllowNavigation(const std::string& url) {
+  if (security_model_version_ == 2)
+    return CheckAllowNavigation(url);
+  return CheckWARP(url);
+}
+
+bool ResourceManager::AllowedResource(const std::string& url) {
+  if (security_model_version_ == 2)
+    return true;
+  return CheckWARP(url);
+}
+
+bool ResourceManager::CheckWARP(const std::string& url) {
+  // allow non-external resource
+  if (!utils::StartsWith(url, kSchemeTypeHttp) &&
+      !utils::StartsWith(url, kSchemeTypeHttps)) {
+    return true;
+  }
+
+  auto warp = application_data_->warp_info();
+  if (warp.get() == NULL)
+    return false;
+
+  auto find = warp_cache_.find(url);
+  if (find != warp_cache_.end()) {
+    return find->second;
+  }
+
+  bool& result = warp_cache_[url];
+  result = true;
+
+  URL url_info(url);
+
+  // if didn't have a scheme, it means local resource
+  if (url_info.scheme().empty()) {
+    return true;
+  }
+
+  for (auto& allow : warp->access_map()) {
+    if (allow.first == "*") {
+      return true;
+    } else if (allow.first.empty()) {
+      continue;
+    }
+
+    URL allow_url(allow.first);
+
+    // should be match the scheme and port
+    if (allow_url.scheme() != url_info.scheme() ||
+        allow_url.port() != url_info.port()) {
+      continue;
+    }
+
+    // if domain alos was matched, allow resource
+    if (allow_url.domain() == url_info.domain()) {
+      return true;
+    } else if (allow.second) {
+      // if does not match domain, should be check sub domain
+
+      // filter : test.com , subdomain=true
+      // url : aaa.test.com
+      // check url was ends with ".test.com"
+      if (utils::EndsWith(url_info.domain(), "." + allow_url.domain())) {
+        return true;
+      }
+    }
+  }
+
+  return result = false;
+}
+
+bool ResourceManager::CheckAllowNavigation(const std::string& url) {
+  // allow non-external resource
+  if (!utils::StartsWith(url, kSchemeTypeHttp) &&
+      !utils::StartsWith(url, kSchemeTypeHttps)) {
+    return true;
+  }
+
+  auto allow = application_data_->allowed_navigation_info();
+  if (allow.get() == NULL)
+    return false;
+
+  auto find = warp_cache_.find(url);
+  if (find != warp_cache_.end()) {
+    return find->second;
+  }
+
+  bool& result = warp_cache_[url];
+  result = true;
+
+  URL url_info(url);
+
+  // if didn't have a scheme, it means local resource
+  if (url_info.scheme().empty()) {
+    return true;
+  }
+
+  for (auto& allow_domain : allow->GetAllowedDomains()) {
+    URL a_domain_info(allow_domain);
+
+    // check wildcard *
+    if (a_domain_info.domain() == "*") {
+      return true;
+    }
+
+    bool prefix_wild = false;
+    bool suffix_wild = false;
+    std::string a_domain = a_domain_info.domain();
+    if (utils::StartsWith(a_domain, "*")) {
+      prefix_wild = true;
+      // *.domain.com -> .domain.com
+      a_domain = a_domain.substr(1);
+    }
+    if (utils::EndsWith(a_domain, "*")) {
+      suffix_wild = true;
+      // domain.* -> domain.
+      a_domain = a_domain.substr(0, a_domain.length() - 1);
+    }
+
+    if (!prefix_wild && !suffix_wild) {
+      // if no wildcard, should be exactly matched
+      if (url_info.domain() == a_domain) {
+        return true;
+      }
+    } else if (prefix_wild && !suffix_wild) {
+      // *.domain.com : it shoud be "domain.com" or end with ".domain.com"
+      if (url_info.domain() == a_domain.substr(1) ||
+          utils::EndsWith(url_info.domain(), a_domain)) {
+        return true;
+      }
+    } else if (!prefix_wild && suffix_wild) {
+      // www.sample.* : it should be starts with "www.sample."
+      if (utils::StartsWith(url_info.domain(), a_domain)) {
+        return true;
+      }
+    } else if (prefix_wild && suffix_wild) {
+      // *.sample.* : it should be starts with sample. or can find ".sample."
+      // in url
+      if (utils::StartsWith(url_info.domain(), a_domain.substr(1)) ||
+          std::string::npos != url_info.domain().find(a_domain)) {
+        return true;
+      }
+    }
+  }
+
+  return result = false;
+}
+
+bool ResourceManager::IsEncrypted(const std::string& path) {
+  auto setting = application_data_->setting_info();
+  if (setting.get() == NULL)
+    return false;
+
+  if (setting->encryption_enabled()) {
+    std::string ext = utils::ExtName(path);
+    if (kEncryptedFileExtensions.count(ext) > 0) {
+      return true;
+    }
+  }
+  return false;
+}
+
+std::string ResourceManager::DecryptResource(const std::string& path) {
+  // read file and make a buffer
+  std::string src_path(path);
+  if (utils::StartsWith(src_path, kSchemeTypeFile)) {
+    src_path.erase(0, strlen(kSchemeTypeFile));
+  }
+
+  // Remove the parameters at the end of an href attribute
+  size_t end_of_path = src_path.find_first_of("?#");
+  if (end_of_path != std::string::npos)
+    src_path = src_path.substr(0, end_of_path);
+
+  // checking web app type
+  static bool inited = false;
+  static bool is_global = false;
+  static bool is_preload = false;
+
+  std::string pkg_id = application_data_->pkg_id();
+  if (!inited) {
+    inited = true;
+    pkgmgrinfo_pkginfo_h handle;
+    int ret =
+        pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), getuid(), &handle);
+    if (ret != PMINFO_R_OK) {
+      LOGGER(ERROR) << "Could not get handle for pkginfo : pkg_id = " << pkg_id;
+      return path;
+    } else {
+      ret = pkgmgrinfo_pkginfo_is_global(handle, &is_global);
+      if (ret != PMINFO_R_OK) {
+        LOGGER(ERROR) << "Could not check is_global : pkg_id = " << pkg_id;
+        pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+        return path;
+      }
+      ret = pkgmgrinfo_pkginfo_is_preload(handle, &is_preload);
+      if (ret != PMINFO_R_OK) {
+        LOGGER(ERROR) << "Could not check is_preload : pkg_id = " << pkg_id;
+        pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+        return path;
+      }
+      pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+    }
+  }
+
+  struct stat buf;
+  memset(&buf, 0, sizeof(buf));
+  if (stat(src_path.c_str(), &buf) == 0) {
+    const std::size_t file_size = buf.st_size;
+    std::unique_ptr<unsigned char[]> in_chunk;
+
+    if (0 == file_size) {
+      LOGGER(ERROR) << src_path.c_str()
+                    << " size is 0, so decryption is skiped";
+      return path;
+    }
+
+    FILE* src = fopen(src_path.c_str(), "rb");
+    if (src == NULL) {
+      LOGGER(ERROR) << "Cannot open file for decryption: " << path;
+      return path;
+    }
+
+    // Read buffer from the source file
+    std::unique_ptr<unsigned char[]> decrypted_str(
+        new unsigned char[file_size]);
+    int decrypted_size = 0;
+
+    do {
+      unsigned char get_dec_size[5];
+      memset(get_dec_size, 0x00, sizeof(get_dec_size));
+
+      size_t read_size = fread(get_dec_size, 1, 4, src);
+      if (0 != read_size) {
+        unsigned int read_buf_size = 0;
+        std::istringstream(std::string((char*)get_dec_size)) >> read_buf_size;
+        if (read_buf_size == 0) {
+          LOGGER(ERROR) << "Failed to read resource";
+          fclose(src);
+          return path;
+        }
+        in_chunk.reset(new unsigned char[read_buf_size]);
+
+        size_t dec_read_size = fread(in_chunk.get(), 1, read_buf_size, src);
+        if (0 != dec_read_size) {
+          unsigned char* decrypted_data = nullptr;
+          size_t decrypted_len = 0;
+          int ret;
+          if (is_global) {
+            ret = wae_decrypt_global_web_application(
+                pkg_id.c_str(), is_preload, in_chunk.get(), (int)dec_read_size,
+                &decrypted_data, &decrypted_len);
+          } else {
+            ret = wae_decrypt_web_application(
+                getuid(), pkg_id.c_str(), in_chunk.get(), (int)dec_read_size,
+                &decrypted_data, &decrypted_len);
+          }
+
+          if (WAE_ERROR_NONE != ret) {
+            LOGGER(ERROR) << "Error during decryption: ";
+            switch (ret) {
+              case WAE_ERROR_INVALID_PARAMETER:
+                LOGGER(ERROR) << "WAE_ERROR_INVALID_PARAMETER";
+                break;
+              case WAE_ERROR_PERMISSION_DENIED:
+                LOGGER(ERROR) << "WAE_ERROR_PERMISSION_DENIED";
+                break;
+              case WAE_ERROR_NO_KEY:
+                LOGGER(ERROR) << "WAE_ERROR_NO_KEY";
+                break;
+              case WAE_ERROR_KEY_MANAGER:
+                LOGGER(ERROR) << "WAE_ERROR_KEY_MANAGER";
+                break;
+              case WAE_ERROR_CRYPTO:
+                LOGGER(ERROR) << "WAE_ERROR_CRYPTO";
+                break;
+              case WAE_ERROR_UNKNOWN:
+                LOGGER(ERROR) << "WAE_ERROR_UNKNOWN";
+                break;
+              default:
+                LOGGER(ERROR) << "UNKNOWN";
+                break;
+            }
+            fclose(src);
+            return path;
+          }
+
+          memcpy(decrypted_str.get() + decrypted_size, decrypted_data,
+                 decrypted_len);
+          decrypted_size += decrypted_len;
+          std::free(decrypted_data);
+        }
+      }
+    } while (0 == std::feof(src));
+    fclose(src);
+    memset(decrypted_str.get() + decrypted_size, '\n',
+           file_size - decrypted_size);
+
+    // change to data schem
+    std::stringstream dst_str;
+    std::string content_type = GetMimeFromUri(path);
+    std::string encoded =
+        utils::Base64Encode(decrypted_str.get(), decrypted_size);
+    dst_str << "data:" << content_type << ";base64," << encoded;
+
+    decrypted_str.reset(new unsigned char[file_size]);
+
+    return dst_str.str();
+  }
+  return path;
+}
+
+}  // namespace common
diff --git a/tizen/common/resource_manager.h b/tizen/common/resource_manager.h
new file mode 100644 (file)
index 0000000..298236a
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_RESOURCE_MANAGER_H_
+#define XWALK_COMMON_RESOURCE_MANAGER_H_
+
+#include <map>
+#include <memory>
+#include <string>
+
+namespace wgt {
+namespace parse {
+class AppControlInfo;
+}  // namespace parse
+}  // namespace wgt
+
+namespace common {
+
+class ApplicationData;
+class LocaleManager;
+class AppControl;
+
+class ResourceManager {
+ public:
+  class Resource {
+   public:
+    explicit Resource(const std::string& uri);
+    Resource(const std::string& uri, bool should_reset);
+    Resource(const std::string& uri,
+             const std::string& mime,
+             const std::string& encoding);
+    Resource(const Resource& res);
+    ~Resource() {}
+
+    Resource& operator=(const Resource& res);
+    bool operator==(const Resource& res);
+
+    void set_uri(const std::string& uri) { uri_ = uri; }
+    void set_mime(const std::string& mime) { mime_ = mime; }
+    void set_should_reset(bool should_reset) { should_reset_ = should_reset; }
+    void set_encoding(const std::string& encoding) { encoding_ = encoding; }
+
+    std::string uri() const { return uri_; }
+    std::string mime() const { return mime_; }
+    bool should_reset() const { return should_reset_; }
+    std::string encoding() const { return encoding_; }
+
+   private:
+    std::string uri_;
+    std::string mime_;
+    bool should_reset_;
+    std::string encoding_;
+  };
+
+  ResourceManager(ApplicationData* application_data,
+                  LocaleManager* locale_manager);
+  ~ResourceManager() {}
+
+  // input : file:///..... , app://[appid]/....
+  // output : /[system path]/.../locales/.../
+  std::string GetLocalizedPath(const std::string& origin);
+  std::unique_ptr<Resource> GetStartResource(const AppControl* app_control);
+  bool AllowNavigation(const std::string& url);
+  bool AllowedResource(const std::string& url);
+
+  bool IsEncrypted(const std::string& url);
+  std::string DecryptResource(const std::string& path);
+
+  void set_base_resource_path(const std::string& base_path);
+
+ private:
+  std::unique_ptr<Resource> GetMatchedResource(
+      const wgt::parse::AppControlInfo&);
+  std::unique_ptr<Resource> GetDefaultResource();
+
+  // for localization
+  bool Exists(const std::string& path);
+  bool CheckWARP(const std::string& url);
+  bool CheckAllowNavigation(const std::string& url);
+  std::string RemoveLocalePath(const std::string& path);
+
+  std::string resource_base_path_;
+  std::string appid_;
+  std::map<const std::string, bool> file_existed_cache_;
+  std::map<const std::string, std::string> locale_cache_;
+  std::map<const std::string, bool> warp_cache_;
+
+  ApplicationData* application_data_;
+  LocaleManager* locale_manager_;
+  int security_model_version_;
+};
+
+}  // namespace common
+
+#endif  // XWALK_COMMON_RESOURCE_MANAGER_H_
diff --git a/tizen/common/string_utils.cc b/tizen/common/string_utils.cc
new file mode 100644 (file)
index 0000000..95402d9
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "common/string_utils.h"
+
+#include <uuid/uuid.h>
+#include <glib.h>
+#include <math.h>
+#include <time.h>
+
+#include <algorithm>
+#include <iomanip>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace common {
+namespace utils {
+
+std::string GenerateUUID() {
+  char tmp[37];
+  uuid_t uuid;
+  uuid_generate(uuid);
+  uuid_unparse(uuid, tmp);
+  return std::string(tmp);
+}
+
+bool StartsWith(const std::string& str, const std::string& sub) {
+  if (sub.size() > str.size())
+    return false;
+  return std::equal(sub.begin(), sub.end(), str.begin());
+}
+
+bool EndsWith(const std::string& str, const std::string& sub) {
+  if (sub.size() > str.size())
+    return false;
+  return std::equal(sub.rbegin(), sub.rend(), str.rbegin());
+}
+
+std::string ReplaceAll(const std::string& replace,
+                       const std::string& from,
+                       const std::string& to) {
+  std::string str = replace;
+  size_t pos = str.find(from);
+  while (pos != std::string::npos) {
+    str.replace(pos, from.length(), to);
+    pos = str.find(from, pos + to.length());
+  }
+  return str;
+}
+
+std::string GetCurrentMilliSeconds() {
+  std::ostringstream ss;
+  struct timespec spec;
+  clock_gettime(CLOCK_REALTIME, &spec);
+  ss << (spec.tv_sec % 10000) << "." << std::setw(3) << std::setfill('0')
+     << (round(spec.tv_nsec / 1.0e6));
+  return ss.str();
+}
+
+bool SplitString(const std::string& str,
+                 std::string* part_1,
+                 std::string* part_2,
+                 const char delim) {
+  if (part_1 == nullptr || part_2 == nullptr)
+    return false;
+
+  size_t pos = str.find(delim);
+  if (pos == std::string::npos)
+    return false;
+
+  *part_1 = str.substr(0, pos);
+  *part_2 = str.substr(pos + 1);
+  return true;
+}
+
+std::string UrlDecode(const std::string& url) {
+  std::unique_ptr<char, decltype(std::free)*> decoded_str{
+      g_uri_unescape_string(url.c_str(), NULL), std::free};
+  return decoded_str.get() != nullptr ? std::string(decoded_str.get()) : url;
+}
+
+std::string UrlEncode(const std::string& url) {
+  std::unique_ptr<char, decltype(std::free)*> encoded_str{
+      g_uri_escape_string(url.c_str(), NULL, TRUE), std::free};
+  return encoded_str.get() != nullptr ? std::string(encoded_str.get()) : url;
+}
+
+std::string Base64Encode(const unsigned char* data, size_t len) {
+  gchar* encoded = g_base64_encode(data, len);
+  std::unique_ptr<gchar, decltype(g_free)*> encoded_ptr{encoded, g_free};
+  return std::string(encoded);
+}
+
+}  // namespace utils
+}  // namespace common
diff --git a/tizen/common/string_utils.h b/tizen/common/string_utils.h
new file mode 100644 (file)
index 0000000..3bfe694
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_STRING_UTILS_H_
+#define XWALK_COMMON_STRING_UTILS_H_
+
+#include <string>
+#include <vector>
+
+namespace common {
+namespace utils {
+
+std::string GenerateUUID();
+bool StartsWith(const std::string& str, const std::string& sub);
+bool EndsWith(const std::string& str, const std::string& sub);
+std::string ReplaceAll(const std::string& replace,
+                       const std::string& from,
+                       const std::string& to);
+std::string GetCurrentMilliSeconds();
+bool SplitString(const std::string& str,
+                 std::string* part_1,
+                 std::string* part_2,
+                 const char delim);
+std::string UrlEncode(const std::string& url);
+std::string UrlDecode(const std::string& url);
+std::string Base64Encode(const unsigned char* data, size_t len);
+
+}  // namespace utils
+}  // namespace common
+
+#endif  // XWALK_COMMON_STRING_UTILS_H_
diff --git a/tizen/common/url.cc b/tizen/common/url.cc
new file mode 100644 (file)
index 0000000..78d7c6b
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "common/url.h"
+
+#include <algorithm>
+#include <stdexcept>
+
+#include "common/logger.h"
+#include "common/string_utils.h"
+
+namespace common {
+
+namespace {
+
+const char* kSchemeTypeFile = "file";
+const char* kSchemeTypeHttp = "http";
+const char* kSchemeTypeHttps = "https";
+const char* kSchemeTypeSsh = "ssh";
+const char* kSchemeTypeFtp = "ftp";
+
+// length of scheme identifier ://
+const int kSchemeIdLen = 3;
+int kPortHttp = 80;
+int kPortHttps = 443;
+int kPortSsh = 22;
+int kPortFtp = 21;
+int kPortDefault = 0;
+
+int GetDefaultPort(const std::string& scheme) {
+  if (scheme == kSchemeTypeHttp)
+    return kPortHttp;
+  else if (scheme == kSchemeTypeHttps)
+    return kPortHttps;
+  else if (scheme == kSchemeTypeSsh)
+    return kPortSsh;
+  else if (scheme == kSchemeTypeFtp)
+    return kPortFtp;
+  else
+    return kPortDefault;
+}
+
+}  // namespace
+
+class URLImpl {
+ public:
+  explicit URLImpl(const std::string& url);
+  URLImpl() {}
+
+  std::string url() const { return url_; }
+  std::string scheme() const { return scheme_; }
+  std::string domain() const { return domain_; }
+  int port() const { return port_; }
+  std::string path() const { return path_; }
+
+ private:
+  std::string url_;
+  std::string scheme_;
+  std::string domain_;
+  int port_;
+  std::string path_;
+
+  bool ExtractScheme();
+  void ExtractDomain();
+  void ExtractDomainPort();
+  void ExtractPath();
+};
+
+URLImpl::URLImpl(const std::string& url) : port_(0) {
+  if (url.empty())
+    return;
+
+  url_ = url;
+  if (!ExtractScheme()) {
+    ExtractDomain();
+    ExtractPath();
+    return;
+  }
+
+  if (scheme_ != kSchemeTypeFile)
+    ExtractDomainPort();
+
+  ExtractPath();
+}
+
+bool URLImpl::ExtractScheme() {
+  size_t end_of_scheme = 0;
+  if (url_.find("://") != std::string::npos) {
+    end_of_scheme = url_.find("://");
+    std::string scheme = url_.substr(0, end_of_scheme);
+    std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower);
+    scheme_ = scheme;
+    return true;
+  } else {
+    return false;
+  }
+}
+
+void URLImpl::ExtractDomain() {
+  size_t start_of_domain =
+      scheme_.empty() ? 0 : scheme_.length() + kSchemeIdLen;
+  size_t end_of_domain = url_.find_first_of('/', start_of_domain);
+  size_t at = url_.find_first_of('@', start_of_domain);
+  if (at < end_of_domain) {
+    start_of_domain = at + 1;
+  }
+  domain_ = url_.substr(start_of_domain, end_of_domain == std::string::npos
+                                             ? std::string::npos
+                                             : end_of_domain - start_of_domain);
+  LOGGER(INFO) << "Extract Domain is " << domain_;
+}
+
+void URLImpl::ExtractDomainPort() {
+  ExtractDomain();
+  std::string domain = domain_;
+
+  // Decide start position to find port considering IPv6 case
+  size_t start_pos = domain.find('@');
+  start_pos = (start_pos != std::string::npos) ? start_pos + 1 : 0;
+  if (domain[start_pos] == '[')
+    start_pos = domain.find(']', start_pos + 1);
+
+  size_t port_separator =
+      domain.find_first_of(':', start_pos != std::string::npos ? start_pos : 0);
+  if (port_separator != std::string::npos) {
+    domain_ = domain.substr(0, port_separator);
+    std::string port = domain.substr(port_separator + 1);
+    if (port.empty()) {
+      port_ = GetDefaultPort(scheme_);
+    } else {
+      try {
+        port_ = std::stoi(port);
+      } catch (...) {
+        port_ = GetDefaultPort(scheme_);
+      }
+    }
+  } else {
+    domain_ = domain;
+    port_ = GetDefaultPort(scheme_);
+  }
+}
+
+void URLImpl::ExtractPath() {
+  std::string sub_url =
+      url_.substr(scheme_.empty() ? 0 : scheme_.length() + kSchemeIdLen);
+  if (domain_.empty()) {
+    path_ = sub_url;
+  } else {
+    size_t start_of_path = sub_url.find_first_of('/');
+    if (start_of_path != std::string::npos)
+      path_ = sub_url.substr(start_of_path);
+  }
+}
+
+URL::URL(const std::string& url) {
+  impl_ = new URLImpl(url);
+}
+
+std::string URL::url() const {
+  return impl_->url();
+}
+std::string URL::scheme() const {
+  return impl_->scheme();
+}
+std::string URL::domain() const {
+  return impl_->domain();
+}
+int URL::port() const {
+  return impl_->port();
+}
+std::string URL::path() const {
+  return impl_->path();
+}
+
+URL::~URL() {
+  delete impl_;
+}
+
+}  // namespace common
diff --git a/tizen/common/url.h b/tizen/common/url.h
new file mode 100644 (file)
index 0000000..222e738
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_COMMON_URL_H_
+#define XWALK_COMMON_URL_H_
+
+#include <string>
+
+namespace common {
+
+class URLImpl;
+
+/*
+ * This class parses a given url based on its scheme type.
+ * The parsed data is stored in different variables depending on the scheme
+ * type.
+ * The following shows the variables which are used for each scheme type:
+ * http:// https:// ssh:// ftp://
+ *   => url_, scheme_, domain_, port_, path_
+ * app://
+ *   => url_, scheme_, domain_, path_
+ * file://
+ *   => url_, scheme_, path_
+ * No Scheme Type
+ *   => domain_, path_
+ *
+ * If the url does not have specific data, an empty string will be stored
+ * in the corresponding variables.(RFC 1738)
+ *
+ * ex) http://user:password@www.tizen.org:8080/market/Item?12345
+ * url_ = http://user:password@www.tizen.org:8080/market/Item?12345
+ * scheme_ = http
+ * user_ = user
+ * password_ = password
+ * domain_ = www.tizen.org
+ * port_ = 8080
+ * path_ = /market/Item?12345
+*/
+class URL {
+ public:
+  explicit URL(const std::string& url);
+  ~URL();
+
+  std::string url() const;
+  std::string scheme() const;
+  std::string domain() const;
+  int port() const;
+  std::string path() const;
+
+ private:
+  URLImpl* impl_;
+};
+
+}  // namespace common
+
+#endif  // XWALK_COMMON_URL_H_