Merge "[sensor] add getHardwareInfo()" into tizen_3.0
authorHyunJin Park <hj.na.park@samsung.com>
Fri, 29 Apr 2016 03:00:17 +0000 (12:00 +0900)
committerGerrit Code Review <gerrit@s001>
Fri, 29 Apr 2016 03:00:18 +0000 (12:00 +0900)
60 files changed:
packaging/webapi-plugins.spec
src/alarm/alarm_manager.cc
src/application/application.gyp
src/application/application_instance.cc
src/archive/archive_instance.cc
src/bluetooth/bluetooth_api.js
src/bluetooth/bluetooth_le_adapter.cc
src/bookmark/bookmark_instance.cc
src/common/common.gyp
src/common/tools.cc
src/common/tools.h
src/contact/contact_util.cc
src/contact/contact_util.h
src/contact/js/contact.js
src/datacontrol/datacontrol_api.js
src/datacontrol/datacontrol_instance.cc
src/feedback/feedback.gyp [new file with mode: 0644]
src/feedback/feedback_api.js [new file with mode: 0755]
src/feedback/feedback_extension.cc [new file with mode: 0755]
src/feedback/feedback_extension.h [new file with mode: 0755]
src/feedback/feedback_instance.cc [new file with mode: 0755]
src/feedback/feedback_instance.h [new file with mode: 0755]
src/feedback/feedback_manager.cc [new file with mode: 0644]
src/feedback/feedback_manager.h [new file with mode: 0644]
src/filesystem/filesystem_instance.cc
src/humanactivitymonitor/humanactivitymonitor_api.js
src/humanactivitymonitor/humanactivitymonitor_manager.cc
src/iotcon/iotcon_client_manager.cc
src/iotcon/iotcon_client_manager.h
src/iotcon/iotcon_instance.cc
src/iotcon/iotcon_server_manager.cc
src/iotcon/iotcon_server_manager.h
src/iotcon/iotcon_utils.cc
src/messageport/messageport_api.js
src/messaging/messaging_instance.cc
src/networkbearerselection/networkbearerselection_instance.cc
src/nfc/nfc_instance.cc
src/package/package_instance.cc
src/power/power_instance.cc
src/preference/preference.gyp [new file with mode: 0644]
src/preference/preference_api.js [new file with mode: 0644]
src/preference/preference_extension.cc [new file with mode: 0644]
src/preference/preference_extension.h [new file with mode: 0644]
src/preference/preference_instance.cc [new file with mode: 0644]
src/preference/preference_instance.h [new file with mode: 0644]
src/preference/preference_manager.cc [new file with mode: 0644]
src/preference/preference_manager.h [new file with mode: 0644]
src/sensor/sensor_service.cc
src/systemsetting/systemsetting_instance.cc
src/tizen-wrt.gyp
src/utils/utils_api.js
src/utils/utils_instance.cc
src/widgetservice/widgetservice.gyp [new file with mode: 0644]
src/widgetservice/widgetservice_api.js [new file with mode: 0755]
src/widgetservice/widgetservice_extension.cc [new file with mode: 0755]
src/widgetservice/widgetservice_extension.h [new file with mode: 0755]
src/widgetservice/widgetservice_instance.cc [new file with mode: 0755]
src/widgetservice/widgetservice_instance.h [new file with mode: 0755]
src/widgetservice/widgetservice_utils.cc [new file with mode: 0644]
src/widgetservice/widgetservice_utils.h [new file with mode: 0644]

index 1f81cab..1f2afdb 100644 (file)
@@ -10,7 +10,7 @@
 %define crosswalk_extensions_path %{_libdir}/%{crosswalk_extensions}
 
 Name:       webapi-plugins
-Version:    0.63
+Version:    0.70
 Release:    0
 License:    Apache-2.0 and BSD-2.0 and MIT
 Group:      Development/Libraries
@@ -51,6 +51,7 @@ Source0:    %{name}-%{version}.tar.gz
 %define tizen_feature_datasync_support                0
 %define tizen_feature_download_support                1
 %define tizen_feature_exif_support                    1
+%define tizen_feature_feedback_support                1
 %define tizen_feature_filesystem_support              1
 %define tizen_feature_fm_radio_support                1
 %if 0%{?tizen_is_emulator}
@@ -80,6 +81,7 @@ Source0:    %{name}-%{version}.tar.gz
 %define tizen_feature_notification_support            1
 %define tizen_feature_package_support                 1
 %define tizen_feature_power_support                   1
+%define tizen_feature_preference_support              1
 %define tizen_feature_push_support                    1
 %if 0%{?tizen_is_emulator}
 %define tizen_feature_se_support                      0
@@ -97,6 +99,7 @@ Source0:    %{name}-%{version}.tar.gz
 %endif
 %define tizen_feature_time_support                    1
 %define tizen_feature_web_setting_support             1
+%define tizen_feature_widget_service_support          0
 %if 0%{?tizen_is_emulator}
 %define tizen_feature_wi_fi_support                   0
 %else
@@ -157,6 +160,7 @@ Source0:    %{name}-%{version}.tar.gz
 %define tizen_feature_download_support                0
 %endif
 %define tizen_feature_exif_support                    1
+%define tizen_feature_feedback_support                1
 %define tizen_feature_filesystem_support              1
 %define tizen_feature_fm_radio_support                0
 %define tizen_feature_ham_support                     1
@@ -180,6 +184,7 @@ Source0:    %{name}-%{version}.tar.gz
 %define tizen_feature_notification_support            1
 %define tizen_feature_package_support                 1
 %define tizen_feature_power_support                   1
+%define tizen_feature_preference_support              1
 %define tizen_feature_push_support                    1
 %if 0%{?model_build_feature_smartcard }
 %define tizen_feature_se_support                      1
@@ -193,6 +198,7 @@ Source0:    %{name}-%{version}.tar.gz
 %define tizen_feature_telephony_support               0
 %define tizen_feature_time_support                    1
 %define tizen_feature_web_setting_support             0
+%define tizen_feature_widget_service_support          0
 %define tizen_feature_wi_fi_support                   1
 %define tizen_feature_inputdevice_support             1
 %define tizen_feature_tvinputdevice_support           0
@@ -233,6 +239,7 @@ Source0:    %{name}-%{version}.tar.gz
 %define tizen_feature_datasync_support                0
 %define tizen_feature_download_support                1
 %define tizen_feature_exif_support                    1
+%define tizen_feature_feedback_support                0
 %define tizen_feature_filesystem_support              1
 %define tizen_feature_fm_radio_support                0
 %define tizen_feature_ham_support                     0
@@ -248,6 +255,7 @@ Source0:    %{name}-%{version}.tar.gz
 %define tizen_feature_notification_support            0
 %define tizen_feature_package_support                 1
 %define tizen_feature_power_support                   0
+%define tizen_feature_preference_support              0
 %define tizen_feature_push_support                    0
 %define tizen_feature_se_support                      0
 %define tizen_feature_sensor_support                  0
@@ -257,12 +265,14 @@ Source0:    %{name}-%{version}.tar.gz
 %define tizen_feature_telephony_support               0
 %define tizen_feature_time_support                    1
 %define tizen_feature_web_setting_support             1
+%define tizen_feature_widget_service_support          0
 %define tizen_feature_wi_fi_support                   1
 %define tizen_feature_inputdevice_support             0
 %define tizen_feature_tvinputdevice_support           1
 
 %endif # tizen_profile_tv
 
+BuildRequires: pkgconfig(security-privilege-manager)
 BuildRequires: ninja
 BuildRequires: pkgconfig(appcore-common)
 BuildRequires: pkgconfig(dlog)
@@ -275,6 +285,7 @@ BuildRequires: pkgconfig(minizip)
 BuildRequires: pkgconfig(zlib)
 BuildRequires: pkgconfig(pkgmgr)
 BuildRequires: pkgconfig(pkgmgr-info)
+BuildRequires: pkgconfig(pkgmgr-installer)
 BuildRequires: pkgconfig(vconf)
 BuildRequires: pkgconfig(ecore)
 BuildRequires: pkgconfig(icu-i18n)
@@ -297,6 +308,7 @@ BuildRequires: pkgconfig(capi-appfw-package-manager)
 BuildRequires: pkgconfig(capi-content-media-content)
 BuildRequires: pkgconfig(capi-media-metadata-extractor)
 BuildRequires: pkgconfig(libtzplatform-config)
+BuildRequires: pkgconfig(widget_service)
 
 %if %{with wayland}
 %define display_type wayland
@@ -404,6 +416,10 @@ BuildRequires:  pkgconfig(capi-network-nfc)
 BuildRequires: pkgconfig(capi-media-radio)
 %endif
 
+%if 0%{?tizen_feature_feedback_support}
+BuildRequires: pkgconfig(feedback)
+%endif
+
 %if 0%{?tizen_feature_se_support}
 BuildRequires:  pkgconfig(smartcard-service)
 BuildRequires:  pkgconfig(smartcard-service-common)
@@ -469,6 +485,7 @@ GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datacontrol_support=%{?tizen_feature_d
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_datasync_support=%{?tizen_feature_datasync_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_download_support=%{?tizen_feature_download_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_exif_support=%{?tizen_feature_exif_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_feedback_support=%{?tizen_feature_feedback_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_filesystem_support=%{?tizen_feature_filesystem_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_fm_radio_support=%{?tizen_feature_fm_radio_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_ham_support=%{?tizen_feature_ham_support}"
@@ -485,6 +502,7 @@ GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_nfc_support=%{?tizen_feature_nfc_suppo
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_notification_support=%{?tizen_feature_notification_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_package_support=%{?tizen_feature_package_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_power_support=%{?tizen_feature_power_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_preference_support=%{?tizen_feature_preference_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_push_support=%{?tizen_feature_push_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sap_support=%{?tizen_feature_sap_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_sensor_support=%{?tizen_feature_sensor_support}"
@@ -496,6 +514,7 @@ GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_telephony_support=%{?tizen_feature_tel
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_time_support=%{?tizen_feature_time_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_inputdevice_support=%{?tizen_feature_inputdevice_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_web_setting_support=%{?tizen_feature_web_setting_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_widget_service_support=%{?tizen_feature_widget_service_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_wi_fi_support=%{?tizen_feature_wi_fi_support}"
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_tvinputdevice_support=%{?tizen_feature_tvinputdevice_support}"
 
index cd34104..5a66ba6 100755 (executable)
@@ -37,7 +37,7 @@ namespace alarm {
 
 namespace {
 const int kDateSize = 22; //"yyy mm dd hh mm ss dd" e.g 115 11 28 11 25 50 -1
-const std::string kPrivilegeAlarm = "http://tizen.org/privilege/alarm.get";
+const std::string kPrivilegeAlarm = "http://tizen.org/privilege/alarm";
 
 const std::string kAlarmRelative = "AlarmRelative";
 const std::string kAlarmAbsolute = "AlarmAbsolute";
index 24d8fbe..5199d22 100644 (file)
@@ -37,6 +37,7 @@
               'capi-appfw-package-manager',
               'pkgmgr',
               'pkgmgr-info',
+              'pkgmgr-installer',
             ]
           },
         }],
index 3364901..67ff539 100755 (executable)
@@ -28,10 +28,10 @@ namespace application {
 
 namespace {
 // The privileges that are required in Application API
-const std::string kPrivilegeAppManagerCertificate = "http://tizen.org/privilege/notexist";
+const std::string kPrivilegeAppManagerCertificate = "http://tizen.org/privilege/appmanager.certificate";
 const std::string kPrivilegeAppManagerKill = "http://tizen.org/privilege/appmanager.kill";
-const std::string kPrivilegeApplicationInfo = "http://tizen.org/privilege/packagemanager.info";
-const std::string kPrivilegeApplicationLaunch = "http://tizen.org/privilege/appmanager.launch";
+const std::string kPrivilegeApplicationInfo = "http://tizen.org/privilege/application.info";
+const std::string kPrivilegeApplicationLaunch = "http://tizen.org/privilege/application.launch";
 }  // namespace
 
 using namespace common;
index 8cf1af7..ce68703 100755 (executable)
@@ -38,8 +38,8 @@ using common::tools::ReportSuccess;
 using common::tools::ReportError;
 
 namespace {
-const std::string kPrivilegeFilesystemRead  = "http://tizen.org/privilege/systemsettings.admin";
-const std::string kPrivilegeFilesystemWrite  = "http://tizen.org/privilege/systemsettings.admin";
+const std::string kPrivilegeFilesystemRead  = "http://tizen.org/privilege/filesystem.read";
+const std::string kPrivilegeFilesystemWrite  = "http://tizen.org/privilege/filesystem.write";
 
 const std::string kArchiveFileEntryOptDest = "destination";
 const std::string kArchiveFileEntryOptStrip = "stripSourceDirectory";
index d1eaee4..06c5fe9 100755 (executable)
@@ -1370,6 +1370,9 @@ var _bleAdvertiseListener = _singleListenerBuilder('BluetoothLEAdvertiseCallback
     case 'onstate':
       if (successCallback) {
         successCallback(native.getResultObject(event));
+        if (native.getResultObject(event) == 'STOPPED') {
+          _bleAdvertiseListener.removeListener();
+        }
       }
       return ret;
 
@@ -1481,7 +1484,6 @@ BluetoothLEAdapter.prototype.startAdvertise = function() {
 BluetoothLEAdapter.prototype.stopAdvertise = function() {
   console.log('Entered BluetoothLEAdapter.stopAdvertise()');
 
-  _bleAdvertiseListener.removeListener();
   var result = native.callSync('BluetoothLEAdapter_stopAdvertise', {});
 
   if (native.isFailure(result)) {
index f34abd9..7447289 100755 (executable)
@@ -693,15 +693,6 @@ void BluetoothLEAdapter::StopAdvertise(const picojson::value& data, picojson::ob
       return;
     }
 
-    ret = bt_adapter_le_destroy_advertiser(bt_advertiser_);
-    if (BT_ERROR_NONE != ret && BT_ERROR_NOT_IN_PROGRESS != ret) {
-      LogAndReportError(
-          PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to destroy advertiser"), &out,
-          ("bt_adapter_le_destroy_advertiser() failed with: %d (%s)",
-            ret, get_error_message(ret)));
-      return;
-    }
-
     bt_advertiser_ = nullptr;
   } else {
     LoggerD("Advertising is not in progress");
@@ -790,6 +781,17 @@ void BluetoothLEAdapter::OnAdvertiseResult(
     LoggerD("Advertise state is: %s", state);
     data_obj->insert(std::make_pair(kAction, picojson::value(kOnAdvertiseState)));
     ReportSuccess(picojson::value(state), *data_obj);
+    if (adv_state == BT_ADAPTER_LE_ADVERTISING_STOPPED){
+      LoggerD("Advertiser destroy");
+      int  ret = bt_adapter_le_destroy_advertiser(advertiser);
+      if (BT_ERROR_NONE != ret && BT_ERROR_NOT_IN_PROGRESS != ret) {
+        LogAndReportError(
+            PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to destroy advertiser"), data_obj,
+            ("bt_adapter_le_destroy_advertiser() failed with: %d (%s)",
+              ret, get_error_message(ret)));
+        return;
+      }
+    }
   }
 
   adapter->instance_.FireEvent(kAdvertiseEvent, value);
index 14bd034..7f8e4bd 100755 (executable)
@@ -37,8 +37,8 @@ namespace {
   const char kParentId[] = "parentId";
   const char kUrl[] = "url";
 
-  const std::string kPrivilegeBookmarkRead = "http://tizen.org/privilege/bookmark.admin";
-  const std::string kPrivilegeBookmarkWrite = "http://tizen.org/privilege/bookmark.admin";
+  const std::string kPrivilegeBookmarkRead = "http://tizen.org/privilege/bookmark.read";
+  const std::string kPrivilegeBookmarkWrite = "http://tizen.org/privilege/bookmark.write";
 }  // namespace
 
 BookmarkInstance::BookmarkInstance() {
index f89186c..a4e9414 100644 (file)
@@ -74,6 +74,7 @@
               'capi-appfw-app-manager',
               'capi-appfw-package-manager',
               'storage',
+              'security-privilege-manager',
             ]
           },
           'conditions': [
index 9a8b8e0..9b46884 100644 (file)
 
 #include "common/tools.h"
 
+#include <privilegemgr/privilege_manager.h>
+#include <app_manager.h>
+#include <pkgmgr-info.h>
+
 #ifdef PRIVILEGE_USE_DB
 #include <sqlite3.h>
 #include "common/current_application.h"
@@ -253,20 +257,115 @@ class AccessControl {
 
 } // namespace
 
+
 PlatformResult CheckAccess(const std::string& privilege) {
   return CheckAccess(std::vector<std::string>{privilege});
 }
 
 PlatformResult CheckAccess(const std::vector<std::string>& privileges) {
   LoggerD("Enter");
-  if (AccessControl::GetInstance().CheckAccess(privileges)) {
-    return PlatformResult(ErrorCode::NO_ERROR);
-  } else {
-    for (const auto& privilege : privileges) {
-      LoggerD("Access to privilege: %s has been denied.", privilege.c_str());
+
+  std::string api_version;
+  PlatformResult res = common::tools::GetPkgApiVersion(&api_version);
+  if (res.IsError()) {
+    return res;
+  }
+  LoggerD("Application api version: %s", api_version.c_str());
+
+  for (auto input_priv : privileges) {
+    LoggerD("Input privilege: %s", input_priv.c_str());
+    GList *input_glist = nullptr;
+    GList *mapped_glist = nullptr;
+
+    SCOPE_EXIT {
+      g_list_free(input_glist);
+      g_list_free(mapped_glist);
+    };
+
+    input_glist = g_list_append(input_glist, (void*)input_priv.c_str());
+    int ret = privilege_manager_get_mapped_privilege_list(api_version.c_str(),
+                                                          PRVMGR_PACKAGE_TYPE_WRT,
+                                                          input_glist,
+                                                          &mapped_glist);
+    if (ret != PRVMGR_ERR_NONE) {
+      return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get mapped privilege list");
+    }
+
+    LoggerD("Mapped privileges:");
+    std::vector<std::string> mapped_vector;
+    auto push_elem = [](gpointer data, gpointer user_data) -> void {
+      if (data && user_data) {
+        std::vector<std::string>* mapped_vector =
+            static_cast<std::vector<std::string>*>(user_data);
+        char* char_data = static_cast<char*>(data);
+        mapped_vector->push_back(char_data);
+        LoggerD("mapped to: %s", char_data);
+      }
+    };
+    g_list_foreach (mapped_glist, push_elem, &mapped_vector);
+
+    if (!AccessControl::GetInstance().CheckAccess(mapped_vector)){
+      for (const auto& mapped_priv : mapped_vector) {
+        LoggerD("Access to privilege: %s has been denied.", mapped_priv.c_str());
+      }
+      return PlatformResult(ErrorCode::SECURITY_ERR, "Permission denied");
+    }
+  }
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult GetPkgApiVersion(std::string* api_version) {
+  LoggerD("Entered");
+
+  char* app_id = nullptr;
+  char* pkgid = nullptr;
+  char* api_ver = nullptr;
+  app_info_h app_handle = nullptr;
+  pkgmgrinfo_pkginfo_h pkginfo_handle = nullptr;
+
+  SCOPE_EXIT {
+    if (app_id) {
+      free(app_id);
     }
-    return PlatformResult(ErrorCode::SECURITY_ERR, "Permission denied");
+    if (pkgid) {
+      free(pkgid);
+    }
+    if (app_handle) {
+      app_info_destroy(app_handle);
+    }
+    if (pkginfo_handle) {
+      pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_handle);
+    }
+  };
+
+  pid_t pid = getpid();
+  int ret = app_manager_get_app_id(pid, &app_id);
+  if (ret != APP_MANAGER_ERROR_NONE) {
+    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get app id");
   }
+
+  ret = app_info_create(app_id, &app_handle);
+  if (ret != APP_MANAGER_ERROR_NONE) {
+    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get app info");
+  }
+
+  ret = app_info_get_package(app_handle, &pkgid);
+  if ((ret != APP_MANAGER_ERROR_NONE) || (pkgid == nullptr)) {
+    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get pkg id");
+  }
+
+  ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, getuid(), &pkginfo_handle);
+  if (ret != PMINFO_R_OK) {
+    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get pkginfo_h");
+  }
+
+  ret = pkgmgrinfo_pkginfo_get_api_version(pkginfo_handle, &api_ver);
+  if (ret != PMINFO_R_OK) {
+    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Fail to get api version");
+  }
+
+  *api_version = api_ver;
+  return PlatformResult(ErrorCode::NO_ERROR);
 }
 
 std::string GetErrorString(int error_code) {
index fcd9868..c3df3a9 100644 (file)
@@ -35,6 +35,7 @@ void ReportError(const PlatformResult& error, picojson::object* out);
 
 common::PlatformResult CheckAccess(const std::string& privilege);
 common::PlatformResult CheckAccess(const std::vector<std::string>& privileges);
+common::PlatformResult GetPkgApiVersion(std::string* api_version);
 
 #define CHECK_PRIVILEGE_ACCESS(privilege, out) \
 do { \
index 6e91ef0..cdc51a5 100755 (executable)
@@ -2367,6 +2367,86 @@ PlatformResult ExportNotesToContactsRecord(contacts_record_h contacts_record,
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
+PlatformResult ImportGroupIdsFromContactsRecord(
+    contacts_record_h contacts_record, unsigned int index, JsonValue* val) {
+
+  LoggerD("Enter");
+  // contacts_record is protected by unique_ptr and its ownership is not passed
+  // here
+  if (!contacts_record) {
+    LoggerE("Contacts record is null");
+    return PlatformResult(ErrorCode::UNKNOWN_ERR, "Contacts record is null");
+  }
+
+  contacts_record_h record = nullptr;
+  int err = contacts_record_get_child_record_at_p(
+      contacts_record, _contacts_contact.group_relation, index, &record);
+  if (CONTACTS_ERROR_NONE != err && CONTACTS_ERROR_NO_DATA != err) {
+    // ignoring this record
+    LoggerW("Skipping record with index %i. error code: %i", index, err);
+    return PlatformResult(ErrorCode::NO_ERROR);
+  }
+
+  int group_id = -1;
+  PlatformResult status =
+      ContactUtil::GetIntFromRecord(record, _contacts_group_relation.id, &group_id);
+  if (status.IsError()) {
+    LoggerE("Error: %s", status.message().c_str());
+    return status;
+  }
+
+  if (-1 == group_id) {
+    return PlatformResult(ErrorCode::UNKNOWN_ERR, "Fetching groupId failed");
+  }
+  *val = JsonValue{std::to_string(group_id)};
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult ExportGroupIdsToContactsRecord(contacts_record_h contacts_record,
+                                           int value) {
+
+  LoggerD("Enter");
+  contacts_record_h notes_record = nullptr;
+  // contacts_record is protected by unique_ptr and its ownership is not passed
+  // here
+  if (!contacts_record) {
+    LoggerE("Contacts record is null");
+    return PlatformResult(ErrorCode::UNKNOWN_ERR, "Contacts record is null");
+  }
+
+  int err = contacts_record_create(_contacts_group_relation._uri, &notes_record);
+  PlatformResult status =
+      ContactUtil::ErrorChecker(err, "Fail to create note record in database");
+  if (status.IsError()) {
+    LoggerE("Error: %s", status.message().c_str());
+    return status;
+  }
+
+  ContactsRecordHPtr record(&notes_record, ContactsDeleter);
+
+  status = ContactUtil::SetIntInRecord(notes_record, _contacts_group_relation.group_id,
+                                       value);
+  if (status.IsError()) {
+    LoggerE("Error: %s", status.message().c_str());
+    return status;
+  }
+
+  err = contacts_record_add_child_record(contacts_record,
+                                         _contacts_contact.group_relation, notes_record);
+  status =
+      ContactUtil::ErrorChecker(err, "Fail to save note record in database");
+  if (status.IsError()) {
+    LoggerE("Error: %s", status.message().c_str());
+    return status;
+  }
+
+  // Do not delete record, it is passed to the platform
+  record.release();
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
 PlatformResult ImportContactFromContactsRecord(
     contacts_record_h contacts_record, JsonObject* out_ptr) {
 
@@ -2593,6 +2673,29 @@ PlatformResult ImportContactFromContactsRecord(
             "vibrationURI",
             value ? JsonValue{ConvertPathToUri(value)} : JsonValue{}));
     value = nullptr;
+
+    //### groupIds: ###
+    JsonArray& group_ids = out.insert(std::make_pair(std::string("groupIds"),
+        picojson::value(JsonArray()))).first->second.get<JsonArray>();
+
+    status = ContactUtil::GetNumberOfChildRecord(
+        contacts_record, _contacts_contact.group_relation, &child_rec_count);
+    if (status.IsError()) {
+      LoggerE("Error: %s", status.message().c_str());
+      return status;
+    }
+
+    for (int i = 0; i < child_rec_count; ++i) {
+      JsonValue val{JsonObject{}};
+
+      status = ImportGroupIdsFromContactsRecord(contacts_record, static_cast<unsigned int>(i), &val);
+      if (status.IsError()) {
+        LoggerE("Error: %s", status.message().c_str());
+        return status;
+      }
+
+      group_ids.push_back(val);
+    }
   }
 
   return PlatformResult(ErrorCode::NO_ERROR);
@@ -2782,6 +2885,26 @@ PlatformResult ExportContactToContactsRecord(contacts_record_h contacts_record,
     }
   }
 
+  {
+    //### groupIds: ###
+    PlatformResult status = ContactUtil::ClearAllContactRecord(
+        contacts_record, _contacts_contact.group_relation);
+    if (status.IsError()) {
+      LoggerE("Error: %s", status.message().c_str());
+      return status;
+    }
+
+    const JsonArray& elements = FromJson<JsonArray>(in, "groupIds");
+    for (auto& element : elements) {
+      auto& str = JsonCast<JsonString>(element);
+      if (str.empty()) {
+        continue;
+      }
+      ExportGroupIdsToContactsRecord(contacts_record, atoi(str.c_str()));
+    }
+  }
+
+
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
index 9e7b985..471d124 100644 (file)
@@ -132,6 +132,10 @@ common::PlatformResult ImportContactNotesFromContactsRecord(
     contacts_record_h contacts_record, unsigned int index, JsonValue *val);
 common::PlatformResult ExportNotesToContactsRecord(
     contacts_record_h contacts_record, const std::string &value);
+common::PlatformResult ImportGroupIdsFromContactsRecord(
+    contacts_record_h contacts_record, unsigned int index, JsonValue *val);
+common::PlatformResult ExportGroupIdsToContactsRecord(
+    contacts_record_h contacts_record, int value);
 common::PlatformResult ImportContactFromContactsRecord(
     contacts_record_h contacts_record, JsonObject *out);
 common::PlatformResult ExportPersonToContactsRecord(contacts_record_h record,
index 1db49ff..bb2f168 100755 (executable)
@@ -70,9 +70,7 @@ var Contact = function(data) {
     }
     for (var i = 0; i < arr.length; ++i) {
       if (type_.isString(type)) {
-        if (!type_.isString(arr[i])) {
-          return previousValue;
-        }
+        arr[i] = converter_.toString(arr[i]);
       } else if (_editGuard.isEditEnabled()) {
         arr[i] = new type(arr[i]);
       } else if (!(arr[i] instanceof type)) {
index 98b7559..5583184 100755 (executable)
@@ -112,7 +112,6 @@ DataControlManager.prototype.getDataControlConsumer = function(providerId, dataI
   return getDataControlConsumer.apply(null, arguments);
 };
 
-
 function DataControlConsumerObject() {
   // constructor of DataControlConsumerObject
 }
@@ -134,11 +133,17 @@ SQLDataControlConsumer.prototype.insert = function(reqId, insertionData) {
     {'name': 'errorCallback', 'type': types_.FUNCTION, optional: true, nullable: true}
   ]);
 
+  // doing conversion of all elements to string
+  var ins = validator_.validateArgs([args.insertionData.columns, args.insertionData.values], [
+    {name : 'columns', type : types_.ARRAY, values : types_.STRING},
+    {name : 'values', type : types_.ARRAY, values : types_.STRING}
+  ]);
+
   var nativeParam = {
     'providerId': this.providerId,
     'dataId': this.dataId,
     'reqId': args.reqId,
-    'insertionData': insertionData
+    'insertionData': args.insertionData
   };
   try {
     var syncResult =
index 8e6c258..cfb1521 100755 (executable)
@@ -37,7 +37,7 @@ namespace datacontrol {
 
 namespace {
 // The privileges that required in Datacontrol API
-const std::string kPrivilegeDatacontrol = "http://tizen.org/privilege/datasharing";
+const std::string kPrivilegeDatacontrol = "http://tizen.org/privilege/datacontrol.consumer";
 
 }  // namespace
 
@@ -565,10 +565,13 @@ void DatacontrolInstance::SQLDataControlConsumerInsert(
         break;
       }
 
-      std::string& columnName = column.get<std::string>();
-      std::string valueString = value.get<std::string>();
+      const std::string& columnName = column.get<std::string>();
+      const std::string& valueString = value.get<std::string>();
 
-      bundle_add_str(b, columnName.c_str(), valueString.c_str());
+      int result = bundle_add_str(b, columnName.c_str(), valueString.c_str());
+      if (BUNDLE_ERROR_NONE != result) {
+        return result;
+      }
     }
 
     return ::data_control_sql_insert(handle, b, requestId);
diff --git a/src/feedback/feedback.gyp b/src/feedback/feedback.gyp
new file mode 100644 (file)
index 0000000..b45c463
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  'includes':[
+    '../common/common.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'tizen_feedback',
+      'type': 'loadable_module',
+      'dependencies': [
+        '../common/common.gyp:tizen_common',
+      ],
+      'sources': [
+        'feedback_api.js',
+        'feedback_extension.cc',
+        'feedback_extension.h',
+        'feedback_instance.cc',
+        'feedback_instance.h',
+        'feedback_manager.cc',
+        'feedback_manager.h'
+      ],
+      'conditions': [
+        ['tizen == 1', {
+          'variables': {
+            'packages': [
+              'feedback'
+            ]
+          },
+        }],
+      ],
+    },
+  ],
+}
diff --git a/src/feedback/feedback_api.js b/src/feedback/feedback_api.js
new file mode 100755 (executable)
index 0000000..5f09d0f
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * 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.
+ */
+var validator_ = xwalk.utils.validator;
+var types_ = validator_.Types;
+var type_ = xwalk.utils.type;
+var native_ = new xwalk.utils.NativeManager(extension);
+
+var ExceptionMap = {
+  'UnknownError' : WebAPIException.UNKNOWN_ERR,
+  'TypeMismatchError' : WebAPIException.TYPE_MISMATCH_ERR,
+  'InvalidValuesError' : WebAPIException.INVALID_VALUES_ERR,
+  'IOError' : WebAPIException.IO_ERR,
+  'ServiceNotAvailableError' : WebAPIException.SERVICE_NOT_AVAILABLE_ERR,
+  'SecurityError' : WebAPIException.SECURITY_ERR,
+  'NetworkError' : WebAPIException.NETWORK_ERR,
+  'NotSupportedError' : WebAPIException.NOT_SUPPORTED_ERR,
+  'NotFoundError' : WebAPIException.NOT_FOUND_ERR,
+  'InvalidAccessError' : WebAPIException.INVALID_ACCESS_ERR,
+  'AbortError' : WebAPIException.ABORT_ERR,
+  'QuotaExceededError' : WebAPIException.QUOTA_EXCEEDED_ERR
+};
+
+function callNative(cmd, args) {
+  var json = {'cmd': cmd, 'args': args};
+  var argjson = JSON.stringify(json);
+  var resultString = extension.internal.sendSyncMessage(argjson);
+  var result = JSON.parse(resultString);
+
+  if (typeof result !== 'object') {
+    throw new WebAPIException(WebAPIException.UNKNOWN_ERR);
+  }
+
+  if (result['status'] == 'success') {
+    if (result['result']) {
+      return result['result'];
+    }
+    return true;
+  }
+  else if (result['status'] == 'error') {
+    var err = result['error'];
+    if (err) {
+      if (ExceptionMap[err.name]) {
+        throw new WebAPIException(ExceptionMap[err.name], err.message);
+      } else {
+        throw new WebAPIException(WebAPIException.UNKNOWN_ERR, err.message);
+      }
+    }
+    return false;
+  }
+}
+
+function SetReadOnlyProperty(obj, n, v) {
+  Object.defineProperty(obj, n, {value: v, writable: false});
+}
+
+var FeedbackType = {
+    TYPE_SOUND: 'TYPE_SOUND',
+    TYPE_VIBRATION: 'TYPE_VIBRATION',
+    NONE: 'NONE'
+}
+
+var FeedbackPattern = {
+  TAP: 'TAP',
+  SIP: 'SIP',
+  KEY0: 'KEY0',
+  KEY1: 'KEY1',
+  KEY2: 'KEY2',
+  KEY3: 'KEY3',
+  KEY4: 'KEY4',
+  KEY5: 'KEY5',
+  KEY6: 'KEY6',
+  KEY7: 'KEY7',
+  KEY8: 'KEY8',
+  KEY9: 'KEY9',
+  KEY_STAR: 'KEY_STAR',
+  KEY_SHARP: 'KEY_SHARP',
+  KEY_BACK: 'KEY_BACK',
+  HOLD: 'HOLD',
+  HW_TAP: 'HW_TAP',
+  HW_HOLD: 'HW_HOLD',
+  MESSAGE: 'MESSAGE',
+  EMAIL: 'EMAIL',
+  WAKEUP: 'WAKEUP',
+  SCHEDULE: 'SCHEDULE',
+  TIMER: 'TIMER',
+  GENERAL: 'GENERAL',
+  POWERON: 'POWERON',
+  POWEROFF: 'POWEROFF',
+  CHARGERCONN: 'CHARGERCONN',
+  CHARGING_ERROR: 'CHARGING_ERROR',
+  FULLCHARGED: 'FULLCHARGED',
+  LOWBATT: 'LOWBATT',
+  LOCK: 'LOCK',
+  UNLOCK: 'UNLOCK',
+  VIBRATION_ON: 'VIBRATION_ON',
+  SILENT_OFF: 'SILENT_OFF',
+  BT_CONNECTED: 'BT_CONNECTED',
+  BT_DISCONNECTED: 'BT_DISCONNECTED',
+  LIST_REORDER: 'LIST_REORDER',
+  LIST_SLIDER: 'LIST_SLIDER',
+  VOLUME_KEY: 'VOLUME_KEY'
+  };
+
+function FeedbackManager() {
+  // constructor of FeedbackManager
+}
+
+
+FeedbackManager.prototype.isPatternSupported = function(pattern, type) {
+  var args = validator_.validateArgs(arguments, [
+    {name: 'pattern', type: types_.ENUM, values: Object.keys(FeedbackPattern)},
+    {name: 'type', type: types_.ENUM, values: Object.keys(FeedbackType)},
+  ]);
+
+  if ('' === args.pattern) {
+    throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
+                              'Pattern name cannot be empty.');
+  }
+
+  if ('' === args.type) {
+    throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
+                              'Pattern type name cannot be empty.');
+  }
+
+    var result = callNative('FeedbackManager_isPatternSupported', args);
+
+    if (native_.isFailure(result)) {
+      throw native_.getErrorObject(result);
+    }
+    return native_.getResultObject(result);
+};
+
+FeedbackManager.prototype.play = function(pattern, type) {
+  var args = validator_.validateArgs(arguments, [
+    {name: 'pattern', type: types_.ENUM, values: Object.keys(FeedbackPattern)},
+    {name: 'type', type: types_.ENUM, values: Object.keys(FeedbackType), 'optional' : true},
+  ]);
+
+  if ('' === args.pattern) {
+    throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
+                              'Pattern name cannot be empty.');
+  }
+  if ('' === args.type) {
+    throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
+                              'Pattern type name cannot be empty.');
+  }
+
+  var nativeParam = {
+      'pattern': args.pattern,
+      'type': args.type ? args.type : 'any'
+    };
+
+  var result = callNative('FeedbackManager_play', nativeParam);
+
+  if (native_.isFailure(result)) {
+    throw native_.getErrorObject(result);
+  }
+  return;
+};
+
+FeedbackManager.prototype.stop = function() {
+  native_.removeListener(TAG_LISTENER);
+
+  var result = callNative('FeedbackManager_stop');
+  if (native_.isFailure(result)) {
+    throw native_.getErrorObject(result);
+  }
+  return;
+};
+
+exports = new FeedbackManager();
diff --git a/src/feedback/feedback_extension.cc b/src/feedback/feedback_extension.cc
new file mode 100755 (executable)
index 0000000..7e686ea
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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 "feedback/feedback_extension.h"
+
+#include "feedback/feedback_instance.h"
+
+// This will be generated from feedback_api.js
+extern const char kSource_feedback_api[];
+
+common::Extension* CreateExtension() {
+  return new FeedbackExtension;
+}
+
+FeedbackExtension::FeedbackExtension() {
+  SetExtensionName("tizen.feedback");
+  SetJavaScriptAPI(kSource_feedback_api);
+}
+
+FeedbackExtension::~FeedbackExtension() {}
+
+common::Instance* FeedbackExtension::CreateInstance() {
+  return new extension::feedback::FeedbackInstance;
+}
diff --git a/src/feedback/feedback_extension.h b/src/feedback/feedback_extension.h
new file mode 100755 (executable)
index 0000000..f115a89
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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 FEEDBACK_FEEDBACK_EXTENSION_H_
+#define FEEDBACK_FEEDBACK_EXTENSION_H_
+
+#include "common/extension.h"
+
+class FeedbackExtension : public common::Extension {
+ public:
+  FeedbackExtension();
+  virtual ~FeedbackExtension();
+
+ private:
+  virtual common::Instance* CreateInstance();
+};
+
+#endif  // FEEDBACK_FEEDBACK_EXTENSION_H_
diff --git a/src/feedback/feedback_instance.cc b/src/feedback/feedback_instance.cc
new file mode 100755 (executable)
index 0000000..ee04359
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * 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 "feedback/feedback_instance.h"
+#include "feedback_manager.h"
+
+#include <functional>
+#include <string>
+
+#include "common/picojson.h"
+#include "common/logger.h"
+#include "common/picojson.h"
+#include "common/platform_exception.h"
+#include "common/platform_result.h"
+#include "common/tools.h"
+
+namespace extension {
+namespace feedback {
+
+using namespace common;
+
+using common::TypeMismatchException;
+using common::InvalidValuesException;
+using common::UnknownException;
+using common::NotFoundException;
+using common::QuotaExceededException;
+
+namespace {
+const std::string kPrivilegeHaptic = "http://tizen.org/privilege/haptic";
+} //namespace
+
+FeedbackInstance::FeedbackInstance()
+    : m_feedbackMapsPtr(new FeedbackMaps),
+      m_feedbackManagerPtr(new FeedbackManager(this->m_feedbackMapsPtr))
+  {
+  LoggerD("Enter");
+  using std::placeholders::_1;
+  using std::placeholders::_2;
+  #define REGISTER_SYNC(c, x) \
+    RegisterSyncHandler(c, std::bind(&FeedbackInstance::x, this, _1, _2));
+  REGISTER_SYNC("FeedbackManager_isPatternSupported",
+                IsPatternSupported);
+  REGISTER_SYNC("FeedbackManager_play",
+                Play);
+  REGISTER_SYNC("FeedbackManager_stop",
+                Stop);
+  #undef REGISTER_SYNC
+}
+
+FeedbackInstance::~FeedbackInstance() {
+  LoggerD("Enter");
+}
+
+void FeedbackInstance::IsPatternSupported
+  (const picojson::value& args, picojson::object& out) {
+  LoggerD("Enter");
+
+  const auto pattern = args.get("pattern").get<std::string>();
+  const auto type = args.get("type").get<std::string>();
+
+  bool patternStatus = false;
+  PlatformResult result =
+      m_feedbackManagerPtr->isPatternSupported(pattern, type, &patternStatus);
+  if (result.IsSuccess()) {
+    ReportSuccess(picojson::value(patternStatus), out);
+  } else {
+    LogAndReportError(result, &out);
+  }
+}
+
+void FeedbackInstance::Play
+  (const picojson::value& args, picojson::object& out) {
+  LoggerD("Enter");
+
+  CHECK_PRIVILEGE_ACCESS(kPrivilegeHaptic, &out);
+
+  const auto pattern = args.get("pattern").get<std::string>();
+  const auto type = args.get("type").get<std::string>();
+
+  PlatformResult result =
+      m_feedbackManagerPtr->play(pattern, type);
+  if (result.IsSuccess()) {
+    ReportSuccess(out);
+  } else {
+    LogAndReportError(result, &out);
+  }
+}
+
+void FeedbackInstance::Stop
+  (const picojson::value& args, picojson::object& out) {
+  LoggerD("Enter");
+
+  CHECK_PRIVILEGE_ACCESS(kPrivilegeHaptic, &out);
+
+  PlatformResult result =
+      m_feedbackManagerPtr->stop();
+  if (result.IsSuccess()) {
+    ReportSuccess(out);
+  } else {
+    LogAndReportError(result, &out);
+  }
+}
+
+#undef CHECK_EXIST
+
+}  // namespace messageport
+}  // namespace extension
diff --git a/src/feedback/feedback_instance.h b/src/feedback/feedback_instance.h
new file mode 100755 (executable)
index 0000000..98f4bda
--- /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 FEEDBACK_FEEDBACK_INSTANCE_H_
+#define FEEDBACK_FEEDBACK_INSTANCE_H_
+
+#include "common/extension.h"
+#include <memory>
+
+namespace extension {
+namespace feedback {
+
+class FeedbackMaps;
+class FeedbackManager;
+
+class FeedbackInstance : public common::ParsedInstance {
+ public:
+  FeedbackInstance();
+  virtual ~FeedbackInstance();
+
+ private:
+  std::shared_ptr<FeedbackMaps> m_feedbackMapsPtr;
+  std::unique_ptr<FeedbackManager> m_feedbackManagerPtr;
+  void IsPatternSupported
+    (const picojson::value& args, picojson::object& out);
+  void Play
+    (const picojson::value& args, picojson::object& out);
+  void Stop
+    (const picojson::value& args, picojson::object& out);
+};
+
+}  // namespace feedback
+}  // namespace extension
+
+#endif  // FEEDBACK_FEEDBACK_INSTANCE_H_
diff --git a/src/feedback/feedback_manager.cc b/src/feedback/feedback_manager.cc
new file mode 100644 (file)
index 0000000..381ecb5
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * 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 <string>
+#include <feedback/feedback_manager.h>
+
+#include "common/assert.h"
+#include "common/converter.h"
+#include "common/extension.h"
+#include "common/logger.h"
+#include "common/platform_exception.h"
+#include "common/picojson.h"
+#include "common/platform_result.h"
+#include "common/tools.h"
+
+using namespace common;
+using namespace std;
+using common::tools::ReportError;
+
+namespace extension {
+namespace feedback {
+
+FeedbackMaps::FeedbackMaps() :
+  mTypeMap{
+    {"TYPE_SOUND", FEEDBACK_TYPE_SOUND},
+    {"TYPE_VIBRATION", FEEDBACK_TYPE_VIBRATION}
+  },
+  mPatternMap{
+    {"TAP", FEEDBACK_PATTERN_TAP},
+    {"SIP", FEEDBACK_PATTERN_SIP},
+    {"KEY0", FEEDBACK_PATTERN_KEY0},
+    {"KEY1", FEEDBACK_PATTERN_KEY1},
+    {"KEY2", FEEDBACK_PATTERN_KEY2},
+    {"KEY3", FEEDBACK_PATTERN_KEY3},
+    {"KEY4", FEEDBACK_PATTERN_KEY4},
+    {"KEY5", FEEDBACK_PATTERN_KEY5},
+    {"KEY6", FEEDBACK_PATTERN_KEY6},
+    {"KEY7", FEEDBACK_PATTERN_KEY7},
+    {"KEY8", FEEDBACK_PATTERN_KEY8},
+    {"KEY9", FEEDBACK_PATTERN_KEY9},
+    {"KEY_STAR", FEEDBACK_PATTERN_KEY_STAR},
+    {"KEY_SHARP", FEEDBACK_PATTERN_KEY_SHARP},
+    {"KEY_BACK", FEEDBACK_PATTERN_KEY_BACK},
+    {"HOLD", FEEDBACK_PATTERN_HOLD},
+    {"HW_TAP", FEEDBACK_PATTERN_HW_TAP},
+    {"HW_HOLD", FEEDBACK_PATTERN_HW_HOLD},
+    {"MESSAGE", FEEDBACK_PATTERN_MESSAGE},
+    {"EMAIL", FEEDBACK_PATTERN_EMAIL},
+    {"WAKEUP", FEEDBACK_PATTERN_WAKEUP},
+    {"SCHEDULE", FEEDBACK_PATTERN_SCHEDULE},
+    {"TIMER", FEEDBACK_PATTERN_TIMER},
+    {"GENERAL", FEEDBACK_PATTERN_GENERAL},
+    {"POWERON", FEEDBACK_PATTERN_POWERON},
+    {"POWEROFF", FEEDBACK_PATTERN_POWEROFF},
+    {"CHARGERCONN", FEEDBACK_PATTERN_CHARGERCONN},
+    {"CHARGING_ERROR", FEEDBACK_PATTERN_CHARGING_ERROR},
+    {"FULLCHARGED", FEEDBACK_PATTERN_FULLCHARGED},
+    {"LOWBATT", FEEDBACK_PATTERN_LOWBATT},
+    {"LOCK", FEEDBACK_PATTERN_LOCK},
+    {"UNLOCK", FEEDBACK_PATTERN_UNLOCK},
+    {"VIBRATION_ON", FEEDBACK_PATTERN_VIBRATION_ON},
+    {"SILENT_OFF", FEEDBACK_PATTERN_SILENT_OFF},
+    {"BT_CONNECTED", FEEDBACK_PATTERN_BT_CONNECTED},
+    {"BT_DISCONNECTED", FEEDBACK_PATTERN_BT_DISCONNECTED},
+    {"LIST_REORDER", FEEDBACK_PATTERN_LIST_REORDER},
+    {"LIST_SLIDER", FEEDBACK_PATTERN_LIST_SLIDER},
+    {"VOLUME_KEY", FEEDBACK_PATTERN_VOLUME_KEY}
+  }
+{};
+
+FeedbackMaps::~FeedbackMaps()
+{}
+
+feedback_pattern_e const & FeedbackMaps::getPatternFromMap(const std::string& pattern) {
+  return mPatternMap[pattern];
+}
+
+feedback_type_e const & FeedbackMaps::getTypeFromMap(const std::string& type) {
+  return mTypeMap[type];
+}
+
+FeedbackManager::FeedbackManager(std::shared_ptr<FeedbackMaps> maps)
+  : m_feedbackMapsPtr(maps)
+{
+  LoggerD("Entered");
+  // feedback API initialization
+  int ret = feedback_initialize();
+  if(ret != FEEDBACK_ERROR_NONE) {
+    LoggerE("Could not initialize Feedback Manager, error: %d", ret);
+  }
+
+}
+
+FeedbackManager::~FeedbackManager() {
+  LoggerD("Entered");
+
+  // feedback library deinitialization
+  int ret = feedback_deinitialize();
+  if(ret != FEEDBACK_ERROR_NONE) {
+    LoggerE("Could not deinitialize Feedback Manager, error: %d", ret);
+  }
+}
+
+common::PlatformResult
+FeedbackManager::isPatternSupported(const std::string &pattern, const std::string &type, bool* patternStatus) {
+  LoggerD("Entered");
+  int ret = feedback_is_supported_pattern(
+    m_feedbackMapsPtr->getTypeFromMap(type),
+    m_feedbackMapsPtr->getPatternFromMap(pattern),
+    patternStatus
+    );
+  if(ret != FEEDBACK_ERROR_NONE) {
+    LoggerE("isPatternSupported failed: %d", ret);
+    return CodeToResult(ret, getFeedbackErrorMessage(ret).c_str());
+    }
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+common::PlatformResult FeedbackManager::play(const std::string &pattern, const std::string &type) {
+  LoggerD("Entered");
+  int ret = 0;
+  if(type == "any") {
+    ret = feedback_play(m_feedbackMapsPtr->getPatternFromMap(pattern));
+  } else {
+    ret = feedback_play_type(m_feedbackMapsPtr->getTypeFromMap(type),
+        m_feedbackMapsPtr->getPatternFromMap(pattern));
+  }
+  if(ret != FEEDBACK_ERROR_NONE) {
+    LoggerE("play failed: %d", ret);
+    return CodeToResult(ret, getFeedbackErrorMessage(ret).c_str());
+    }
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+common::PlatformResult FeedbackManager::stop() {
+  LoggerD("Entered");
+  int ret = feedback_stop();
+  if(ret != FEEDBACK_ERROR_NONE && ret != FEEDBACK_ERROR_NOT_SUPPORTED) {
+    LoggerE("stop failed: %d", ret);
+    return CodeToResult(ret, getFeedbackErrorMessage(ret).c_str());
+    }
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult FeedbackManager::CodeToResult(const int errorCode,
+                                     const std::string& message) {
+  LoggerD("Entered");
+  switch(errorCode) {
+    case FEEDBACK_ERROR_INVALID_PARAMETER:
+      return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, message);
+    case FEEDBACK_ERROR_OPERATION_FAILED:
+      return LogAndCreateResult(ErrorCode::SECURITY_ERR, message);
+    case FEEDBACK_ERROR_NOT_SUPPORTED:
+      return LogAndCreateResult(ErrorCode::NOT_SUPPORTED_ERR, message);
+    case FEEDBACK_ERROR_NOT_INITIALIZED:
+    default:
+      return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, message);
+  }
+}
+
+const std::string FeedbackManager::getFeedbackErrorMessage(const int error_code) {
+  LoggerD("Error code : %d", error_code);
+  switch(error_code) {
+    case FEEDBACK_ERROR_OPERATION_FAILED:
+      return "Operation not permitted";
+    case FEEDBACK_ERROR_INVALID_PARAMETER:
+      return "Invalid parameter";
+    case FEEDBACK_ERROR_NOT_SUPPORTED:
+      return "Not supported device";
+    case FEEDBACK_ERROR_NOT_INITIALIZED:
+      return "Not initialized";
+    default:
+      return "UnknownError";
+  }
+}
+
+}// feedback
+}// extension
diff --git a/src/feedback/feedback_manager.h b/src/feedback/feedback_manager.h
new file mode 100644 (file)
index 0000000..471ab7c
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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 FEEDBACK_MANAGER_H_
+#define FEEDBACK_MANAGER_H_
+
+#include "common/picojson.h"
+#include "common/platform_result.h"
+
+#include <feedback.h>
+#include <memory>
+#include <string>
+
+namespace extension {
+namespace feedback {
+
+using stringPatternMap = std::map<std::string, feedback_pattern_e>;
+using stringTypeMap = std::map<std::string, feedback_type_e>;
+
+class FeedbackMaps {
+ public:
+  FeedbackMaps();
+  virtual ~FeedbackMaps();
+  feedback_pattern_e const & getPatternFromMap(const std::string& pattern);
+  feedback_type_e const & getTypeFromMap(const std::string& type);
+ private:
+  stringTypeMap mTypeMap;
+  stringPatternMap mPatternMap;
+};
+
+class FeedbackManager {
+ public:
+  FeedbackManager(std::shared_ptr<FeedbackMaps> maps);
+  virtual ~FeedbackManager();
+
+  common::PlatformResult isPatternSupported(
+      const std::string &pattern, const std::string &type, bool* patternStatus);
+  common::PlatformResult play(const std::string &pattern, const std::string &type);
+  common::PlatformResult stop();
+ private:
+  const std::string getFeedbackErrorMessage(const int error_code);
+  common::PlatformResult CodeToResult(
+      const int errorCode, const std::string& message);
+  std::shared_ptr<FeedbackMaps> m_feedbackMapsPtr;
+};
+
+} // feedback
+} // extension
+
+#endif // FEEDBACK_MANAGER_H_
index df1d003..54b0a2e 100644 (file)
@@ -30,8 +30,8 @@ namespace filesystem {
 
 namespace {
 // The privileges that required in Filesystem API
-const std::string kPrivilegeFilesystemRead = "http://tizen.org/privilege/systemsettings.admin";
-const std::string kPrivilegeFilesystemWrite = "http://tizen.org/privilege/systemsettings.admin";
+const std::string kPrivilegeFilesystemRead = "http://tizen.org/privilege/filesystem.read";
+const std::string kPrivilegeFilesystemWrite = "http://tizen.org/privilege/filesystem.write";
 }
 
 using namespace common;
index e71b6a7..d78c2ad 100755 (executable)
@@ -225,10 +225,18 @@ function pedometerCallback(result) {
   }
 }
 
+var GPSListener = null;
+function GPSCallback(result) {
+  if (GPSListener) {
+    GPSListener(result);
+  }
+}
+
 HumanActivityMonitorManager.prototype.start = function(type, changedCallback) {
   var args = validator_.validateArgs(arguments, [
     {name: 'type', type: types_.ENUM, values: Object.keys(HumanActivityType)},
     {name: 'changedCallback', type: types_.FUNCTION, optional: true, nullable: true},
+    {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true},
     {name : 'option', type : types_.DICTIONARY, optional : true, nullable : true}
   ]);
 
@@ -238,17 +246,9 @@ HumanActivityMonitorManager.prototype.start = function(type, changedCallback) {
   switch (args.type) {
   case HumanActivityType.GPS:
     callbackInterval = !type_.isNullOrUndefined(args.option) ?
-        args.option.callbackInterval : 120000;
+        args.option.callbackInterval : 150000;
     sampleInterval = !type_.isNullOrUndefined(args.option) ?
         args.option.sampleInterval : 1000;
-    if (callbackInterval < 120000 || callbackInterval > 600000) {
-      throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
-                                'callbackInterval is out of range');
-    }
-    if (sampleInterval < 1000 || sampleInterval > 120000) {
-      throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR,
-                                'sampleInterval is out of range');
-    }
     break;
   case HumanActivityType.HRM:
     callbackInterval = !type_.isNullOrUndefined(args.option) ?
@@ -260,9 +260,19 @@ HumanActivityMonitorManager.prototype.start = function(type, changedCallback) {
     break;
   }
 
-  var listener = HumanActivityType.PEDOMETER === args.type ? pedometerCallback : function(result) {
-    native_.callIfPossible(args.changedCallback, convertActivityData(args.type, result));
-  };
+  var listener = null;
+  switch (args.type) {
+    case HumanActivityType.PEDOMETER:
+      listener = pedometerCallback;
+      break;
+    case HumanActivityType.GPS:
+      listener = GPSCallback;
+      break;
+    default:
+      listener = function(result) {
+        native_.callIfPossible(args.changedCallback, convertActivityData(args.type, result));
+      };
+  }
 
   console.log("callbackInterval = " + callbackInterval + ", sampleInterval = " + sampleInterval);
   startListener(listenerId,
@@ -278,6 +288,18 @@ HumanActivityMonitorManager.prototype.start = function(type, changedCallback) {
   if (HumanActivityType.PEDOMETER === args.type) {
     pedometerListener = args.changedCallback;
   }
+
+  if (HumanActivityType.GPS === args.type) {
+    var callback = function(result) {
+      if (native_.isFailure(result)) {
+        native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
+      } else {
+        native_.callIfPossible(args.changedCallback, convertActivityData(args.type, result));
+      }
+    };
+
+    GPSListener = callback;
+  }
 };
 
 HumanActivityMonitorManager.prototype.stop = function(type) {
@@ -292,6 +314,10 @@ HumanActivityMonitorManager.prototype.stop = function(type) {
   if (HumanActivityType.PEDOMETER === args.type) {
     pedometerListener = null;
   }
+
+  if (HumanActivityType.GPS === args.type) {
+    GPSListener = null;
+  }
 };
 
 HumanActivityMonitorManager.prototype.setAccumulativePedometerListener = function() {
index d75da60..8ecc12b 100755 (executable)
@@ -21,6 +21,7 @@
 #include <location_batch.h>
 #include <sensor.h>
 #include <sensor_internal.h>
+#include <system_info.h>
 
 #include "common/logger.h"
 #include "common/optional.h"
@@ -104,6 +105,28 @@ struct PedometerDataWrapper : public sensor_pedometer_data_t {
   }
 };
 
+static int64_t getCurrentTimeStamp(unsigned long long evTime)
+{
+  LoggerD("Enter");
+  struct timespec t;
+  unsigned long long systemCurrentTime = 0;
+  unsigned long long realCurrentTime = 0;
+  unsigned long long timeDiff = 0;
+  int64_t timeStamp = 0;
+
+  //get current system monotonic  time
+  clock_gettime(CLOCK_MONOTONIC, &t);
+  systemCurrentTime = ((unsigned long long)(t.tv_sec)*1000000000LL + t.tv_nsec) /1000000; //convert millisecond
+  timeDiff = (systemCurrentTime - (evTime/1000));
+
+  //get current epoch time(millisecond)
+  clock_gettime(CLOCK_REALTIME, &t);
+  realCurrentTime = ((unsigned long long)(t.tv_sec)*1000000000LL + t.tv_nsec) /1000000;
+  timeStamp =static_cast<int64_t>(realCurrentTime -timeDiff);
+
+  return timeStamp;
+}
+
 void InsertStepDifference(float step_difference, float timestamp, picojson::array* out) {
   ScopeLogger();
 
@@ -535,7 +558,8 @@ class HumanActivityMonitorManager::Monitor::GpsMonitor : public HumanActivityMon
   virtual PlatformResult IsSupportedImpl(bool* s) const override {
     ScopeLogger(type());
 
-    *s = location_manager_is_supported_method(LOCATIONS_METHOD_GPS);
+    int ret = 0;
+    ret = system_info_get_platform_bool("http://tizen.org/feature/location.batch", s);
 
     return PlatformResult(ErrorCode::NO_ERROR);
   }
@@ -543,6 +567,8 @@ class HumanActivityMonitorManager::Monitor::GpsMonitor : public HumanActivityMon
   virtual PlatformResult SetListenerImpl(const picojson::value& args) override {
     ScopeLogger(type());
 
+    int ret = 0;
+
     if (!handle_) {
       int ret = location_manager_create(LOCATIONS_METHOD_GPS, &handle_);
       if (LOCATIONS_ERROR_NONE != ret) {
@@ -551,29 +577,50 @@ class HumanActivityMonitorManager::Monitor::GpsMonitor : public HumanActivityMon
                                   ("Failed to create location manager, error: %d (%s)", ret, get_error_message(ret)));
       }
 
-      int callback_interval = static_cast<int>(args.get(kCallbackInterval).get<double>() / 1000);
-      int sample_interval = static_cast<int>(args.get(kSampleInterval).get<double>() / 1000);
-      LoggerD("callbackInterval: %d, sampleInterval: %d", callback_interval, sample_interval);
-
-      ret = location_manager_set_location_batch_cb(handle_,
-                                                   OnGpsEvent,
-                                                   sample_interval, // batch_interval
-                                                   callback_interval, // batch_period
+      ret = location_manager_set_setting_changed_cb(LOCATIONS_METHOD_GPS,
+                                                   OnGpsSettingEvent,
                                                    this);
       if (LOCATIONS_ERROR_NONE != ret) {
         return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
-                                  "Failed to set location listener",
-                                  ("Failed to set location listener, error: %d (%s)", ret, get_error_message(ret)));
+                                  "Failed to set setting listener",
+                                  ("Failed to set setting listener, error: %d (%s)", ret, get_error_message(ret)));
       }
-
-      ret = location_manager_start_batch(handle_);
+    } else {
+      ret = location_manager_stop_batch(handle_);
       if (LOCATIONS_ERROR_NONE != ret) {
         return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
-                                  "Failed to start location manager",
-                                  ("Failed to start location manager, error: %d (%s)", ret, get_error_message(ret)));
+                                  "Failed to stop location manager",
+                                  ("Failed to stop location manager, error: %d (%s)", ret, get_error_message(ret)));
       }
     }
 
+    int callback_interval = static_cast<int>(args.get(kCallbackInterval).get<double>() / 1000);
+    int sample_interval = static_cast<int>(args.get(kSampleInterval).get<double>() / 1000);
+    LoggerD("callbackInterval: %d, sampleInterval: %d", callback_interval, sample_interval);
+
+    ret = location_manager_set_location_batch_cb(handle_,
+                                                 OnGpsEvent,
+                                                 sample_interval, // batch_interval
+                                                 callback_interval, // batch_period
+                                                 this);
+    if (LOCATIONS_ERROR_NONE != ret) {
+      if (LOCATIONS_ERROR_INVALID_PARAMETER == ret) {
+        return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR,
+                                  "Failed to set location listener",
+                                  ("Failed to set location listener, error: %d (%s)", ret, get_error_message(ret)));
+      }
+      return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
+                                "Failed to set location listener",
+                                ("Failed to set location listener, error: %d (%s)", ret, get_error_message(ret)));
+    }
+
+    ret = location_manager_start_batch(handle_);
+    if (LOCATIONS_ERROR_NONE != ret) {
+      return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
+                                "Failed to start location manager",
+                                ("Failed to start location manager, error: %d (%s)", ret, get_error_message(ret)));
+    }
+
     return PlatformResult(ErrorCode::NO_ERROR);
   }
 
@@ -588,11 +635,11 @@ class HumanActivityMonitorManager::Monitor::GpsMonitor : public HumanActivityMon
                                   ("Failed to stop location manager, error: %d (%s)", ret, get_error_message(ret)));
       }
 
-      ret = location_manager_unset_location_batch_cb(handle_);
+      ret = location_manager_unset_setting_changed_cb(LOCATIONS_METHOD_GPS);
       if (LOCATIONS_ERROR_NONE != ret) {
         return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
-                                  "Failed to unset location listener",
-                                  ("Failed to unset location listener, error: %d (%s)", ret, get_error_message(ret)));
+                                  "Failed to unset location setting changed cb",
+                                  ("Failed to unset location setting changed cb, error: %d (%s)", ret, get_error_message(ret)));
       }
 
       ret = location_manager_destroy(handle_);
@@ -638,6 +685,34 @@ class HumanActivityMonitorManager::Monitor::GpsMonitor : public HumanActivityMon
   }
 
  private:
+  static void OnGpsSettingEvent(location_method_e method, bool enable, void *user_data) {
+    ScopeLogger();
+
+    if (LOCATIONS_METHOD_GPS != method) {
+      LoggerD("Location method different from GPS");
+      return;
+    }
+
+    auto monitor = static_cast<GpsMonitor*>(user_data);
+    auto& callback = monitor->event_callback();
+
+    if (!callback) {
+      LoggerE("No GPS event callback registered, skipping.");
+      return;
+    }
+
+    if (!enable) {
+      picojson::value val{picojson::object{}};
+      auto& obj = val.get<picojson::object>();
+
+      LogAndReportError(
+          PlatformResult(ErrorCode::SERVICE_NOT_AVAILABLE_ERR, "GPS service is not available"),
+          &obj, ("GPS service is not available"));
+
+      callback(&val);
+    }
+  }
+
   static void OnGpsEvent(int num_of_location, void* user_data) {
     ScopeLogger();
 
@@ -682,7 +757,7 @@ class HumanActivityMonitorManager::Monitor::GpsMonitor : public HumanActivityMon
     gps_info_o["altitude"] = picojson::value(altitude);
     gps_info_o["speed"] = picojson::value(speed);
     // TODO(r.galka): errorRange not available in CAPI
-    gps_info_o["errorRange"] = picojson::value(static_cast<double>(0));
+    gps_info_o["errorRange"] = picojson::value(horizontal);
     gps_info_o[kTimestamp] = picojson::value(static_cast<double>(timestamp));
 
     gps_info_array->push_back(gps_info);
@@ -929,10 +1004,10 @@ HumanActivityMonitorManager::HumanActivityMonitorManager()
 
     if (pedometer_data->diffs_count > 0) {
       for (int i = 0; i < pedometer_data->diffs_count; ++i) {
-        InsertStepDifference(pedometer_data->diffs[i].steps, pedometer_data->diffs[i].timestamp, &diffs);
+        InsertStepDifference(pedometer_data->diffs[i].steps, getCurrentTimeStamp(pedometer_data->diffs[i].timestamp) / 1000, &diffs);
       }
     } else {
-      InsertStepDifference(steps_so_far > 0.0 ? pedometer_data->steps() - steps_so_far : 0.0, pedometer_data->timestamp, &diffs);
+      InsertStepDifference(steps_so_far > 0.0 ? pedometer_data->steps() - steps_so_far : 0.0, getCurrentTimeStamp(pedometer_data->timestamp) / 1000, &diffs);
     }
 
     steps_so_far = pedometer_data->steps();
@@ -999,7 +1074,7 @@ HumanActivityMonitorManager::HumanActivityMonitorManager()
     }
 
     data->insert(std::make_pair(kStatus, picojson::value(sleep_state)));
-    data->insert(std::make_pair(kTimestamp, picojson::value(static_cast<double>(event->timestamp))));
+    data->insert(std::make_pair(kTimestamp, picojson::value(getCurrentTimeStamp(event->timestamp))));
 
     return PlatformResult(ErrorCode::NO_ERROR);
   };
index 879ce19..41f9c3b 100644 (file)
@@ -43,41 +43,6 @@ IotconClientManager& IotconClientManager::GetInstance() {
   return instance;
 }
 
-TizenResult IotconClientManager::RestoreHandles() {
-  ScopeLogger();
-
-  for (const auto& it : presence_map_) {
-    LoggerD("Restoring handle for presence event with id: %lld", it.first);
-
-    PresenceEventPtr presence = it.second;
-    char* host = nullptr;
-    char* resource_type = nullptr;
-    iotcon_connectivity_type_e con_type = IOTCON_CONNECTIVITY_IPV4;
-
-    auto res = IotconUtils::ExtractFromPresenceEvent(presence, &host,
-                                                   &con_type, &resource_type);
-    if (!res){
-      return res;
-    }
-
-    const iotcon_presence_h old_handle = presence->handle;
-    int ret = iotcon_add_presence_cb(host, con_type, resource_type,
-                                     PresenceHandler, this,&(presence->handle));
-    if (IOTCON_ERROR_NONE != ret || nullptr == presence->handle) {
-      LogAndReturnTizenError(IotconUtils::ConvertIotconError(ret),
-                             ("iotcon_add_presence_cb() failed: %d (%s)",
-                                 ret, get_error_message(ret)));
-    }
-    if (old_handle) {
-      LoggerD("destroy handle which is currently invalid: %p", old_handle);
-      iotcon_remove_presence_cb(old_handle);
-    }
-    LoggerD("new handle: %p", (presence->handle));
-  }
-
-  return TizenSuccess();
-}
-
 void IotconClientManager::PresenceHandler(iotcon_presence_h presence,
                                          iotcon_error_e err,
                                          iotcon_presence_response_h response,
index e57308d..8b8fd9f 100644 (file)
@@ -33,7 +33,6 @@ class IotconClientManager {
  public:
   static IotconClientManager& GetInstance();
 
-  common::TizenResult RestoreHandles();
   common::TizenResult AddPresenceEventListener(const char* host,
                                                const iotcon_connectivity_type_e con_type_e,
                                                const char* resource_type,
index 3344a02..5eb5a75 100644 (file)
@@ -17,7 +17,6 @@
 #include "iotcon/iotcon_instance.h"
 
 #include <thread>
-#include <iotcon-internal.h>
 
 #include "common/logger.h"
 #include "common/scope_exit.h"
@@ -135,18 +134,11 @@ IotconInstance::IotconInstance() {
 #undef REGISTER_ASYNC
 
   // initialize connection to iotcon service
-  int ret = iotcon_connect();
+  int ret = iotcon_initialize();
   if (IOTCON_ERROR_NONE != ret) {
     LoggerE("Could not connnect to iotcon service: %s", get_error_message(ret));
   } else {
     LoggerD("Iotcon service connected");
-    ret = iotcon_add_connection_changed_cb(ConnectionChangedCallback, this);
-    if (IOTCON_ERROR_NONE != ret) {
-      LoggerE("Could not add connection changed callback for iotcon service: %s",
-              get_error_message(ret));
-    } else {
-      LoggerD("Iotcon connection changed callback is registered");
-    }
 
     ret = iotcon_start_presence(0);
     if (IOTCON_ERROR_NONE != ret) {
@@ -158,37 +150,11 @@ IotconInstance::IotconInstance() {
   }
 }
 
-void IotconInstance::ConnectionChangedCallback(bool is_connected, void* user_data) {
-  ScopeLogger();
-
-  if (!is_connected) {
-    LoggerD("Connection lost, need to wait for connection recovery");
-  } else {
-    IotconInstance* instance = static_cast<IotconInstance*>(user_data);
-    if (!instance) {
-      LoggerE("instance is NULL");
-      return;
-    }
-
-    LoggerD("Connection recovered, restoring handles");
-    auto ret = IotconServerManager::GetInstance().RestoreHandles();
-    if (!ret) {
-      LoggerD("Connection recovered, but restoring handles failed");
-    }
-
-    ret = IotconClientManager::GetInstance().RestoreHandles();
-    if (!ret) {
-      LoggerD("Connection recovered, but restoring presence failed");
-    }
-  }
-}
-
 IotconInstance::~IotconInstance() {
   ScopeLogger();
 
   iotcon_stop_presence();
-  iotcon_remove_connection_changed_cb(ConnectionChangedCallback, this);
-  iotcon_disconnect();
+  iotcon_deinitialize();
 }
 
 common::TizenResult IotconInstance::ResourceGetObserverIds(const picojson::object& args) {
index a873cb4..277e52e 100644 (file)
@@ -41,57 +41,6 @@ IotconServerManager& IotconServerManager::GetInstance() {
   return instance;
 }
 
-TizenResult IotconServerManager::RestoreHandles() {
-  ScopeLogger();
-
-  for (const auto& it : resource_map_) {
-    LoggerD("Restoring handle for resource with id: %lld", it.first);
-
-    ResourceInfoPtr resource = it.second;
-    char* uri_path = nullptr;
-    iotcon_resource_types_h res_types = nullptr;
-    iotcon_resource_interfaces_h ifaces = 0;
-    int properties = 0;
-
-    auto res = IotconUtils::ExtractFromResource(resource, &uri_path,
-                                                &res_types, &ifaces, &properties);
-    if (!res){
-      return res;
-    }
-
-    const iotcon_resource_h old_handle = resource->handle;
-    LoggerD("Create resource from backup data, uri: %s, res_types: %p, ifaces: %d, properties: %d",
-            uri_path, res_types, ifaces, properties);
-
-    int ret = iotcon_resource_create(uri_path, res_types, ifaces, properties,
-                                     RequestHandler, // request_callback
-                                     this, // user_data
-                                     &(resource->handle));
-    if (IOTCON_ERROR_NONE != ret || nullptr == resource->handle) {
-      LogAndReturnTizenError(IotconUtils::ConvertIotconError(ret),
-                             ("iotcon_resource_create() failed: %d (%s)",
-                                 ret, get_error_message(ret)));
-    }
-    LoggerD("new handle: %p", (resource->handle));
-    if (old_handle) {
-      LoggerD("destroy handle which is currently invalid: %p", old_handle);
-      iotcon_resource_destroy(old_handle);
-    }
-  }
-
-  // rebind children
-  for (const auto& it : resource_map_) {
-    for (const auto& child : it.second->children) {
-      auto result = IotconUtils::ConvertIotconError(iotcon_resource_bind_child_resource(it.second->handle, child->handle));
-      if (!result) {
-        LogAndReturnTizenError(result, ("iotcon_resource_bind_child_resource() failed"));
-      }
-    }
-  }
-
-  return TizenSuccess();
-}
-
 void IotconServerManager::RequestHandler(iotcon_resource_h resource,
                                          iotcon_request_h request, void *user_data) {
   ScopeLogger();
index 3f9d8ef..7b9d347 100644 (file)
@@ -35,7 +35,6 @@ class IotconServerManager {
  public:
   static IotconServerManager& GetInstance();
 
-  common::TizenResult RestoreHandles();
   common::TizenResult CreateResource(const std::string& uri_path,
                                      const picojson::array& interfaces_array,
                                      const picojson::array& types_array,
index 6fa89bf..3e8c06b 100644 (file)
@@ -1988,7 +1988,6 @@ common::TizenResult IotconUtils::ConvertIotconError(int error) {
     case IOTCON_ERROR_OUT_OF_MEMORY:
     case IOTCON_ERROR_IOTIVITY:
     case IOTCON_ERROR_REPRESENTATION:
-    case IOTCON_ERROR_DBUS:
     case IOTCON_ERROR_SYSTEM:
     default:
       return common::AbortError(error);
index f8406b4..acc1cae 100755 (executable)
@@ -17,6 +17,7 @@
 var validator_ = xwalk.utils.validator;
 var types_ = validator_.Types;
 var type_ = xwalk.utils.type;
+var converter_ = xwalk.utils.converter;
 
 var callbackId = 0;
 var callbacks = {};
@@ -337,6 +338,9 @@ RemoteMessagePort.prototype.sendMessage = function() {
         }
         filtered_data[i] = { key: key, value: value, valueType: 'byteStreamArrayValueType'};
       }
+    } else {
+      // convert any other value to string -> backward compatibility
+      filtered_data[i] = { key: key, value: converter_.toString(value), valueType: 'stringValueType'};
     }
     unique_data_key[key] = true;
   }
index 1b7d18c..cd656a7 100755 (executable)
@@ -120,8 +120,8 @@ auto getServiceIdFromJSON = [](picojson::object& data) -> int {
     }
 };
 
-const std::string kPrivilegeMessagingRead  = "http://tizen.org/privilege/message.read";
-const std::string kPrivilegeMessagingWrite = "http://tizen.org/privilege/message.write";
+const std::string kPrivilegeMessagingRead  = "http://tizen.org/privilege/messaging.read";
+const std::string kPrivilegeMessagingWrite = "http://tizen.org/privilege/messaging.write";
 
 const long kDumbCallbackId= -1;
 }
index 6e39214..809c836 100644 (file)
@@ -29,7 +29,7 @@ namespace networkbearerselection {
 
 namespace {
 // The privileges that required in NetworkBearerSelection API
-const std::string kPrivilegeNetworkBearerSelection = "http://tizen.org/privilege/network.set";
+const std::string kPrivilegeNetworkBearerSelection = "http://tizen.org/privilege/networkbearerselection";
 const std::string kPrivilegeInternet = "http://tizen.org/privilege/internet";
 const std::vector<std::string> kNbsPrivileges{kPrivilegeNetworkBearerSelection, kPrivilegeInternet};
 
index f29a298..781f90e 100644 (file)
@@ -40,9 +40,9 @@ namespace {
 
 const std::string kPrivilegeNfcAdmin = "http://tizen.org/privilege/nfc.admin";
 const std::string kPrivilegeNfcCardEmulation = "http://tizen.org/privilege/nfc.cardemulation";
-const std::string kPrivilegeNfcCommon = "http://tizen.org/privilege/nfc";
-const std::string kPrivilegeNfcP2P = "http://tizen.org/privilege/nfc";
-const std::string kPrivilegeNfcTag = "http://tizen.org/privilege/nfc";
+const std::string kPrivilegeNfcCommon = "http://tizen.org/privilege/nfc.common";
+const std::string kPrivilegeNfcP2P = "http://tizen.org/privilege/nfc.p2p";
+const std::string kPrivilegeNfcTag = "http://tizen.org/privilege/nfc.tag";
 
 } // namespace
 
index d7b5f53..8125076 100644 (file)
@@ -40,7 +40,7 @@ using common::PlatformResult;
 
 namespace {
 // The privileges that required in Package API
-const std::string kPrivilegePackageInstall = "http://tizen.org/privilege/packagemanager.admin";
+const std::string kPrivilegePackageInstall = "http://tizen.org/privilege/packagemanager.install";
 const std::string kPrivilegePackageInfo = "http://tizen.org/privilege/packagemanager.info";
 }  // namespace
 
index 6d7d2df..a4b566d 100755 (executable)
@@ -34,7 +34,7 @@ namespace power {
 
 namespace {
 // The privileges that required in Power API
-const std::string kPrivilegePower = "http://tizen.org/privilege/display";
+const std::string kPrivilegePower = "http://tizen.org/privilege/power";
 
 const std::map<std::string, PowerResource> kPowerResourceMap = {
     {"SCREEN", POWER_RESOURCE_SCREEN},
diff --git a/src/preference/preference.gyp b/src/preference/preference.gyp
new file mode 100644 (file)
index 0000000..0b5161b
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  'includes':[
+    '../common/common.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'tizen_preference',
+      'type': 'loadable_module',
+      'dependencies': [
+        '../common/common.gyp:tizen_common',
+      ],
+      'sources': [
+        'preference_api.js',
+        'preference_extension.cc',
+        'preference_extension.h',
+        'preference_instance.cc',
+        'preference_instance.h',
+        'preference_manager.cc',
+        'preference_manager.h',
+      ],
+      'conditions': [
+        ['tizen == 1', {
+          'variables': {
+            'packages': [
+              'capi-appfw-application',
+            ]
+          },
+        }],
+      ],
+    },
+  ],
+}
diff --git a/src/preference/preference_api.js b/src/preference/preference_api.js
new file mode 100644 (file)
index 0000000..2343402
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+
+
+var validator_ = xwalk.utils.validator;
+var type_ = xwalk.utils.type;
+var types_ = validator_.Types;
+var native_ = new xwalk.utils.NativeManager(extension);
+
+function PreferenceManager() {
+}
+
+PreferenceManager.prototype.getAll = function() {
+  var args = validator_.validateArgs(arguments, [
+    { name: 'successCallback', type: types_.FUNCTION },
+    { name: 'errorCallback', type: types_.FUNCTION, optional : true, nullable : true }
+  ]);
+
+  var callback = function(result) {
+    if (native_.isFailure(result)) {
+      native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
+    } else {
+      args.successCallback(native_.getResultObject(result));
+    }
+  };
+
+  var result = native_.call('PreferenceManager_getAll', {}, callback);
+  if (native_.isFailure(result)) {
+    throw native_.getErrorObject(result);
+  }
+};
+
+PreferenceManager.prototype.setValue = function() {
+  var args = validator_.validateArgs(arguments, [
+    { name: 'key', type: types_.STRING },
+    { name: 'value', type: types_.SIMPLE_TYPE }
+  ]);
+
+  var result = native_.callSync('PreferenceManager_setValue',
+                                {
+                                   key: args.key,
+                                   value: args.value
+                                }
+  );
+
+  if (native_.isFailure(result)) {
+    throw native_.getErrorObject(result);
+  }
+};
+
+PreferenceManager.prototype.getValue = function() {
+  var args = validator_.validateArgs(arguments, [
+    { name: 'key', type: types_.STRING }
+  ]);
+
+  var result = native_.callSync('PreferenceManager_getValue', { key: args.key });
+
+  if (native_.isFailure(result)) {
+    throw native_.getErrorObject(result);
+  } else {
+    return native_.getResultObject(result);
+  }
+};
+
+PreferenceManager.prototype.remove = function() {
+  var args = validator_.validateArgs(arguments, [
+    { name: 'key', type: types_.STRING }
+  ]);
+
+  var result = native_.callSync('PreferenceManager_remove', { key: args.key });
+
+  if (native_.isFailure(result)) {
+    throw native_.getErrorObject(result);
+  }
+};
+
+PreferenceManager.prototype.removeAll = function() {
+  var result = native_.callSync('PreferenceManager_removeAll', {});
+
+  if (native_.isFailure(result)) {
+    throw native_.getErrorObject(result);
+  }
+};
+
+PreferenceManager.prototype.exists = function() {
+  var args = validator_.validateArgs(arguments, [
+    { name: 'key', type: types_.STRING }
+  ]);
+
+  var result = native_.callSync('PreferenceManager_exists', { key: args.key });
+
+  if (native_.isFailure(result)) {
+    throw native_.getErrorObject(result);
+  } else {
+    return native_.getResultObject(result);
+  }
+};
+
+var PREFERENCE_CHANGED_LISTENER = 'PREFERENCE_CHANGED';
+
+function PreferenceChangedListener() {
+  var that = this;
+  this.appListener = function (result) {
+    var data = native_.getResultObject(result);
+    var key = data.key;
+    var value = data.value;
+
+    if (that.instances[key]) {
+      var listener = that.instances[key];
+      if (type_.isFunction(listener)) {
+        listener({ key: key, value: value });
+      }
+    }
+  };
+}
+
+PreferenceChangedListener.prototype.instances = {};
+
+PreferenceChangedListener.prototype.addListener = function(key, listener) {
+  if (type_.isEmptyObject(this.instances)) {
+    native_.addListener(PREFERENCE_CHANGED_LISTENER, this.appListener);
+  }
+
+  this.instances[key] = listener;
+};
+
+PreferenceChangedListener.prototype.removeListener = function(key) {
+  if (this.instances[key]) {
+    delete this.instances[key];
+    if (type_.isEmptyObject(this.instances)) {
+      native_.removeListener(PREFERENCE_CHANGED_LISTENER);
+    }
+  }
+};
+
+var _preferenceChangedListener = new PreferenceChangedListener();
+
+PreferenceManager.prototype.setChangeListener = function() {
+  var args = validator_.validateArgs(arguments, [
+    { name: 'key', type: types_.STRING },
+    { name: 'listener', type: types_.FUNCTION }
+  ]);
+
+  var result = native_.callSync('PreferenceManager_setChangeListener', { key: args.key });
+  if (native_.isFailure(result)) {
+    throw native_.getErrorObject(result);
+  }
+
+  _preferenceChangedListener.addListener(args.key, args.listener);
+}
+
+PreferenceManager.prototype.unsetChangeListener = function() {
+  var args = validator_.validateArgs(arguments, [
+    { name: 'key', type: types_.STRING }
+  ]);
+
+  var result = native_.callSync('PreferenceManager_unsetChangeListener', { key: args.key });
+
+  if (native_.isFailure(result)) {
+    throw native_.getErrorObject(result);
+  }
+
+  _preferenceChangedListener.removeListener(args.key);
+};
+
+// Exports
+exports = new PreferenceManager();
+
diff --git a/src/preference/preference_extension.cc b/src/preference/preference_extension.cc
new file mode 100644 (file)
index 0000000..45d388f
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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 "preference/preference_extension.h"
+
+#include "preference/preference_instance.h"
+
+// This will be generated from preference_api.js
+extern const char kSource_preference_api[];
+
+common::Extension* CreateExtension() {
+  return new PreferenceExtension;
+}
+
+PreferenceExtension::PreferenceExtension() {
+  SetExtensionName("tizen.preference");
+  SetJavaScriptAPI(kSource_preference_api);
+}
+
+PreferenceExtension::~PreferenceExtension() {}
+
+common::Instance* PreferenceExtension::CreateInstance() {
+  return new extension::preference::PreferenceInstance;
+}
diff --git a/src/preference/preference_extension.h b/src/preference/preference_extension.h
new file mode 100644 (file)
index 0000000..1df8fd1
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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 PREFERENCE_PREFERENCE_EXTENSION_H_
+#define PREFERENCE_PREFERENCE_EXTENSION_H_
+
+#include "common/extension.h"
+
+class PreferenceExtension : public common::Extension {
+ public:
+  PreferenceExtension();
+  virtual ~PreferenceExtension();
+
+ private:
+  virtual common::Instance* CreateInstance();
+};
+
+#endif // PREFERENCE_PREFERENCE_EXTENSION_H_
+
diff --git a/src/preference/preference_instance.cc b/src/preference/preference_instance.cc
new file mode 100644 (file)
index 0000000..851689b
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * 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 "common/logger.h"
+#include "common/picojson.h"
+#include "common/task-queue.h"
+#include "common/tools.h"
+#include "common/scope_exit.h"
+#include "preference/preference_instance.h"
+
+
+namespace extension {
+namespace preference {
+
+namespace {
+const char* kKey = "key";
+const char* kValue = "value";
+
+const common::ListenerToken kPreferenceChangeListenerToken{"PREFERENCE_CHANGED"};
+} // namespace
+
+#define CHECK_EXIST(args, name) \
+  if (args.end() == args.find(name)) { \
+    return common::TypeMismatchError(std::string(name) + " is required argument"); \
+  }
+
+
+PreferenceInstance::PreferenceInstance() {
+  ScopeLogger();
+
+  using std::placeholders::_1;
+  using std::placeholders::_2;
+
+#define REGISTER(c,x) \
+    RegisterSyncHandler(c, std::bind(&PreferenceInstance::x, this, _1));
+  REGISTER("PreferenceManager_setValue", SetValue);
+  REGISTER("PreferenceManager_getValue", GetValue);
+  REGISTER("PreferenceManager_remove", Remove);
+  REGISTER("PreferenceManager_removeAll", RemoveAll);
+  REGISTER("PreferenceManager_exists", Exists);
+  REGISTER("PreferenceManager_setChangeListener", SetChangeListener);
+  REGISTER("PreferenceManager_unsetChangeListener", UnsetChangeListener);
+#undef REGISTER
+#define REGISTER_ASYNC(c,x) \
+    RegisterHandler(c, std::bind(&PreferenceInstance::x, this, _1, _2));
+  REGISTER_ASYNC("PreferenceManager_getAll", GetAll);
+#undef REGISTER_ASYNC
+}
+
+PreferenceInstance::~PreferenceInstance()
+{
+  ScopeLogger();
+}
+
+common::TizenResult PreferenceInstance::GetAll(const picojson::object& args, const common::AsyncToken& token) {
+  ScopeLogger();
+
+  return manager_.GetAll(SimplePost(token));
+}
+
+common::TizenResult PreferenceInstance::SetValue(const picojson::object& args) {
+  ScopeLogger();
+
+  CHECK_EXIST(args, kKey)
+  CHECK_EXIST(args, kValue)
+
+  const auto& key = args.find(kKey)->second.get<std::string>();
+  const auto& value = args.find(kValue)->second;
+
+  return manager_.SetValue(key, value);
+}
+
+common::TizenResult PreferenceInstance::GetValue(const picojson::object& args) {
+  ScopeLogger();
+
+  CHECK_EXIST(args, kKey)
+  const auto& key = args.find(kKey)->second.get<std::string>();
+  return manager_.GetValue(key);
+}
+
+common::TizenResult PreferenceInstance::Remove(const picojson::object& args) {
+  ScopeLogger();
+
+  CHECK_EXIST(args, kKey)
+  const auto& key = args.find(kKey)->second.get<std::string>();
+  return manager_.Remove(key);
+}
+
+common::TizenResult PreferenceInstance::RemoveAll(const picojson::object& args) {
+  ScopeLogger();
+  return manager_.RemoveAll();
+}
+
+common::TizenResult PreferenceInstance::Exists(const picojson::object& args) {
+  ScopeLogger();
+
+  CHECK_EXIST(args, kKey)
+  const auto& key = args.find(kKey)->second.get<std::string>();
+  return manager_.Exists(key);
+}
+
+common::TizenResult PreferenceInstance::SetChangeListener(const picojson::object& args) {
+  ScopeLogger();
+  CHECK_EXIST(args, kKey)
+  const auto& key = args.find(kKey)->second.get<std::string>();
+
+  common::PostCallback callback = [this](const common::TizenResult&, const picojson::value& v) {
+    Post(kPreferenceChangeListenerToken, common::TizenSuccess{v});
+  };
+
+  return manager_.SetChangeListener(key, callback);
+}
+
+common::TizenResult PreferenceInstance::UnsetChangeListener(const picojson::object& args) {
+  ScopeLogger();
+
+  CHECK_EXIST(args, kKey)
+  const auto& key = args.find(kKey)->second.get<std::string>();
+  return manager_.UnsetChangeListener(key);
+}
+
+} // namespace preference
+} // namespace extension
diff --git a/src/preference/preference_instance.h b/src/preference/preference_instance.h
new file mode 100644 (file)
index 0000000..946bc72
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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 PREFERENCE_PREFERENCE_INSTANCE_H_
+#define PREFERENCE_PREFERENCE_INSTANCE_H_
+
+#include "common/tizen_instance.h"
+#include "preference/preference_manager.h"
+
+namespace extension {
+namespace preference {
+
+class PreferenceInstance : public common::TizenInstance {
+public:
+  PreferenceInstance();
+  virtual ~PreferenceInstance();
+
+private:
+  common::TizenResult GetAll(const picojson::object& args, const common::AsyncToken& token);
+  common::TizenResult SetValue(const picojson::object& args);
+  common::TizenResult GetValue(const picojson::object& args);
+  common::TizenResult Remove(const picojson::object& args);
+  common::TizenResult RemoveAll(const picojson::object& args);
+  common::TizenResult Exists(const picojson::object& args);
+  common::TizenResult SetChangeListener(const picojson::object& args);
+  common::TizenResult UnsetChangeListener(const picojson::object& args);
+
+  PreferenceManager manager_;
+};
+
+} // namespace preference
+} // namespace extension
+
+#endif // PREFERENCE_PREFERENCE_INSTANCE_H_
diff --git a/src/preference/preference_manager.cc b/src/preference/preference_manager.cc
new file mode 100644 (file)
index 0000000..b976004
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * 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 <app_preference.h>
+
+#include <thread>
+
+#include "common/logger.h"
+#include "common/tools.h"
+#include "preference/preference_manager.h"
+#include "preference/preference_instance.h"
+
+namespace extension {
+namespace preference {
+
+std::mutex PreferenceManager::key_listener_mtx_;
+
+namespace {
+const char* kKey = "key";
+const char* kValue = "value";
+
+common::TizenResult MakeErrResult(int ret, const char* err_msg) {
+  LoggerE("%s", err_msg);
+  switch (ret) {
+    case PREFERENCE_ERROR_INVALID_PARAMETER:
+      return common::InvalidValuesError(std::string(err_msg));
+
+    case PREFERENCE_ERROR_OUT_OF_MEMORY:
+      return common::AbortError(std::string(err_msg));
+
+    case PREFERENCE_ERROR_IO_ERROR:
+      return common::IoError(std::string(err_msg));
+
+    case PREFERENCE_ERROR_NO_KEY:
+      return common::NotFoundError(std::string(err_msg));
+
+    default:
+      return common::AbortError(std::string(err_msg));
+  }
+}
+
+int GetValueInternal(const std::string& key, picojson::value* val) {
+  char* result_str = nullptr;
+  int ret = preference_get_string(key.c_str(), &result_str);
+
+  if (ret == PREFERENCE_ERROR_NONE) {
+    *val = picojson::value(std::string(result_str));
+    free(result_str);
+  } else {
+    double result_double = 0;
+    ret = preference_get_double(key.c_str(), &result_double);
+
+    if (ret == PREFERENCE_ERROR_NONE) {
+      *val = picojson::value(result_double);
+    } else {
+      bool result_bool = false;
+      ret = preference_get_boolean(key.c_str(), &result_bool);
+
+      if (ret == PREFERENCE_ERROR_NONE) {
+        *val = picojson::value(result_bool);
+      } else {
+        int result_int = 0;
+        ret = preference_get_int(key.c_str(), &result_int);
+
+        if (ret == PREFERENCE_ERROR_NONE) {
+          *val = picojson::value(static_cast<double>(result_int));
+        }
+      }
+    }
+  }
+  return ret;
+}
+
+bool GetAllCb(const char* key, void* user_data) {
+  ScopeLogger();
+
+  if (!key) {
+    LoggerW("Key is null");
+    return true;
+  }
+
+  picojson::array* array = static_cast<picojson::array*>(user_data);
+
+  if (!array) {
+    LoggerW("User data is null");
+    return true;
+  }
+
+  picojson::value val;
+  if (PREFERENCE_ERROR_NONE == GetValueInternal(key, &val)) {
+    picojson::value result_val{picojson::object{}};
+    picojson::object& result_obj = result_val.get<picojson::object>();
+
+    result_obj.insert(std::make_pair(kKey, picojson::value(key)));
+    result_obj.insert(std::make_pair(kValue, val));
+
+    array->push_back(result_val);
+  }
+
+  return true;
+}
+
+void ChangedCb(const char* key, void* user_data) {
+  ScopeLogger();
+
+  if (!key) {
+    LoggerW("Key is null");
+    return;
+  }
+
+  common::PostCallback* callback = static_cast<common::PostCallback*>(user_data);
+  if (!callback) {
+    LoggerW("User data is null");
+    return;
+  }
+
+  picojson::value val;
+
+  if (PREFERENCE_ERROR_NONE == GetValueInternal(key, &val)) {
+    picojson::value result_val{picojson::object{}};
+    picojson::object& result_obj = result_val.get<picojson::object>();
+
+    result_obj.insert(std::make_pair(kKey, picojson::value(key)));
+    result_obj.insert(std::make_pair(kValue, val));
+
+    (*callback)(common::TizenSuccess(), result_val);
+  } else {
+    LoggerE("preference_set_ function error");
+  }
+}
+} // namespace
+
+PreferenceManager::~PreferenceManager() {
+  ScopeLogger();
+
+  std::lock_guard<std::mutex> lock(key_listener_mtx_);
+  for (const auto& it : key_listeners_) {
+    preference_unset_changed_cb(it.c_str());
+  }
+}
+
+common::TizenResult PreferenceManager::GetAll(const common::PostCallback& callback) {
+  ScopeLogger();
+
+  auto get_all = [](const common::PostCallback& callback) -> void {
+    picojson::value response{picojson::array{}};
+    auto* array = &response.get<picojson::array>();
+
+    int ret = preference_foreach_item(GetAllCb, array);
+
+    common::TizenResult result = common::TizenSuccess();
+
+    if (PREFERENCE_ERROR_NONE != ret) {
+      result = MakeErrResult(ret, "preference_foreach_item function error");
+    }
+
+    callback(result, response);
+  };
+
+  std::thread(get_all, callback).detach();
+
+  return common::TizenSuccess();
+}
+
+common::TizenResult PreferenceManager::SetValue(const std::string& key, const picojson::value& value) {
+  ScopeLogger();
+
+  int ret = PREFERENCE_ERROR_NONE;
+
+  if (value.is<bool>()) {
+    ret = preference_set_boolean(key.c_str(), value.get<bool>());
+  } else if (value.is<double>()) {
+    ret = preference_set_double(key.c_str(), value.get<double>());
+  } else if (value.is<std::string>()) {
+    ret = preference_set_string(key.c_str(), value.get<std::string>().c_str());
+  } else {
+    ret = PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  if (ret == PREFERENCE_ERROR_NONE) {
+    return common::TizenSuccess();
+  } else {
+    return MakeErrResult(ret, "preference_set_ function error");
+  }
+}
+
+common::TizenResult PreferenceManager::GetValue(const std::string& key) {
+  ScopeLogger();
+
+  picojson::value val;
+
+  int ret = GetValueInternal(key, &val);
+
+  if (ret == PREFERENCE_ERROR_NONE) {
+    return common::TizenSuccess(val);
+  } else {
+    return MakeErrResult(ret, "preference_set_ function error");
+  }
+}
+
+common::TizenResult PreferenceManager::Remove(const std::string& key) {
+  ScopeLogger();
+
+  int ret = preference_remove(key.c_str());
+
+  if (ret == PREFERENCE_ERROR_NONE) {
+    return common::TizenSuccess();
+  } else {
+    return MakeErrResult(ret, "preference_remove function error");
+  }
+}
+
+common::TizenResult PreferenceManager::RemoveAll() {
+  ScopeLogger();
+
+  int ret = preference_remove_all();
+
+  if (ret == PREFERENCE_ERROR_NONE) {
+    return common::TizenSuccess();
+  } else {
+    return MakeErrResult(ret, "preference_remove_all function error");
+  }
+}
+
+common::TizenResult PreferenceManager::Exists(const std::string& key) {
+  ScopeLogger();
+
+  bool is_existing = false;
+  int ret = preference_is_existing(key.c_str(), &is_existing);
+
+  if (ret == PREFERENCE_ERROR_NONE) {
+    return common::TizenSuccess(picojson::value(is_existing));
+  } else {
+    return MakeErrResult(ret, "preference_is_existing function error");
+  }
+}
+
+common::TizenResult PreferenceManager::SetChangeListener(const std::string& key,
+                                                         const common::PostCallback callback) {
+  ScopeLogger();
+
+  if (!post_changed_callback_) {
+    post_changed_callback_ = callback;
+  }
+
+  std::lock_guard<std::mutex> lock(key_listener_mtx_);
+  for (const auto& it : key_listeners_) {
+    if (key == it) {
+      return common::TizenSuccess();
+    }
+  }
+
+  int ret = preference_set_changed_cb(key.c_str(), ChangedCb, (void*) &post_changed_callback_);
+
+  if (PREFERENCE_ERROR_NONE == ret) {
+    key_listeners_.push_back(key);
+    return common::TizenSuccess();
+  } else {
+    return MakeErrResult(ret, "preference_set_changed_cb function error");
+  }
+}
+
+common::TizenResult PreferenceManager::UnsetChangeListener(const std::string& key) {
+  ScopeLogger();
+
+  if (post_changed_callback_) {
+    std::lock_guard<std::mutex> lock(key_listener_mtx_);
+    for (auto it = key_listeners_.begin(); it != key_listeners_.end(); ++it) {
+      if (key == (*it)) {
+        int ret = preference_unset_changed_cb(key.c_str());
+
+        if (PREFERENCE_ERROR_NONE != ret) {
+          return MakeErrResult(ret, "preference_unset_changed_cb function error");
+        }
+
+        key_listeners_.erase(it);
+        break;
+      }
+    }
+  }
+
+  return common::TizenSuccess();
+}
+
+} // namespace preference
+} // namespace extension
diff --git a/src/preference/preference_manager.h b/src/preference/preference_manager.h
new file mode 100644 (file)
index 0000000..2f46539
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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 PREFERENCE_PREFERENCE_MANAGER_H_
+#define PREFERENCE_PREFERENCE_MANAGER_H_
+
+#include <mutex>
+
+#include "common/picojson.h"
+#include "common/tizen_instance.h"
+
+namespace extension {
+namespace preference {
+
+class PreferenceManager {
+public:
+  ~PreferenceManager();
+  common::TizenResult GetAll(const common::PostCallback& callback);
+  common::TizenResult SetValue(const std::string& key, const picojson::value& value);
+  common::TizenResult GetValue(const std::string& key);
+  common::TizenResult Remove(const std::string& key);
+  common::TizenResult RemoveAll(void);
+  common::TizenResult Exists(const std::string& key);
+  common::TizenResult SetChangeListener(const std::string& key, const common::PostCallback callback);
+  common::TizenResult UnsetChangeListener(const std::string& key);
+
+private:
+  common::PostCallback post_changed_callback_;
+  std::vector<std::string> key_listeners_;
+  static std::mutex key_listener_mtx_;
+};
+
+} // namespace preference
+} // namespace extension
+
+#endif // PREFERENCE_PREFERENCE_MANAGER_H_
index 9f51362..45eab7c 100755 (executable)
@@ -262,7 +262,7 @@ void SensorData::SensorCallback(sensor_h sensor, sensor_event_s* event, void* us
 }
 
 bool SensorData::DefaultEventComparator(sensor_event_s* l, sensor_event_s* r) {
-  return (l->values[0] == r->values[0]);
+  return (l->timestamp == r->timestamp);
 }
 
 PlatformResult SensorData::CheckInitialization() {
index c95fbca..55d6891 100644 (file)
@@ -36,7 +36,7 @@ const std::string SETTING_LOCK_SCREEN = "LOCK_SCREEN";
 const std::string SETTING_INCOMING_CALL = "INCOMING_CALL";
 const std::string SETTING_NOTIFICATION_EMAIL = "NOTIFICATION_EMAIL";
 
-const std::string kPrivilegeSetting = "http://tizen.org/privilege/systemsettings.admin";
+const std::string kPrivilegeSetting = "http://tizen.org/privilege/setting";
 }
 
 using namespace common;
index 65659de..939e691 100755 (executable)
           },
         ],
         [
+          'tizen_feature_feedback_support==1', {
+            'dependencies': [
+              'feedback/feedback.gyp:*',
+            ],
+          },
+        ],
+        [
           'tizen_feature_filesystem_support==1', {
             'dependencies': [
               'filesystem/filesystem.gyp:*',
           },
         ],
         [
+          'tizen_feature_preference_support==1', {
+            'dependencies': [
+              'preference/preference.gyp:*',
+            ],
+          },
+        ],
+        [
           'tizen_feature_push_support==1', {
             'dependencies': [
               'push/push.gyp:*',
             ],
           },
         ],
+        [
+          'tizen_feature_widget_service_support==1', {
+            'dependencies': [
+              'widgetservice/widgetservice.gyp:*',
+            ],
+          },
+        ],
       ], # end conditions
     },
   ], # end targets
index 6c81ff1..b4a6e23 100644 (file)
@@ -72,18 +72,18 @@ function Utils() {
     ACCOUNT_READ: 'http://tizen.org/privilege/account.read',
     ACCOUNT_WRITE: 'http://tizen.org/privilege/account.write',
     ALARM: 'http://tizen.org/privilege/alarm.get',
-    APPLICATION_INFO: 'http://tizen.org/privilege/packagemanager.info',
-    APPLICATION_LAUNCH: 'http://tizen.org/privilege/appmanager.launch',
-    APPMANAGER_CERTIFICATE: 'http://tizen.org/privilege/notexist',
+    APPLICATION_INFO: 'http://tizen.org/privilege/application.info',
+    APPLICATION_LAUNCH: 'http://tizen.org/privilege/application.launch',
+    APPMANAGER_CERTIFICATE: 'http://tizen.org/privilege/appmanager.certificate',
     APPMANAGER_KILL: 'http://tizen.org/privilege/appmanager.kill',
     BLUETOOTH_ADMIN: 'http://tizen.org/privilege/bluetooth.admin',
-    BLUETOOTH_GAP: 'http://tizen.org/privilege/bluetooth.admin',
-    BLUETOOTH_HEALTH: 'http://tizen.org/privilege/bluetooth.admin',
-    BLUETOOTH_SPP: 'http://tizen.org/privilege/bluetooth.admin',
-    BLUETOOTHMANAGER: 'http://tizen.org/privilege/bluetooth.admin',
+    BLUETOOTH_GAP: 'http://tizen.org/privilege/bluetooth.gap',
+    BLUETOOTH_HEALTH: 'http://tizen.org/privilege/bluetooth.health',
+    BLUETOOTH_SPP: 'http://tizen.org/privilege/bluetooth.spp',
+    BLUETOOTHMANAGER: 'http://tizen.org/privilege/bluetoothmanager',
     BLUETOOTH: 'http://tizen.org/privilege/bluetooth',
-    BOOKMARK_READ: 'http://tizen.org/privilege/bookmark.admin',
-    BOOKMARK_WRITE: 'http://tizen.org/privilege/bookmark.admin',
+    BOOKMARK_READ: 'http://tizen.org/privilege/bookmark.read',
+    BOOKMARK_WRITE: 'http://tizen.org/privilege/bookmark.write',
     CALENDAR_READ: 'http://tizen.org/privilege/calendar.read',
     CALENDAR_WRITE: 'http://tizen.org/privilege/calendar.write',
     CALLHISTORY_READ: 'http://tizen.org/privilege/callhistory.read',
@@ -92,36 +92,40 @@ function Utils() {
     CONTACT_WRITE: 'http://tizen.org/privilege/contact.write',
     CONTENT_READ: 'http://tizen.org/privilege/content.write',
     CONTENT_WRITE: 'http://tizen.org/privilege/content.write',
-    DATACONTROL_CONSUMER: 'http://tizen.org/privilege/datasharing',
-    DATASYNC: 'http://tizen.org/privilege/notexist',
+    D2D_DATASHARING: 'http://tizen.org/privilege/d2d.datasharing',
+    DATACONTROL_CONSUMER: 'http://tizen.org/privilege/datacontrol.consumer',
+    DATASYNC: 'http://tizen.org/privilege/datasync',
     DOWNLOAD: 'http://tizen.org/privilege/download',
-    FILESYSTEM_READ: 'http://tizen.org/privilege/systemsettings.admin',
-    FILESYSTEM_WRITE: 'http://tizen.org/privilege/systemsettings.admin',
+    FILESYSTEM_READ: 'http://tizen.org/privilege/filesystem.read',
+    FILESYSTEM_WRITE: 'http://tizen.org/privilege/filesystem.write',
+    HAPTIC: 'http://tizen.org/privilege/haptic',
     HEALTHINFO: 'http://tizen.org/privilege/healthinfo',
     INTERNET: 'http://tizen.org/privilege/internet',
     LED: 'http://tizen.org/privilege/led',
     LOCATION: 'http://tizen.org/privilege/location',
     MEDIACONTROLLER_SERVER: 'http://tizen.org/privilege/mediacontroller.server',
     MEDIACONTROLLER_CLIENT: 'http://tizen.org/privilege/mediacontroller.client',
-    MESSAGING_READ: 'http://tizen.org/privilege/message.read',
-    MESSAGING_WRITE: 'http://tizen.org/privilege/message.write',
-    NETWORKBEARERSELECTION: 'http://tizen.org/privilege/network.set',
+    MESSAGING_READ: 'http://tizen.org/privilege/messaging.read',
+    MESSAGING_WRITE: 'http://tizen.org/privilege/messaging.write',
+    NETWORKBEARERSELECTION: 'http://tizen.org/privilege/networkbearerselection',
     NFC_ADMIN: 'http://tizen.org/privilege/nfc.admin',
     NFC_CARDEMULATION: 'http://tizen.org/privilege/nfc.cardemulation',
-    NFC_COMMON: 'http://tizen.org/privilege/nfc',
-    NFC_P2P: 'http://tizen.org/privilege/nfc',
-    NFC_TAG: 'http://tizen.org/privilege/nfc',
+    NFC_COMMON: 'http://tizen.org/privilege/nfc.common',
+    NFC_P2P: 'http://tizen.org/privilege/nfc.p2p',
+    NFC_TAG: 'http://tizen.org/privilege/nfc.tag',
     NOTIFICATION: 'http://tizen.org/privilege/notification',
     PACKAGE_INFO: 'http://tizen.org/privilege/packagemanager.info',
-    PACKAGEMANAGER_INSTALL: 'http://tizen.org/privilege/packagemanager.admin',
-    POWER: 'http://tizen.org/privilege/display',
+    PACKAGEMANAGER_INSTALL: 'http://tizen.org/privilege/packagemanager.install',
+    POWER: 'http://tizen.org/privilege/power',
     PUSH: 'http://tizen.org/privilege/push',
     SECUREELEMENT: 'http://tizen.org/privilege/secureelement',
-    SETTING: 'http://tizen.org/privilege/systemsettings.admin',
-    SYSTEM: 'http://tizen.org/privilege/telephony',
+    SETTING_ADMIN: 'http://tizen.org/privilege/systemsettings.admin',
+    SETTING: 'http://tizen.org/privilege/setting',
+    SYSTEM: 'http://tizen.org/privilege/system',
     SYSTEMMANAGER: 'http://tizen.org/privilege/systemmanager',
     TELEPHONY: 'http://tizen.org/privilege/telephony',
-    VOLUME_SET: 'http://tizen.org/privilege/volume.set'
+    VOLUME_SET: 'http://tizen.org/privilege/volume.set',
+    WEBSETTING: 'http://tizen.org/privilege/websetting'
   };
 
   Object.freeze(privilege);
index 96a7e4e..be751ee 100644 (file)
@@ -6,8 +6,6 @@
 #include <sys/types.h>
 #include <utility>
 #include <unistd.h>
-#include <app_manager.h>
-#include <pkgmgr-info.h>
 
 #include "common/logger.h"
 #include "common/scope_exit.h"
@@ -44,63 +42,11 @@ UtilsInstance::UtilsInstance() {
 void UtilsInstance::GetPkgApiVersion(const picojson::value& args, picojson::object& out) {
   LoggerD("Entered");
 
-  char* app_id = nullptr;
-  char* pkgid = nullptr;
-  app_info_h app_handle = nullptr;
-  pkgmgrinfo_pkginfo_h pkginfo_handle = nullptr;
-  char *api_version = nullptr;
-
-  SCOPE_EXIT {
-    if (app_id) {
-      free(app_id);
-    }
-    if (pkgid) {
-      free(pkgid);
-    }
-    if (app_handle) {
-      app_info_destroy(app_handle);
-    }
-    if (pkginfo_handle) {
-      pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_handle);
-    }
-  };
-
-  pid_t pid = getpid();
-  int ret = app_manager_get_app_id(pid, &app_id);
-  if (ret != APP_MANAGER_ERROR_NONE) {
-    LoggerE("Failed to get app id");
-    ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get app id"), &out);
-    return;
-  }
-
-  ret = app_info_create(app_id, &app_handle);
-  if (ret != APP_MANAGER_ERROR_NONE) {
-    LoggerE("Fail to get app info");
-    ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Fail to get app info"), &out);
-    return;
+  std::string api_version;
+  PlatformResult ret = common::tools::GetPkgApiVersion(&api_version);
+  if (ret.IsError()) {
+    ReportError(ret, &out);
   }
-
-  ret = app_info_get_package(app_handle, &pkgid);
-  if ((ret != APP_MANAGER_ERROR_NONE) || (pkgid == nullptr)) {
-    LoggerE("Fail to get pkg id");
-    ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Fail to get pkg id"), &out);
-    return;
-  }
-
-  ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, getuid(), &pkginfo_handle);
-  if (ret != PMINFO_R_OK) {
-    LoggerE("Fail to get pkginfo_h");
-    ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Fail to get pkginfo_h"), &out);
-    return;
-  }
-
-  ret = pkgmgrinfo_pkginfo_get_api_version(pkginfo_handle, &api_version);
-  if (ret != PMINFO_R_OK) {
-    LoggerE("Fail to get api version");
-    ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Fail to get api version"), &out);
-    return;
-  }
-
   ReportSuccess(picojson::value(api_version), out);
 }
 
diff --git a/src/widgetservice/widgetservice.gyp b/src/widgetservice/widgetservice.gyp
new file mode 100644 (file)
index 0000000..371f8eb
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  'includes':[
+    '../common/common.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'tizen_widgetservice',
+      'type': 'loadable_module',
+      'dependencies': [
+        '../common/common.gyp:tizen_common',
+      ],
+      'sources': [
+        'widgetservice_api.js',
+        'widgetservice_extension.cc',
+        'widgetservice_extension.h',
+        'widgetservice_instance.cc',
+        'widgetservice_instance.h',
+        'widgetservice_utils.cc',
+        'widgetservice_utils.h',
+      ],
+      'conditions': [
+        ['tizen == 1', {
+          'variables': {
+            'packages': [
+              'widget_service',
+            ]
+          },
+        }],
+      ],
+    },
+  ],
+}
diff --git a/src/widgetservice/widgetservice_api.js b/src/widgetservice/widgetservice_api.js
new file mode 100755 (executable)
index 0000000..9435b50
--- /dev/null
@@ -0,0 +1,489 @@
+/*
+ * 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.
+ */
+
+var validator = xwalk.utils.validator;
+var converter = xwalk.utils.converter;
+var types = validator.Types;
+var T = xwalk.utils.type;
+var native = new xwalk.utils.NativeManager(extension);
+
+var WidgetSizeType = {
+  S_1x1 : '1x1',
+  S_2x1 : '2x1',
+  S_2x2 : '2x2',
+  S_4x1 : '4x1',
+  S_4x2 : '4x2',
+  S_4x3 : '4x3',
+  S_4x4 : '4x4',
+  S_4x5 : '4x5',
+  S_4x6 : '4x6',
+  EASY_1x1 : 'EASY_1x1',
+  EASY_3x1 : 'EASY_3x1',
+  EASY_3x3 : 'EASY_3x3',
+  FULL : 'FULL',
+};
+
+function createObjects(data, func, widget) {
+  var array = [];
+  var objects = native.getResultObject(data);
+
+  objects.forEach(function (d) {
+    array.push(new func(d, widget));
+  });
+
+  return array;
+};
+
+function WidgetSize(data) {
+  Object.defineProperties(this, {
+    width: {
+      value: data.width,
+      writable: false,
+      enumerable: true
+    },
+    height: {
+      value: data.height,
+      writable: false,
+      enumerable: true
+    },
+  });
+};
+
+function WidgetVariant(data) {
+  Object.defineProperties(this, {
+    sizeType: {
+      value: data.sizeType,
+      writable: false,
+      enumerable: true
+    },
+    width: {
+      value: data.width,
+      writable: false,
+      enumerable: true
+    },
+    height: {
+      value: data.height,
+      writable: false,
+      enumerable: true
+    },
+    previewImagePath: {
+      value: data.previewImagePath,
+      writable: false,
+      enumerable: true
+    },
+    needsMouseEvents: {
+      value: data.needsMouseEvents,
+      writable: false,
+      enumerable: true
+    },
+    needsTouchEffect: {
+      value: data.needsTouchEffect,
+      writable: false,
+      enumerable: true
+    },
+    needsFrame: {
+      value: data.needsFrame,
+      writable: false,
+      enumerable: true
+    },
+  });
+};
+
+function WidgetInstance(data, widget) {
+  Object.defineProperties(this, {
+    widget: {
+      value: widget,
+      writable: false,
+      enumerable: true
+    },
+    id: {
+      value: data.id,
+      writable: false,
+      enumerable: true
+    },
+  });
+};
+
+WidgetInstance.prototype.changeUpdatePeriod = function() {
+  var args = validator.validateMethod(arguments, [{
+    name : 'period',
+    type : types.DOUBLE,
+  }]);
+
+  var callArgs = {};
+  callArgs.widgetId = this.widget.id;
+  callArgs.instanceId = this.id;
+  callArgs.period = args.period;
+
+  var ret = native.callSync('WidgetInstance_changeUpdatePeriod', callArgs);
+
+  if (native.isFailure(ret)) {
+    throw native.getErrorObject(ret);
+  }
+};
+
+WidgetInstance.prototype.sendContent = function() {
+  var args = validator.validateMethod(arguments, [{
+    name : 'data',
+    type: types.DICTIONARY,
+  }, {
+    name : 'force',
+    type : types.BOOLEAN,
+  }]);
+
+  var callArgs = {};
+  callArgs.widgetId = this.widget.id;
+  callArgs.instanceId = this.id;
+  callArgs.data = args.data;
+  callArgs.force = args.force;
+
+  var ret = native.callSync('WidgetInstance_sendContent', callArgs);
+
+  if (native.isFailure(ret)) {
+    throw native.getErrorObject(ret);
+  }
+};
+
+WidgetInstance.prototype.getContent = function() {
+  var args = validator.validateMethod(arguments, [{
+    name : 'successCallback',
+    type : types.FUNCTION,
+  }, {
+    name : 'errorCallback',
+    type : types.FUNCTION,
+  }]);
+
+  var callArgs = {};
+  callArgs.widgetId = this.widget.id;
+  callArgs.instanceId = this.id;
+
+  var callback = function(result) {
+    if (native.isFailure(result)) {
+      args.errorCallback(native.getErrorObject(result));
+    } else {
+      //TODO what is type of returned data
+      args.successCallback(native.getResultObject(result));
+    }
+  };
+
+  var result = native.call('WidgetInstance_getContent', callArgs, callback);
+  if (native.isFailure(result)) {
+    throw native.getErrorObject(result);
+  }
+};
+
+function Widget(data) {
+  Object.defineProperties(this, {
+    id: {
+      value: data.id,
+      writable: false,
+      enumerable: true
+    },
+    applicationId: {
+      value: data.applicationId,
+      writable: false,
+      enumerable: true
+    },
+    setupApplicationId: {
+      value: data.setupApplicationId ? data.setupApplicationId : null,
+      writable: false,
+      enumerable: true
+    },
+    packageId: {
+      value: data.packageId,
+      writable: false,
+      enumerable: true
+    },
+    noDisplay: {
+      value: data.noDisplay,
+      writable: false,
+      enumerable: true
+    },
+  });
+};
+
+Widget.prototype.getName = function() {
+  var args = validator.validateMethod(arguments, [{
+    name : 'lang',
+    type : types.STRING,
+    optional : true,
+    nullable : true
+  }]);
+
+  var callArgs = {};
+  callArgs.widgetId = this.id;
+
+  if (args.lang) {
+    callArgs.lang = args.lang;
+  }
+
+  var ret = native.callSync('Widget_getName', callArgs);
+
+  if (native.isFailure(ret)) {
+    throw native.getErrorObject(ret);
+  } else {
+    return native.getResultObject(ret);
+  }
+};
+
+Widget.prototype.getInstances = function() {
+  var args = validator.validateMethod(arguments, [{
+    name : 'successCallback',
+    type : types.FUNCTION,
+  }, {
+    name : 'errorCallback',
+    type : types.FUNCTION,
+    optional : true,
+    nullable : true
+  }]);
+
+  var callback = function(result) {
+    if (native.isFailure(result)) {
+      native.callIfPossible(args.errorCallback, native.getErrorObject(result));
+    } else {
+      var instances = createObjects(result, WidgetInstance, this);
+      args.successCallback(instances);
+    }
+  }.bind(this);
+
+  var callArgs = {};
+  callArgs.widgetId = this.id;
+
+  var result = native.call('Widget_getInstances', callArgs, callback);
+  if (native.isFailure(result)) {
+    throw native.getErrorObject(result);
+  }
+};
+
+Widget.prototype.getVariant = function() {
+  var args = validator.validateMethod(arguments, [{
+    name : 'sizeType',
+    type: types.ENUM,
+    values: T.getValues(WidgetSizeType)
+  }]);
+
+  var callArgs = {};
+  callArgs.widgetId = this.id;
+  callArgs.sizeType = args.sizeType;
+
+  var ret = native.callSync('Widget_getVariant', callArgs);
+
+  if (native.isFailure(ret)) {
+    throw native.getErrorObject(ret);
+  } else {
+    return new WidgetVariant(native.getResultObject(ret));
+  }
+};
+
+Widget.prototype.getVariants = function() {
+  var args = validator.validateMethod(arguments, [{
+    name : 'successCallback',
+    type : types.FUNCTION,
+  }, {
+    name : 'errorCallback',
+    type : types.FUNCTION,
+    optional : true,
+    nullable : true
+  }]);
+
+  var callback = function(result) {
+    if (native.isFailure(result)) {
+      native.callIfPossible(args.errorCallback, native.getErrorObject(result));
+    } else {
+      var variants = createObjects(result, WidgetVariant);
+      args.successCallback(variants);
+    }
+  };
+
+  var callArgs = {};
+  callArgs.widgetId = this.id;
+
+  var result = native.call('Widget_getVariants', callArgs, callback);
+  if (native.isFailure(result)) {
+    throw native.getErrorObject(result);
+  }
+};
+
+function ListenerManager(native, listenerName) {
+  this.listeners = {};
+  this.nextId = 1;
+  this.nativeSet = false;
+  this.native = native;
+  this.listenerName = listenerName;
+};
+
+ListenerManager.prototype.onListenerCalled = function(msg) {
+  for (var watchId in this.listeners) {
+    if (this.listeners.hasOwnProperty(watchId) && this.listeners[watchId][msg.action]) {
+      this.listeners[watchId](this.native.getResultObject(msg));
+    }
+  }
+};
+
+ListenerManager.prototype.addListener = function(callback) {
+  var id = this.nextId;
+  if (!this.nativeSet) {
+    this.native.addListener(this.listenerName, this.onListenerCalled.bind(this));
+    this.nativeSet = true;
+  }
+  this.listeners[id] = callback;
+  ++this.nextId;
+  return id;
+};
+
+ListenerManager.prototype.removeListener = function(watchId) {
+  if (this.listeners[watchId] === null || this.listeners[watchId] === undefined) {
+    throw new WebAPIException(0, 'Watch id not found.', 'NotFoundError');
+  }
+
+  if (this.listeners.hasOwnProperty(watchId)) {
+    delete this.listeners[watchId];
+  }
+};
+
+var WIDGET_CHANGE_LISTENER = 'WidgetChangeCallback';
+var widgetChangeListener = new ListenerManager(native, WIDGET_CHANGE_LISTENER);
+
+Widget.prototype.addChangeListener = function() {
+  var args = validator.validateMethod(arguments, [{
+    name : 'eventCallback',
+    type : types.FUNCTION,
+  }]);
+
+  var result = native.callSync('Widget_addChangeListener', {widgetId : this.id});
+  if (native.isFailure(result)) {
+    throw native.getErrorObject(result);
+  }
+
+  var func = function(msg) {
+    if (msg.widgetId === this.id) {
+      args.eventCallback(msg.instanceId, msg.event);
+    }
+  }.bind(this);
+
+  return widgetChangeListener.addListener(func);
+};
+
+Widget.prototype.removeChangeListener = function() {
+  var args = validator.validateMethod(arguments, [{
+    name : 'watchId',
+    type : types.LONG,
+  }]);
+
+  widgetChangeListener.removeListener(args.watchId);
+
+  var result = native.callSync('Widget_removeChangeListener', {widgetId : this.id});
+  if (native.isFailure(result)) {
+    throw native.getErrorObject(result);
+  }
+};
+
+function WidgetServiceManager() {
+};
+
+WidgetServiceManager.prototype.getWidget = function() {
+  var args = validator.validateMethod(arguments, [{
+    name : 'widgetId',
+    type : types.STRING,
+  }]);
+
+  var callArgs = {};
+  callArgs.widgetId = args.widgetId;
+
+  var ret = native.callSync('WidgetServiceManager_getWidget', callArgs);
+
+  if (native.isFailure(ret)) {
+    throw native.getErrorObject(ret);
+  } else {
+    return new Widget(native.getResultObject(ret));
+  }
+};
+
+WidgetServiceManager.prototype.getWidgets = function() {
+  var args = validator.validateMethod(arguments, [{
+    name : 'successCallback',
+    type : types.FUNCTION,
+  }, {
+    name : 'errorCallback',
+    type : types.FUNCTION,
+    optional : true,
+    nullable : true
+  }, {
+    name : 'packageId',
+    type : types.STRING,
+    optional : true,
+    nullable : true
+  }]);
+
+  var callback = function(result) {
+    if (native.isFailure(result)) {
+      native.callIfPossible(args.errorCallback, native.getErrorObject(result));
+    } else {
+      var widgets = createObjects(result, Widget);
+      args.successCallback(widgets);
+    }
+  };
+
+  var callArgs = {};
+  if (args.packageId) {
+    callArgs.packageId = args.packageId;
+  }
+
+  var result = native.call('WidgetServiceManager_getWidgets', callArgs, callback);
+  if (native.isFailure(result)) {
+    throw native.getErrorObject(result);
+  }
+};
+
+WidgetServiceManager.prototype.getPrimaryWidgetId = function() {
+  var args = validator.validateMethod(arguments, [{
+    name : 'id',
+    type : types.STRING,
+  }]);
+
+  var callArgs = {};
+  callArgs.id = args.id;
+
+  var ret = native.callSync('WidgetServiceManager_getPrimaryWidgetId', callArgs);
+
+  if (native.isFailure(ret)) {
+    throw native.getErrorObject(ret);
+  } else {
+    return native.getResultObject(ret);
+  }
+};
+
+WidgetServiceManager.prototype.getSize = function() {
+  var args = validator.validateMethod(arguments, [{
+    name : 'sizeType',
+    type: types.ENUM,
+    values: T.getValues(WidgetSizeType)
+  }]);
+
+  var callArgs = {};
+  callArgs.sizeType = args.sizeType;
+
+  var ret = native.callSync('WidgetServiceManager_getSize', callArgs);
+
+  if (native.isFailure(ret)) {
+    throw native.getErrorObject(ret);
+  } else {
+    return new WidgetSize(native.getResultObject(ret));
+  }
+};
+
+//Exports
+exports = new WidgetServiceManager();
diff --git a/src/widgetservice/widgetservice_extension.cc b/src/widgetservice/widgetservice_extension.cc
new file mode 100755 (executable)
index 0000000..9bdbfca
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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 "widgetservice/widgetservice_extension.h"
+
+#include "widgetservice/widgetservice_instance.h"
+
+// This will be generated from widget_api.js
+extern const char kSource_widgetservice_api[];
+
+common::Extension* CreateExtension() {
+  return new WidgetExtension;
+}
+
+WidgetExtension::WidgetExtension() {
+  SetExtensionName("tizen.widgetservice");
+  SetJavaScriptAPI(kSource_widgetservice_api);
+}
+
+WidgetExtension::~WidgetExtension() {}
+
+common::Instance* WidgetExtension::CreateInstance() {
+  return new extension::widgetservice::WidgetServiceInstance();
+}
diff --git a/src/widgetservice/widgetservice_extension.h b/src/widgetservice/widgetservice_extension.h
new file mode 100755 (executable)
index 0000000..db83db2
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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 WIDGETSERVICE_WIDGET_EXTENSION_H_
+#define WIDGETSERVICE_WIDGET_EXTENSION_H_
+
+#include "common/extension.h"
+
+class WidgetExtension : public common::Extension {
+ public:
+  WidgetExtension();
+  virtual ~WidgetExtension();
+
+ private:
+  virtual common::Instance* CreateInstance();
+};
+
+#endif  // WIDGETSERVICE_WIDGET_EXTENSION_H_
diff --git a/src/widgetservice/widgetservice_instance.cc b/src/widgetservice/widgetservice_instance.cc
new file mode 100755 (executable)
index 0000000..81ac3c9
--- /dev/null
@@ -0,0 +1,613 @@
+/*
+ * 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 "widgetservice/widgetservice_instance.h"
+
+#include <thread>
+
+#include <widget_service.h>
+#include <widget_errno.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+
+#include "widgetservice/widgetservice_utils.h"
+#include "common/scope_exit.h"
+
+namespace extension {
+namespace widgetservice {
+
+using common::TizenResult;
+using common::TizenSuccess;
+
+std::mutex WidgetServiceInstance::listener_mutex_;
+
+namespace {
+const common::ListenerToken kWidgetChangeCallbackToken{"WidgetChangeCallback"};
+
+const std::string kPrivilegeWidget = "http://tizen.org/privilege/widget.viewer";
+
+const std::string kLang = "lang";
+const std::string kInstanceId = "instanceId";
+const std::string kPeriod = "period";
+const std::string kForce = "force";
+const std::string kData = "data";
+const std::string kEvent = "event";
+
+int WidgetListCb(const char* pkgid, const char* widget_id, int is_primary, void* data) {
+  ScopeLogger();
+
+  //is_primary is not supported by native api
+  picojson::array* array = static_cast<picojson::array*>(data);
+
+  if (!array) {
+    LoggerW("User data is null");
+    return WIDGET_ERROR_NONE;
+  }
+
+  picojson::value val = picojson::value(picojson::object());
+
+  auto result = WidgetServiceUtils::WidgetToJson(widget_id, &val.get<picojson::object>(), pkgid);
+  if (result) {
+    array->push_back(val);
+  }
+
+  return WIDGET_ERROR_NONE;
+}
+
+int WidgetListByPkgIdCb(const char* widget_id, int is_primary, void* data) {
+  ScopeLogger();
+
+  //is_primary is not supported by native api
+  picojson::array* array = static_cast<picojson::array*>(data);
+
+  if (!array) {
+    LoggerW("User data is null");
+    return WIDGET_ERROR_NONE;
+  }
+
+  picojson::value val = picojson::value(picojson::object());
+
+  auto result = WidgetServiceUtils::WidgetToJson(widget_id, &val.get<picojson::object>());
+  if (result) {
+    array->push_back(val);
+  }
+
+  return WIDGET_ERROR_NONE;
+}
+
+int WidgetInstanceCb(const char* widget_id, const char* instance_id, void* data) {
+  ScopeLogger();
+
+  picojson::array* array = static_cast<picojson::array*>(data);
+
+  if (!array) {
+    LoggerW("User data is null");
+    return WIDGET_ERROR_NONE;
+  }
+
+  array->push_back(picojson::value(instance_id));
+
+  return WIDGET_ERROR_NONE;
+}
+
+int WidgetLifecycleCb(const char* widget_id, widget_lifecycle_event_e lifecycle_event,
+                      const char* widget_instance_id, void* data) {
+  ScopeLogger();
+
+  //WIDGET_LIFE_CYCLE_EVENT_MAX event is not supported
+  if (WIDGET_LIFE_CYCLE_EVENT_RESUME < lifecycle_event) {
+    LoggerW("Unknown event type");
+    return WIDGET_ERROR_NONE;
+  }
+
+  WidgetServiceInstance* instance = static_cast<WidgetServiceInstance*>(data);
+
+  if (!instance) {
+    LoggerW("User data is null");
+    return WIDGET_ERROR_NONE;
+  }
+
+  picojson::value response = picojson::value(picojson::object());
+  auto& obj = response.get<picojson::object>();
+
+  obj.insert(std::make_pair(kWidgetId, picojson::value(widget_id)));
+  obj.insert(std::make_pair(kInstanceId, picojson::value(widget_instance_id)));
+  obj.insert(std::make_pair(kEvent, picojson::value(WidgetServiceUtils::FromEventType(lifecycle_event))));
+
+  instance->CallWidgetLifecycleListener(widget_id, response);
+
+  return WIDGET_ERROR_NONE;
+}
+
+}  // namespace
+
+WidgetServiceInstance::WidgetServiceInstance() {
+  ScopeLogger();
+  using std::placeholders::_1;
+  using std::placeholders::_2;
+
+#define REGISTER_SYNC(c, x) \
+  RegisterSyncHandler(c, std::bind(&WidgetServiceInstance::x, this, _1));
+
+  REGISTER_SYNC("WidgetServiceManager_getWidget", GetWidget);
+  REGISTER_SYNC("WidgetServiceManager_getPrimaryWidgetId", GetPrimaryWidgetId);
+  REGISTER_SYNC("WidgetServiceManager_getSize", GetSize);
+  REGISTER_SYNC("Widget_getName", GetName);
+  REGISTER_SYNC("Widget_getVariant", GetVariant);
+  REGISTER_SYNC("Widget_addChangeListener", AddChangeListener);
+  REGISTER_SYNC("Widget_removeChangeListener", RemoveChangeListener);
+  REGISTER_SYNC("WidgetInstance_changeUpdatePeriod", ChangeUpdatePeriod);
+  REGISTER_SYNC("WidgetInstance_sendContent", SendContent);
+
+#undef REGISTER_SYNC
+
+#define REGISTER_ASYNC(c, x) \
+  RegisterHandler(c, std::bind(&WidgetServiceInstance::x, this, _1, _2));
+
+  REGISTER_ASYNC("WidgetServiceManager_getWidgets", GetWidgets);
+  REGISTER_ASYNC("Widget_getInstances", GetInstances);
+  REGISTER_ASYNC("Widget_getVariants", GetVariants);
+  REGISTER_ASYNC("WidgetInstance_getContent", GetContent);
+#undef REGISTER_ASYNC
+}
+
+WidgetServiceInstance::~WidgetServiceInstance() {
+  ScopeLogger();
+
+  std::lock_guard<std::mutex> lock(listener_mutex_);
+  for (auto& it : listener_map_) {
+    int ret = widget_service_unset_lifecycle_event_cb(it.first.c_str(), nullptr);
+    if (WIDGET_ERROR_NONE != ret) {
+      LoggerE("widget_service_unset_lifecycle_event_cb() failed");
+    }
+  }
+
+  listener_map_.clear();
+}
+
+TizenResult WidgetServiceInstance::GetWidget(const picojson::object& args) {
+  ScopeLogger();
+
+  //CHECK_PRIVILEGE_ACCESS(kPrivilegeWidget, &out);
+  CHECK_EXIST(args, kWidgetId, out)
+
+  const auto& widget_id = args.find(kWidgetId)->second.get<std::string>();
+
+  picojson::value value {picojson::object{}};
+  auto* obj = &value.get<picojson::object>();
+
+  auto result = WidgetServiceUtils::WidgetToJson(widget_id.c_str(), obj);
+  if (!result) {
+    LogAndReturnTizenError(result, ("GetWidget() failed"));
+  }
+
+  return TizenSuccess(value);
+}
+
+TizenResult WidgetServiceInstance::GetWidgets(const picojson::object& args,
+                                               const common::AsyncToken& token) {
+  ScopeLogger();
+
+  //CHECK_PRIVILEGE_ACCESS(kPrivilegeWidget, &out);
+
+  std::string pkgid;
+  const auto id = args.find(kPackageId);
+  if (args.end() != id) {
+    pkgid = id->second.get<std::string>();
+  }
+
+  auto get_widgets = [this, pkgid](const common::AsyncToken& token) -> void {
+    int ret = WIDGET_ERROR_NONE;
+    picojson::value response{picojson::array{}};
+    auto* array = &response.get<picojson::array>();
+
+    if (pkgid.empty()) {
+      ret = widget_service_get_widget_list(WidgetListCb, array);
+    } else {
+      ret = widget_service_get_widget_list_by_pkgid(pkgid.c_str(), WidgetListByPkgIdCb, array);
+    }
+
+    TizenResult result = TizenSuccess();
+
+    if (WIDGET_ERROR_NONE != ret) {
+      LoggerE("widget_service_get_widget_list() failed");
+      result = WidgetServiceUtils::ConvertErrorCode(ret);
+    } else {
+      result = TizenSuccess{response};
+    }
+
+    this->Post(token, result);
+  };
+
+  std::thread(get_widgets, token).detach();
+
+  return TizenSuccess();
+}
+
+TizenResult WidgetServiceInstance::GetPrimaryWidgetId(const picojson::object& args) {
+  ScopeLogger();
+
+  //CHECK_PRIVILEGE_ACCESS(kPrivilegeWidget, &out);
+  CHECK_EXIST(args, kId, out)
+
+  const auto& id = args.find(kId)->second.get<std::string>();
+
+  char* widget_id = widget_service_get_widget_id(id.c_str());
+  if (!widget_id) {
+    LogAndReturnTizenError(
+        WidgetServiceUtils::ConvertErrorCode(get_last_result()), ("widget_service_get_widget_id() failed"));
+  }
+
+  SCOPE_EXIT {
+    free(widget_id);
+  };
+
+  return TizenSuccess(picojson::value(widget_id));
+}
+
+TizenResult WidgetServiceInstance::GetSize(const picojson::object& args) {
+  ScopeLogger();
+
+  CHECK_EXIST(args, kSizeType, out)
+
+  widget_size_type_e type = WidgetServiceUtils::ToSizeType(args.find(kSizeType)->second.get<std::string>());
+  if (WIDGET_SIZE_TYPE_UNKNOWN == type) {
+    LogAndReturnTizenError(common::InvalidValuesError(), ("incorrect size type"));
+  }
+
+  picojson::value value{picojson::object{}};
+  auto* obj = &value.get<picojson::object>();
+
+  auto result = WidgetServiceUtils::SizeToJson(type, obj);
+  if (!result) {
+    LogAndReturnTizenError(result, ("GetSize() failed"));
+  }
+
+  return TizenSuccess(value);
+}
+
+TizenResult WidgetServiceInstance::GetName(picojson::object const& args) {
+  ScopeLogger();
+
+  //CHECK_PRIVILEGE_ACCESS(kPrivilegeWidget, &out);
+  CHECK_EXIST(args, kWidgetId, out)
+
+  const auto& widget_id = args.find(kWidgetId)->second.get<std::string>();
+  char* lang = nullptr;
+
+  const auto lang_it = args.find(kLang);
+  if (args.end() != lang_it) {
+    lang = const_cast<char*>(lang_it->second.get<std::string>().c_str());
+  }
+
+  char* name = widget_service_get_name(widget_id.c_str(), lang);
+  if (!name) {
+    LogAndReturnTizenError(
+        WidgetServiceUtils::ConvertErrorCode(get_last_result()), ("widget_service_get_name() failed"));
+  }
+
+  SCOPE_EXIT {
+    free(name);
+  };
+
+  return TizenSuccess(picojson::value(name));
+}
+
+TizenResult WidgetServiceInstance::GetInstances(picojson::object const& args, const common::AsyncToken& token) {
+  ScopeLogger();
+
+  CHECK_EXIST(args, kWidgetId, out)
+
+  const auto& widget_id = args.find(kWidgetId)->second.get<std::string>();
+
+  auto get_instances = [this, widget_id](const common::AsyncToken& token) -> void {
+    picojson::value response{picojson::array{}};
+    auto* array = &response.get<picojson::array>();
+
+    int ret = widget_service_get_widget_instance_list(widget_id.c_str(), WidgetInstanceCb, array);
+
+    TizenResult result = TizenSuccess();
+
+    if (WIDGET_ERROR_NONE != ret) {
+      LoggerE("widget_service_get_widget_instance_list() failed");
+      result = WidgetServiceUtils::ConvertErrorCode(ret);
+    } else {
+      result = TizenSuccess{response};
+    }
+
+    this->Post(token, result);
+  };
+
+  std::thread(get_instances, token).detach();
+
+  return TizenSuccess();
+}
+
+TizenResult WidgetServiceInstance::GetVariant(picojson::object const& args) {
+  ScopeLogger();
+
+  CHECK_EXIST(args, kWidgetId, out)
+  CHECK_EXIST(args, kSizeType, out)
+
+  const auto& widget_id = args.find(kWidgetId)->second.get<std::string>();
+  const auto& type = args.find(kSizeType)->second.get<std::string>();
+
+  widget_size_type_e size_type = WidgetServiceUtils::ToSizeType(type);
+  if (WIDGET_SIZE_TYPE_UNKNOWN == size_type) {
+    LogAndReturnTizenError(common::InvalidValuesError(), ("incorrect size type"));
+  }
+
+  picojson::value value{picojson::object{}};
+  auto* obj = &value.get<picojson::object>();
+
+  auto result = WidgetServiceUtils::SizeToJson(size_type, obj);
+  if (!result) {
+    LogAndReturnTizenError(result, ("GetVariant() failed"));
+  }
+
+  result = WidgetServiceUtils::WidgetVariantToJson(widget_id.c_str(), size_type, obj);
+  if (!result) {
+    LogAndReturnTizenError(result, ("GetVariant() failed"));
+  }
+
+  //sizeType
+  obj->insert(std::make_pair(kSizeType, picojson::value(type)));
+
+  return TizenSuccess(value);
+}
+
+TizenResult WidgetServiceInstance::GetVariants(picojson::object const& args, const common::AsyncToken& token) {
+  ScopeLogger();
+
+  //CHECK_PRIVILEGE_ACCESS(kPrivilegeWidget, &out);
+  CHECK_EXIST(args, kWidgetId, out)
+
+  const auto& widget_id = args.find(kWidgetId)->second.get<std::string>();
+
+  auto get_variants = [this, widget_id](const common::AsyncToken& token) -> void {
+    int count = 0;
+    int* type_array = nullptr;
+    int ret = widget_service_get_supported_size_types(widget_id.c_str(), &count, &type_array);
+
+    if (WIDGET_ERROR_NONE != ret) {
+      LoggerE("widget_service_get_supported_size_types() failed");
+      this->Post(token, WidgetServiceUtils::ConvertErrorCode(ret));
+      return;
+    }
+
+    //it is not mentioned in header file if array should be freed by caller
+    //but in widget_service_get_supported_size_types definition it is allocated
+    //so it should be released when it is not needed anymore
+    SCOPE_EXIT {
+      free(type_array);
+    };
+
+    TizenResult result = TizenSuccess();
+    picojson::value response{picojson::array{}};
+    auto& array = response.get<picojson::array>();
+
+    for (int i = 0; i < count; i++) {
+      picojson::value val = picojson::value(picojson::object());
+      picojson::object* obj = &val.get<picojson::object>();
+
+      widget_size_type_e size_type = static_cast<widget_size_type_e>(type_array[i]);
+      result = WidgetServiceUtils::SizeToJson(size_type, obj);
+      if (!result) {
+        break;
+      }
+
+      result = WidgetServiceUtils::WidgetVariantToJson(widget_id.c_str(), size_type, obj);
+      if (!result) {
+        break;
+      }
+
+      obj->insert(std::make_pair(kSizeType, picojson::value(WidgetServiceUtils::FromSizeType(size_type))));
+      array.push_back(val);
+    }
+
+    if (!result) {
+      this->Post(token, result);
+    } else {
+      this->Post(token, TizenSuccess{response});
+    }
+  };
+
+  std::thread(get_variants, token).detach();
+
+  return TizenSuccess();
+}
+
+void WidgetServiceInstance::CallWidgetLifecycleListener(const std::string& widget_id,
+                                                 const picojson::value& response) {
+  ScopeLogger();
+
+  std::lock_guard<std::mutex> lock(listener_mutex_);
+  const auto it = listener_map_.find(widget_id);
+  if (listener_map_.end() != it) {
+    Post(kWidgetChangeCallbackToken, TizenSuccess{response});
+    return;
+  }
+
+  LoggerW("widget id was not found.");
+}
+
+TizenResult WidgetServiceInstance::AddChangeListener(picojson::object const& args) {
+  ScopeLogger();
+
+  //CHECK_PRIVILEGE_ACCESS(kPrivilegeWidget, &out);
+  CHECK_EXIST(args, kWidgetId, out)
+
+  const auto& widget_id = args.find(kWidgetId)->second.get<std::string>();
+
+  std::lock_guard<std::mutex> lock(listener_mutex_);
+  auto it = listener_map_.find(widget_id);
+  if (listener_map_.end() != it) {
+    it->second++;
+    return TizenSuccess();
+  }
+
+  int ret = widget_service_set_lifecycle_event_cb(widget_id.c_str(), WidgetLifecycleCb , this);
+  if (WIDGET_ERROR_NONE != ret) {
+    LogAndReturnTizenError(
+        WidgetServiceUtils::ConvertErrorCode(ret), ("widget_service_set_lifecycle_event_cb() failed"));
+  }
+
+  listener_map_[widget_id]++;
+
+  return TizenSuccess();
+}
+
+TizenResult WidgetServiceInstance::RemoveChangeListener(picojson::object const& args) {
+  ScopeLogger();
+
+  CHECK_EXIST(args, kWidgetId, out)
+
+  const auto& widget_id = args.find(kWidgetId)->second.get<std::string>();
+
+  std::lock_guard<std::mutex> lock(listener_mutex_);
+  auto it = listener_map_.find(widget_id);
+  if (listener_map_.end() == it) {
+    LoggerW("Listener id not found");
+    return TizenSuccess();
+  }
+
+  if (!(--it->second)) {
+    int ret = widget_service_unset_lifecycle_event_cb(widget_id.c_str(), nullptr);
+    if (WIDGET_ERROR_NONE != ret) {
+      LogAndReturnTizenError(
+          WidgetServiceUtils::ConvertErrorCode(ret), ("widget_service_unset_lifecycle_event_cb() failed"));
+    }
+    listener_map_.erase(it);
+  }
+
+  return TizenSuccess();
+}
+
+TizenResult WidgetServiceInstance::ChangeUpdatePeriod(picojson::object const& args) {
+  ScopeLogger();
+
+  CHECK_EXIST(args, kWidgetId, out)
+  CHECK_EXIST(args, kInstanceId, out)
+  CHECK_EXIST(args, kPeriod, out)
+
+  const auto& widget_id = args.find(kWidgetId)->second.get<std::string>();
+  const auto& instance_id = args.find(kInstanceId)->second.get<std::string>();
+  const double period = args.find(kPeriod)->second.get<double>();
+
+  int ret = widget_service_change_period(widget_id.c_str(), instance_id.c_str(), period);
+
+  if (WIDGET_ERROR_NONE != ret) {
+    LogAndReturnTizenError(
+        WidgetServiceUtils::ConvertErrorCode(ret), ("widget_service_change_period() failed"));
+  }
+
+  return TizenSuccess();
+}
+
+TizenResult WidgetServiceInstance::SendContent(picojson::object const& args) {
+  ScopeLogger();
+
+  CHECK_EXIST(args, kWidgetId, out)
+  CHECK_EXIST(args, kInstanceId, out)
+  CHECK_EXIST(args, kData, out)
+  CHECK_EXIST(args, kForce, out)
+
+  const auto& widget_id = args.find(kWidgetId)->second.get<std::string>();
+  const auto& instance_id = args.find(kInstanceId)->second.get<std::string>();
+  const int force = args.find(kForce)->second.get<bool>() ? 1 : 0;
+
+  bundle* data = bundle_create();
+  int ret = get_last_result();
+  if (BUNDLE_ERROR_NONE != ret) {
+    LogAndReturnTizenError(common::AbortError(ret), ("bundle_create() failed"));
+  }
+
+  SCOPE_EXIT {
+    bundle_free(data);
+  };
+
+  ret = bundle_add(data, kData.c_str(), args.find(kData)->second.serialize().c_str());
+  if (BUNDLE_ERROR_NONE != ret) {
+    LogAndReturnTizenError(common::AbortError(ret), ("bundle_add() failed"));
+  }
+
+  ret = widget_service_trigger_update(widget_id.c_str(), instance_id.c_str(), data, force);
+  if (WIDGET_ERROR_NONE != ret) {
+    LogAndReturnTizenError(
+        WidgetServiceUtils::ConvertErrorCode(ret), ("widget_service_trigger_update() failed"));
+  }
+
+  return TizenSuccess();
+}
+
+TizenResult WidgetServiceInstance::GetContent(picojson::object const& args, const common::AsyncToken& token) {
+  ScopeLogger();
+
+  CHECK_EXIST(args, kWidgetId, out)
+  CHECK_EXIST(args, kInstanceId, out)
+
+  const auto& widget_id = args.find(kWidgetId)->second.get<std::string>();
+  const auto& instance_id = args.find(kInstanceId)->second.get<std::string>();
+
+  auto get_content = [this, widget_id, instance_id](const common::AsyncToken& token) -> void {
+    bundle* bundle_data = bundle_create();
+
+    int ret = get_last_result();
+    if (BUNDLE_ERROR_NONE != ret) {
+      LoggerE("bundle_create() failed");
+      this->Post(token, common::AbortError(ret));
+      return;
+    }
+
+    SCOPE_EXIT {
+      bundle_free(bundle_data);
+    };
+
+    ret = widget_service_get_content_of_widget_instance(widget_id.c_str(),
+                                                        instance_id.c_str(), &bundle_data);
+    if (WIDGET_ERROR_NONE != ret) {
+      LoggerE("widget_service_get_content_of_widget_instance() failed");
+      this->Post(token, WidgetServiceUtils::ConvertErrorCode(ret));
+      return;
+    }
+
+    char* data_str = nullptr;
+    ret = bundle_get_str(bundle_data, kData.c_str(), &data_str);
+    if (BUNDLE_ERROR_NONE != ret) {
+      LoggerE("bundle_get_str() failed");
+      this->Post(token, common::AbortError(ret));
+      return;
+    }
+
+    picojson::value response;
+    std::string err;
+    picojson::parse(response, data_str, data_str + strlen(data_str), &err);
+    if (!err.empty()) {
+      LoggerE("Failed to parse bundle data() failed [%s]", err.c_str());
+      this->Post(token, common::AbortError());
+      return;
+    }
+
+    this->Post(token, TizenSuccess{response});
+  };
+
+  std::thread(get_content, token).detach();
+
+  return TizenSuccess();
+}
+
+} // namespace widgetservice
+} // namespace extension
diff --git a/src/widgetservice/widgetservice_instance.h b/src/widgetservice/widgetservice_instance.h
new file mode 100755 (executable)
index 0000000..8aadbfa
--- /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.
+ */
+
+#ifndef WIDGETSERVICE_WIDGET_INSTANCE_H_
+#define WIDGETSERVICE_WIDGET_INSTANCE_H_
+
+#include <mutex>
+#include <map>
+
+#include "common/tizen_instance.h"
+
+namespace extension {
+namespace widgetservice {
+
+class WidgetServiceInstance : public common::TizenInstance {
+ public:
+  WidgetServiceInstance();
+  virtual ~WidgetServiceInstance();
+  void CallWidgetLifecycleListener(const std::string& widget_id, const picojson::value& response);
+ private:
+  //WidgetManager
+  common::TizenResult GetWidget(picojson::object const& args);
+  common::TizenResult GetWidgets(picojson::object const& args, const common::AsyncToken& token);
+  common::TizenResult GetPrimaryWidgetId(picojson::object const& args);
+  common::TizenResult GetSize(picojson::object const& args);
+  //Widget
+  common::TizenResult GetName(picojson::object const& args);
+  common::TizenResult GetInstances(picojson::object const& args, const common::AsyncToken& token);
+  common::TizenResult GetVariant(picojson::object const& args);
+  common::TizenResult GetVariants(picojson::object const& args, const common::AsyncToken& token);
+  common::TizenResult AddChangeListener(picojson::object const& args);
+  common::TizenResult RemoveChangeListener(picojson::object const& args);
+  //WidgetInstance
+  common::TizenResult ChangeUpdatePeriod(picojson::object const& args);
+  common::TizenResult SendContent(picojson::object const& args);
+  common::TizenResult GetContent(picojson::object const& args, const common::AsyncToken& token);
+
+  static std::mutex listener_mutex_;
+  std::map<std::string, int> listener_map_;
+};
+
+} // namespace widgetservice
+} // namespace extension
+
+#endif // WIDGETSERVICE_WIDGET_INSTANCE_H_
diff --git a/src/widgetservice/widgetservice_utils.cc b/src/widgetservice/widgetservice_utils.cc
new file mode 100644 (file)
index 0000000..7ba52e0
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * 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 "widgetservice_utils.h"
+
+#include <widget_errno.h>
+
+namespace extension {
+namespace widgetservice {
+
+namespace {
+
+#define WIDGET_SIZE_TYPE_E \
+  X(WIDGET_SIZE_TYPE_1x1, "1x1") \
+  X(WIDGET_SIZE_TYPE_2x1, "2x1") \
+  X(WIDGET_SIZE_TYPE_2x2, "2x2") \
+  X(WIDGET_SIZE_TYPE_4x1, "4x1") \
+  X(WIDGET_SIZE_TYPE_4x2, "4x2") \
+  X(WIDGET_SIZE_TYPE_4x3, "4x3") \
+  X(WIDGET_SIZE_TYPE_4x4, "4x4") \
+  X(WIDGET_SIZE_TYPE_4x5, "4x5") \
+  X(WIDGET_SIZE_TYPE_4x6, "4x6") \
+  X(WIDGET_SIZE_TYPE_EASY_1x1, "EASY_1x1") \
+  X(WIDGET_SIZE_TYPE_EASY_3x1, "EASY_3x1") \
+  X(WIDGET_SIZE_TYPE_EASY_3x3, "EASY_3x3") \
+  X(WIDGET_SIZE_TYPE_FULL, "FULL") \
+  XD(WIDGET_SIZE_TYPE_UNKNOWN, "unknown")
+
+#define WIDGET_LIFECYCLE_EVENT_E \
+  X(WIDGET_LIFE_CYCLE_EVENT_CREATE, "CREATE") \
+  X(WIDGET_LIFE_CYCLE_EVENT_DESTROY, "DESTROY") \
+  X(WIDGET_LIFE_CYCLE_EVENT_PAUSE, "PAUSE") \
+  X(WIDGET_LIFE_CYCLE_EVENT_RESUME, "RESUME") \
+  XD(WIDGET_LIFE_CYCLE_EVENT_MAX, "unknown")
+
+} // namespace
+
+const std::string kWidgetId = "widgetId";
+const std::string kPackageId = "packageId";
+const std::string kId = "id";
+const std::string kApplicationId = "applicationId";
+const std::string kSetupApplicationId = "setupApplicationId";
+const std::string kNoDisplay = "noDisplay";
+const std::string kSizeType = "sizeType";
+const std::string kWidth = "width";
+const std::string kHeight = "height";
+const std::string kNeedsMouseEvents = "needsMouseEvents";
+const std::string kNeedsTouchEffect = "needsTouchEffect";
+const std::string kNeedsFrame = "needsFrame";
+const std::string kPreviewImagePath = "previewImagePath";
+
+using common::TizenResult;
+using common::TizenSuccess;
+
+TizenResult WidgetServiceUtils::ConvertErrorCode(int error) {
+  switch (error) {
+    case WIDGET_ERROR_NONE:
+      return TizenSuccess();
+    case WIDGET_ERROR_IO_ERROR:
+      return common::IoError(error);
+    case WIDGET_ERROR_INVALID_PARAMETER:
+      return common::InvalidValuesError(error);
+    case WIDGET_ERROR_RESOURCE_BUSY:
+      return common::ServiceNotAvailableError(error);
+    case WIDGET_ERROR_PERMISSION_DENIED:
+      return common::PermissionDeniedError(error);
+    case WIDGET_ERROR_TIMED_OUT:
+      return common::TimeoutError(error);
+    case WIDGET_ERROR_NOT_SUPPORTED:
+    case WIDGET_ERROR_DISABLED:
+      return common::NotSupportedError(error);
+    case WIDGET_ERROR_CANCELED:
+      return common::OperationCanceledError(error);
+    case WIDGET_ERROR_OUT_OF_MEMORY:
+    case WIDGET_ERROR_FILE_NO_SPACE_ON_DEVICE:
+    case WIDGET_ERROR_FAULT:
+    case WIDGET_ERROR_ALREADY_EXIST:
+    case WIDGET_ERROR_ALREADY_STARTED:
+    case WIDGET_ERROR_NOT_EXIST:
+    default:
+      return common::AbortError(error);
+  }
+}
+
+TizenResult WidgetServiceUtils::WidgetToJson(const char* id, picojson::object* out, const char* pkgid) {
+  ScopeLogger();
+
+  //applicationId
+  char* tmp_str = widget_service_get_main_app_id(id);
+  if (!tmp_str) {
+    LogAndReturnTizenError(
+        ConvertErrorCode(get_last_result()), ("widget_service_get_main_app_id() failed"));
+  }
+  out->insert(std::make_pair(kApplicationId, picojson::value(tmp_str)));
+  free(tmp_str);
+
+  //setupApplicationId
+  tmp_str = widget_service_get_app_id_of_setup_app(id);
+  if (!tmp_str) {
+    if (WIDGET_ERROR_NONE != get_last_result()) {
+      LogAndReturnTizenError(
+          ConvertErrorCode(get_last_result()), ("widget_service_get_app_id_of_setup_app() failed"));
+    }
+  } else {
+    out->insert(std::make_pair(kSetupApplicationId, picojson::value(tmp_str)));
+    free(tmp_str);
+  }
+
+  //packageId
+  if (!pkgid) {
+    tmp_str = widget_service_get_package_id(id);
+    if (!tmp_str) {
+      LogAndReturnTizenError(
+          ConvertErrorCode(get_last_result()), ("widget_service_get_package_id() failed"));
+    }
+    out->insert(std::make_pair(kPackageId, picojson::value(tmp_str)));
+    free(tmp_str);
+  }
+
+  //noDisplay
+  bool tmp_bool = widget_service_get_nodisplay(id);
+  if (WIDGET_ERROR_NONE != get_last_result()) {
+    LogAndReturnTizenError(
+        ConvertErrorCode(get_last_result()), ("widget_service_get_nodisplay() failed"));
+  }
+  out->insert(std::make_pair(kNoDisplay, picojson::value(tmp_bool)));
+
+  //id
+  out->insert(std::make_pair(kId, picojson::value(id)));
+
+  return TizenSuccess();
+}
+
+TizenResult WidgetServiceUtils::SizeToJson(widget_size_type_e type, picojson::object* out) {
+  ScopeLogger();
+
+  int width = 0;
+  int height = 0;
+
+  int ret = widget_service_get_size(type, &width, &height);
+  if (WIDGET_ERROR_NONE != ret) {
+    LogAndReturnTizenError(ConvertErrorCode(ret), ("widget_service_get_size() failed"));
+  }
+
+  out->insert(std::make_pair(kWidth, picojson::value(static_cast<double>(width))));
+  out->insert(std::make_pair(kHeight, picojson::value(static_cast<double>(height))));
+
+  return TizenSuccess();
+}
+
+TizenResult WidgetServiceUtils::WidgetVariantToJson(
+    const char* id, widget_size_type_e type, picojson::object* out) {
+  ScopeLogger();
+
+  bool tmp = false;
+
+  //needsMouseEvents
+  int ret = widget_service_get_need_of_mouse_event(id, type, &tmp);
+  if (WIDGET_ERROR_NONE != ret) {
+    LogAndReturnTizenError(
+        ConvertErrorCode(ret), ("widget_service_get_need_of_mouse_event() failed"));
+  }
+  out->insert(std::make_pair(kNeedsMouseEvents, picojson::value(tmp)));
+
+  //needsTouchEffect
+  ret = widget_service_get_need_of_touch_effect(id, type, &tmp);
+  if (WIDGET_ERROR_NONE != ret) {
+    LogAndReturnTizenError(
+        ConvertErrorCode(ret), ("widget_service_get_need_of_touch_effect() failed"));
+  }
+  out->insert(std::make_pair(kNeedsTouchEffect, picojson::value(tmp)));
+
+  //needsFrame
+  ret = widget_service_get_need_of_frame(id, type, &tmp);
+  if (WIDGET_ERROR_NONE != ret) {
+    LogAndReturnTizenError(
+        ConvertErrorCode(ret), ("widget_service_get_need_of_frame() failed"));
+  }
+  out->insert(std::make_pair(kNeedsFrame, picojson::value(tmp)));
+
+  //previewImagePath
+  char* path = widget_service_get_preview_image_path(id, type);
+  if (!path) {
+    LogAndReturnTizenError(
+        ConvertErrorCode(get_last_result()), ("widget_service_get_preview_image_path() failed"));
+  }
+  out->insert(std::make_pair(kPreviewImagePath, picojson::value(path)));
+  free(path);
+
+  return TizenSuccess();
+}
+
+#define X(v, s) case v: return s;
+#define XD(v, s) \
+  default: \
+    LoggerE("Unknown value: %d, returning default: %s", e, s); \
+    return s;
+
+std::string WidgetServiceUtils::FromSizeType(widget_size_type_e e) {
+  ScopeLogger();
+
+  switch (e) {
+    WIDGET_SIZE_TYPE_E
+  }
+}
+
+std::string WidgetServiceUtils::FromEventType(widget_lifecycle_event_e e) {
+  ScopeLogger();
+
+  switch (e) {
+    WIDGET_LIFECYCLE_EVENT_E
+  }
+}
+
+#undef X
+#undef XD
+
+#define X(v, s) if (e == s) return v;
+#define XD(v, s) \
+  LoggerE("Unknown value: %s, returning default: %d", e.c_str(), v); \
+  return v;
+
+widget_size_type_e WidgetServiceUtils::ToSizeType(const std::string& e) {
+  ScopeLogger();
+
+  WIDGET_SIZE_TYPE_E
+}
+
+#undef X
+#undef XD
+
+} // widgetservice
+} // extension
diff --git a/src/widgetservice/widgetservice_utils.h b/src/widgetservice/widgetservice_utils.h
new file mode 100644 (file)
index 0000000..5f6a264
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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 WEBAPI_PLUGINS_WIDGETSERVICE_WIDGET_UTILS_H__
+#define WEBAPI_PLUGINS_WIDGETSERVICE_WIDGET_UTILS_H__
+
+#include <string>
+
+#include <widget_service.h>
+
+#include "common/tizen_result.h"
+
+namespace extension {
+namespace widgetservice {
+
+#define CHECK_EXIST(args, name, out) \
+  if (args.end() == args.find(name)) { \
+    return common::TypeMismatchError(std::string(name) + " is required argument"); \
+  }
+
+extern const std::string kWidgetId;
+extern const std::string kPackageId;
+extern const std::string kId;
+extern const std::string kSizeType;
+extern const std::string kWidth;
+extern const std::string kHeight;
+
+class WidgetServiceUtils {
+ public:
+  static widget_size_type_e ToSizeType(const std::string& e);
+  static std::string FromSizeType(widget_size_type_e e);
+  static std::string FromEventType(widget_lifecycle_event_e e);
+  static common::TizenResult ConvertErrorCode(int error);
+  static common::TizenResult WidgetToJson(const char* id, picojson::object* out, const char* pkgid = nullptr);
+  static common::TizenResult SizeToJson(widget_size_type_e type, picojson::object* out);
+  static common::TizenResult WidgetVariantToJson(const char* id, widget_size_type_e type, picojson::object* out);
+
+};
+
+} // widgetservice
+} // extension
+
+#endif // WEBAPI_PLUGINS_WIDGETSERVICE_WIDGET_UTILS_H__